Scrapy嵌套Item中使用ImagesPipeline下载图片返回空数组求助
解决Scrapy嵌套Item中ImagesPipeline无法下载图片的问题
我帮你分析下问题所在,以及给出具体的解决步骤:
一、先修正两个基础错误
1. 字段名不匹配
你的AuctionItem里定义的图片URL字段是image_urls,但爬虫代码里赋值的是img_urls——这直接导致ImagesPipeline找不到要处理的目标字段。
2. 字段格式不符合要求
Scrapy的ImagesPipeline要求image_urls必须是可迭代对象(比如列表),但你用get()得到的是单个字符串,这也会导致处理失败。
修改爬虫里的对应代码:
# 替换原来的img_urls为image_urls,并且包装成列表 img_src = caritem.css("img.img-responsive::attr(src)").get() # 如果是相对路径,记得用response.urljoin转成绝对路径 data["image_urls"] = [response.urljoin(img_src)] if img_src else [] # 如果页面有多个图片,直接用getall()获取列表即可 # data["image_urls"] = caritem.css("img.img-responsive::attr(src)").getall()
二、核心问题:默认Pipeline不处理嵌套Item
你的顶层Item里包含results字段(存储AuctionItem列表),但默认的ImagesPipeline只会处理顶层Item的image_urls,不会递归处理嵌套的子Item。我们需要自定义Pipeline来解决这个问题。
1. 编写自定义Pipeline
在项目的pipelines.py文件中添加以下代码:
from scrapy.pipelines.images import ImagesPipeline from scrapy.exceptions import DropItem class NestedImagesPipeline(ImagesPipeline): def process_item(self, item, spider): # 检查顶层Item是否包含嵌套的子Item列表 if 'results' in item: processed_sub_items = [] for sub_item in item['results']: # 调用父类方法处理每个子Item的图片 try: processed_sub = super().process_item(sub_item, spider) processed_sub_items.append(processed_sub) except DropItem as e: spider.logger.warning(f"丢弃子Item:{str(e)}") # 用处理后的子Item列表替换原数据 item['results'] = processed_sub_items return item # 可选:自定义下载后图片的存储字段名(默认是images) 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未包含有效图片URL") # 替换成你想要的字段名,比如auction_images item['auction_images'] = image_paths return item
2. 修改Settings配置
把默认的ImagesPipeline替换成自定义的Pipeline:
ITEM_PIPELINES = { # 路径格式:项目名.pipelines.自定义Pipeline类名 'ccv_spiders.pipelines.NestedImagesPipeline': 1, } IMAGES_STORE = 'images' DOWNLOAD_TIMEOUT = 1200
三、验证效果
运行爬虫后,你会发现:
- 图片会正常下载到
images目录下 - 每个AuctionItem里会新增
auction_images(或默认的images)字段,存储下载后的图片路径 - 顶层Item的
results结构完全保留,符合你需要的JSON输出格式
内容的提问来源于stack exchange,提问作者lf_celine
相关产品推荐
相关产品推荐

