关闭主抓取管道但保持图像下载直到它在 scrapy 中完成
Closing main scraping pipeline but keeping image download till it finishes in scrapy
关于如何在 scrapy 中优先处理图像下载管道,或者停止抓取管道而不杀死其余部分的任何想法?
我的目标
我正在使用 scrapy 的蜘蛛编写爬虫程序。我的目标是爬取页面,一旦满足条件(抓取的更新日期早于参数),就关闭爬取过程。但是我不希望图像下载管道在完成工作之前关闭。
目前取得的成果是:
- 除了图像之外的所有数据都被正确存储并且蜘蛛程序正常关闭。
- 图像已下载(因此管道有效)但不是全部。
问题:某些页面的图像无法下载。 “images_urls”字段已填充,但“图像”字段为空。我怀疑这是因为主要的数据抓取管道“先行”,当它关闭时它会杀死图像管道。
简化实施
我正在汇总这几行中的代码,以便您检查一些重要部分。
- mySpider_spider.py -->
raise CloseSpider("Date has been reached")
关闭抓取管道。
正在正确下载图像,直到发生异常:
- myspider_settings.py -->
ITEM_PIPELINES = {'scrapy.pipelines.images.ImagesPipeline': 1}
- main.py -->
process.setting["IMAGES_STORE"] = pathFromArguments
这样我就可以参数化输出了。
- items -->
image_urls = scrapy.Field()
and images = scrapy.Field()
inside mySpider class.
- mySpider_spider.py -->
#Stores url in image_urls and yields correctly
- pipelines.py
class itemScrapingPipeline(object):
def process_item(self, item, spider):
return item
class MyImagesPipeline(ImagesPipeline):
def get_media_requests(self, item, info):
for image_url in item['image_urls']:
yield scrapy.Request(image_url)
def item_completed(self, results, item, info):
image_paths = [x['path'] for ok, x in results if ok]
if not image_paths:
raise DropItem("Item contains no images")
item['image_paths'] = image_paths
return item
PD:第一次 post 来到这里,所以我很感激你的建议。
看来您可以像这样轻松地为管道添加优先级:
在设置文件中,为 ImagePipeline 提供比其他管道更高的编号。这将确保您在抓取该页面后立即下载图像。
ITEM_PIPELINES = {
'scrapy.pipelines.images.ImagesPipeline': 301,
'scrapy_redis.pipelines.RedisPipeline': 300}
但是为了按时间顺序抓取页面,您需要更改堆并将其用作 FIFO 堆。您可以在设置中再次执行此操作(格式为“DEPTH_PRIORITY = 1”),或者像我在 main.py:
中那样在启动爬虫之前给它一个值
process.settings["DEPTH_PRIORITY"] = 1
process.settings["SCHEDULER_DISK_QUEUE"] = 'scrapy.squeues.PickleFifoDiskQueue'
process.settings["SCHEDULER_MEMORY_QUEUE"] = 'scrapy.squeues.FifoMemoryQueue'
建议使用全部三行以使其正常工作。
关于如何在 scrapy 中优先处理图像下载管道,或者停止抓取管道而不杀死其余部分的任何想法?
我的目标
我正在使用 scrapy 的蜘蛛编写爬虫程序。我的目标是爬取页面,一旦满足条件(抓取的更新日期早于参数),就关闭爬取过程。但是我不希望图像下载管道在完成工作之前关闭。
目前取得的成果是:
- 除了图像之外的所有数据都被正确存储并且蜘蛛程序正常关闭。
- 图像已下载(因此管道有效)但不是全部。
问题:某些页面的图像无法下载。 “images_urls”字段已填充,但“图像”字段为空。我怀疑这是因为主要的数据抓取管道“先行”,当它关闭时它会杀死图像管道。
简化实施
我正在汇总这几行中的代码,以便您检查一些重要部分。
- mySpider_spider.py -->
raise CloseSpider("Date has been reached")
关闭抓取管道。
正在正确下载图像,直到发生异常:
- myspider_settings.py -->
ITEM_PIPELINES = {'scrapy.pipelines.images.ImagesPipeline': 1}
- main.py -->
process.setting["IMAGES_STORE"] = pathFromArguments
这样我就可以参数化输出了。 - items -->
image_urls = scrapy.Field()
andimages = scrapy.Field()
inside mySpider class. - mySpider_spider.py -->
#Stores url in image_urls and yields correctly
- pipelines.py
class itemScrapingPipeline(object):
def process_item(self, item, spider):
return item
class MyImagesPipeline(ImagesPipeline):
def get_media_requests(self, item, info):
for image_url in item['image_urls']:
yield scrapy.Request(image_url)
def item_completed(self, results, item, info):
image_paths = [x['path'] for ok, x in results if ok]
if not image_paths:
raise DropItem("Item contains no images")
item['image_paths'] = image_paths
return item
PD:第一次 post 来到这里,所以我很感激你的建议。
看来您可以像这样轻松地为管道添加优先级:
在设置文件中,为 ImagePipeline 提供比其他管道更高的编号。这将确保您在抓取该页面后立即下载图像。
ITEM_PIPELINES = {
'scrapy.pipelines.images.ImagesPipeline': 301,
'scrapy_redis.pipelines.RedisPipeline': 300}
但是为了按时间顺序抓取页面,您需要更改堆并将其用作 FIFO 堆。您可以在设置中再次执行此操作(格式为“DEPTH_PRIORITY = 1”),或者像我在 main.py:
中那样在启动爬虫之前给它一个值process.settings["DEPTH_PRIORITY"] = 1
process.settings["SCHEDULER_DISK_QUEUE"] = 'scrapy.squeues.PickleFifoDiskQueue'
process.settings["SCHEDULER_MEMORY_QUEUE"] = 'scrapy.squeues.FifoMemoryQueue'
建议使用全部三行以使其正常工作。