gpt4 book ai didi

Python Scrapy如何将数据保存在不同的文件中

转载 作者:行者123 更新时间:2023-12-03 17:10:45 26 4
gpt4 key购买 nike

我想保存来自 http://quotes.toscrape.com/ 的每个报价保存到 csv 文件中(2 个字段:作者、引用)。另一个必要条件是将这些引用保存在由它们所在的页面分隔的不同文件中。即:(page1.csv,page2.csv ...)。我试图通过在 custom_settings 中声明饲料导出来实现这一点。我的蜘蛛中的属性,如下所示。然而,这甚至不会产生一个名为 page-1.csv 的文件。 .我是一个使用scrapy的初学者,请尝试解释,假设我知之甚少。

import scrapy
import urllib

class spidey(scrapy.Spider):
name = "idk"
start_urls = [
"http://quotes.toscrape.com/"
]

custom_settings = {
'FEEDS' : {
'file://page-1.csv' : { #edit: uri needs to be absolute path
'format' : 'csv',
'store_empty' : True
}
},
'FEED_EXPORT_ENCODING' : 'utf-8',
'FEED_EXPORT_FIELDS' : ['author', 'quote']
}


def parse(self, response):
for qts in response.xpath("//*[@class=\"quote\"]"):
author = qts.xpath("./span[2]/small/text()").get()
quote = qts.xpath("./*[@class=\"text\"]/text()").get()
yield {
'author' : author,
'quote' : quote
}

next_pg = response.xpath('//li[@class="next"]/a/@href').get()
if next_pg is not None:
next_pg = urllib.parse.urljoin(self.start_urls[0], next_pg)
yield scrapy.Request(next_pg, self.parse)
我如何运行爬虫: scrapy crawl idk作为一个附加问题,我需要覆盖我的文件,而不是像指定 -o 那样被附加。旗帜。是否可以在不必手动检查/删除蜘蛛中预先存在的文件的情况下做到这一点?

最佳答案

设置不支持(afaik)将您的项目保存到以您找到它们的页面命名的文件中。如果你想实现这一点,你可以使用 python 的 open 创建你自己的功能。功能和 csv.writer在您的 parse方法。另一种选择是写一个 item pipeline管理不同的 item exporters对于不同的文件。
但是,您可以使用设置来限制文件中的项目数 FEED_EXPORT_BATCH_ITEM_COUNT 设置,从 Scrapy 2.3 版开始支持。
从 Scrapy 2.4 开始,也可以覆盖而不是附加到文件中。在 FEEDS您可以设置 overwrite到 True 不久就演示了。
如果您要更换您的 custom_settings使用以下内容,它将生成包含 10 个项目的文件,每个项目名为 page-其次是 batch_id ,从一开始。因此,您的前 3 个文件将命名为 page-1.csv、page-2.csv 和 page-3.csv。

    custom_settings = {
'FEED_EXPORT_BATCH_ITEM_COUNT': 10,
'FEEDS' : {
'page-%(batch_id)d.csv' : {
'format' : 'csv',
'store_empty' : True,
'overwrite': True
}
}
}

作为管道实现
如果您想使用项目管道实现这一点,您可以将您所在的页码保存在您返回的字典中,然后由项目管道处理和删除。
您的管道 pipelines.py (基于 this example )可能看起来像这样:
from scrapy.exporters import CsvItemExporter


class PerFilenameExportPipeline:
"""Distribute items across multiple CSV files according to their 'page' field"""

def open_spider(self, spider):
self.filename_to_exporter = {}

def close_spider(self, spider):
for exporter in self.filename_to_exporter.values():
exporter.finish_exporting()

def _exporter_for_item(self, item):
filename = 'page-' + str(item['page_no'])
del item['page_no']
if filename not in self.filename_to_exporter:
f = open(f'{filename}.csv', 'wb')
exporter = CsvItemExporter(f)
exporter.start_exporting()
self.filename_to_exporter[filename] = exporter
return self.filename_to_exporter[filename]

def process_item(self, item, spider):
exporter = self._exporter_for_item(item)
exporter.export_item(item)
return item
然后,您需要为您的蜘蛛添加一个例程来获取您所在的页面,并在您的 custom_settings 中设置管道。 ,您可以执行以下操作:
import scrapy
from ..pipelines import PerFilenameExportPipeline


class spidey(scrapy.Spider):
name = "idk"
custom_settings = {
'ITEM_PIPELINES': {
PerFilenameExportPipeline: 100
}
}

def start_requests(self):
yield scrapy.Request("http://quotes.toscrape.com/", cb_kwargs={'page_no': 1})

def parse(self, response, page_no):
for qts in response.xpath("//*[@class=\"quote\"]"):
yield {
'page_no': page_no,
'author' : qts.xpath("./span[2]/small/text()").get(),
'quote' : qts.xpath("./*[@class=\"text\"]/text()").get()
}

next_pg = response.xpath('//li[@class="next"]/a/@href').get()
if next_pg is not None:
yield response.follow(next_pg, cb_kwargs={'page_no': page_no + 1})
但是,这有一个问题。由于我无法理解的原因,最后一个文件 (page-10.csv) 保持为空。我问过为什么会是 here .

关于Python Scrapy如何将数据保存在不同的文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63749285/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com