You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scrapy ImagesPipeline下载图片失败无文件产出问题求助

Scrapy图片管道无下载文件故障排查

已定位的直接故障点

  • 字段名不符合内置ImagesPipeline规则:Scrapy图片管道默认读取item内的image_urls字段(列表类型,存待下载图片URL)发起下载,下载完成后才会把结果写入images字段。现有代码直接把URL写入images字段,管道识别不到待下载地址,不会触发下载逻辑。
  • 空值未做拦截:循环匹配页面div时,大量嵌套div无img标签,image_url会取到None,直接调用.split('?')会触发AttributeError,中断当前item处理。
  • 图片URL未补全域名:页面提取的img src多为相对路径,未拼接站点根域名时Scrapy发起的是无效请求,拿不到图片资源。
  • 依赖缺失:ImagesPipeline依赖Pillow库完成图片格式校验、存储,未安装时管道会静默失效。
  • 自定义管道方法签名不匹配:高版本Scrapy的file_path方法新增了item关键字参数,旧写法会导致自定义命名逻辑不生效。
  • 判断逻辑错位:现有代码仅判断link不为空就生成item,未校验image_url是否存在,会生成大量无有效下载地址的无效item。

修正步骤

  1. 先安装必备依赖
pip install pillow
  1. 修改items.py,匹配管道字段要求
import scrapy
class ScrapyExercisesItem(scrapy.Item):
    image_urls = scrapy.Field()  # 存储待下载的图片URL列表,供管道读取
    images = scrapy.Field()      # 存储下载完成后的图片元信息
  1. 修正爬虫解析逻辑,补全URL、加空值判断
import scrapy
from scrapy_exercises.items import ScrapyExercisesItem


class TestSpider(scrapy.Spider):
    name = 'test'
    start_urls = ['https://www.meadowhall.co.uk/eatdrinkshop?page=1']

    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(
                url=url,
                callback=self.parse
            )

    def parse(self, response):
        content_page = response.xpath("//div[@class='view-content']//div")
        for cnt in content_page:
            link = cnt.xpath('.//a/@href').get()
            image_url = cnt.xpath(".//img//@src").get()
            # 同时校验链接和图片地址不为空
            if link and image_url:
                # 补全相对路径为完整URL,清理URL后的查询参数
                clean_img_url = response.urljoin(image_url.split('?')[0])
                item = ScrapyExercisesItem()
                item['image_urls'] = [clean_img_url]
                yield item
  1. 修正自定义图片管道,适配版本签名
from scrapy.pipelines.images import ImagesPipeline

class DownfilesPipeline(ImagesPipeline):
    def file_path(self, request, response=None, info=None, *, item=None):
        # 取URL最后一段作为文件名,新增item参数适配Scrapy 2.0+版本
        return request.url.split("/")[-1]
  1. 调整settings.py配置
ITEM_PIPELINES = {
    # 优先级调整为300,符合Scrapy媒体管道的优先级惯例
    'scrapy_exercises.pipelines.DownfilesPipeline': 300,
}
# 图片统一存储到项目下的images文件夹,避免根目录权限问题、文件混乱
IMAGES_STORE = './images'

后续排查方向

改完后运行爬虫加--loglevel=DEBUG参数,通过日志定位剩余问题:

  • 日志出现图片请求403/404:站点做了反爬校验,需要重写管道的get_media_requests方法,给图片请求加上Referer等请求头
  • 日志报权限错误:把IMAGES_STORE改成当前用户有读写权限的目录
  • 日志提示字段未找到:检查image_urls字段拼写,不要写成单数或者错拼

内容的提问来源于stack exchange,提问作者tesla john

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:39:15