Scrapy自定义图片下载管道报No adapter found for ItemAdapter错误
错误原因
- 自定义的
ScrapyExercisesPipeline逻辑错误:Scrapy管道要求每个process_item方法返回原始item对象供后续管道处理,该管道直接返回ItemAdapter实例,导致下游管道拿到的不是标准item对象,ItemAdapter尝试对已为Adapter类型的对象做适配时,就会抛出你看到的No adapter found类型错误。 DownfilesPipeline的file_path方法实现逻辑完全错误:无参实例化ScrapyExercisesPipeline后空参调用process_item(),既没有传入必填的item、spider参数,也做了完全多余的绕路操作——Scrapy的ImagesPipeline在调用file_path生成存储路径时,本身就会将当前处理的item作为关键字参数传入,不需要额外通过其他管道获取。- 管道配置冗余:无实际作用的
ScrapyExercisesPipeline被加入管道流,是触发类型错误的直接诱因。
正确实现步骤
1. 重写pipelines.py代码
删除无用的ScrapyExercisesPipeline类,修正自定义图片管道的文件命名逻辑,代码如下:
from scrapy.pipelines.images import ImagesPipeline class DownfilesPipeline(ImagesPipeline): def file_path(self, request, response=None, info=None, *, item=None): # 直接从传入的item中读取提前提取好的alt属性对应name值 image_name = item['name'] # 过滤文件名非法字符,避免跨系统存储报错 invalid_char_list = ['\\', '/', ':', '*', '?', '"', '<', '>', '|'] for c in invalid_char_list: image_name = image_name.replace(c, '') return f"{image_name}.jpg"
2. 修正settings.py管道配置
删除冗余的管道配置项,仅保留自定义图片管道,配置段修改为:
ITEM_PIPELINES = { 'scrapy_exercises.pipelines.DownfilesPipeline': 300 } # 以下原有图片存储相关配置保持不变即可 from pathlib import Path import os BASE_DIR = Path(__file__).resolve().parent.parent IMAGES_STORE = os.path.join(BASE_DIR, 'images') IMAGES_URLS_FIELD = 'images' IMAGES_RESULT_FIELD = 'results'
补充说明
- 你现有爬虫代码里的图片链接提取、alt值读取、空alt兜底命名的逻辑没有问题,不需要修改。
- 增加非法字符过滤逻辑是为了兼容Windows、Linux等不同系统的文件命名规则,避免alt文本中包含系统不允许的文件名字符导致下载写入失败。
- 如果遇到不同页面同名alt的图片被覆盖的问题,可以在文件名后追加请求URL的哈希值或者序号做区分,按需调整即可。
内容的提问来源于stack exchange,提问作者tesla john
相关产品推荐
相关产品推荐

