news 2026/6/10 22:27:12

Scrapy ImagesPipeline和FilesPipeline自定义使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Scrapy ImagesPipeline和FilesPipeline自定义使用

Scrapy 作为 Python 生态中强大的爬虫框架,内置了ImagesPipelineFilesPipeline两个核心管道,专门用于处理图片、文件的下载需求。默认配置虽能满足基础场景,但实际开发中,我们常需要自定义存储路径、过滤文件格式、处理下载异常等,本文将详细讲解如何灵活定制这两个管道。

一、核心概念与基础使用

1. 管道作用

  • ImagesPipeline:专注图片下载,支持图片校验(如校验是否为有效图片)、缩略图生成、图片格式转换等。
  • FilesPipeline:通用文件下载管道,可下载任意格式文件(如 PDF、视频、压缩包等),逻辑与ImagesPipeline高度相似,仅处理对象不同。

2. 基础配置(以 ImagesPipeline 为例)

首先需安装依赖(处理图片需要Pillow):

bash

运行

pip install scrapy pillow

settings.py中配置基础参数:

python

运行

# 启用图片管道 ITEM_PIPELINES = { 'scrapy.pipelines.images.ImagesPipeline': 1, } # 图片存储根目录(绝对路径/相对路径均可) IMAGES_STORE = './downloaded_images' # 允许的图片扩展名 IMAGES_ALLOWED_EXTENSIONS = {'jpg', 'jpeg', 'png', 'gif'} # 图片下载超时时间 IMAGES_TIMEOUT = 15

爬虫中需返回包含image_urls字段的 Item(FilesPipeline对应file_urls):

python

运行

import scrapy class ImageItem(scrapy.Item): image_urls = scrapy.Field() # 必须包含,存储图片URL列表 images = scrapy.Field() # 下载完成后,存储图片信息(路径、URL、校验和等) title = scrapy.Field() # 自定义字段,如图片标题 class ImageSpider(scrapy.Spider): name = 'image_spider' start_urls = ['https://example.com/image-page'] def parse(self, response): item = ImageItem() # 提取页面中的图片URL item['image_urls'] = response.css('img::attr(src)').extract() item['title'] = response.css('h1::text').extract_first() yield item

二、自定义管道的核心场景与实现

默认管道的不足:存储路径固定(按哈希值生成)、无法根据 Item 字段动态命名、无自定义异常处理。我们通过继承ImagesPipeline/FilesPipeline并重写核心方法解决这些问题。

场景 1:自定义文件存储路径与文件名

需求:将图片按 “爬虫名 / 分类 / 标题 + 后缀” 的格式存储,而非默认的哈希路径。

实现(自定义 ImagesPipeline):

python

运行

# pipelines.py import os from urllib.parse import urlparse from scrapy.pipelines.images import ImagesPipeline from scrapy.exceptions import DropItem class CustomImagesPipeline(ImagesPipeline): # 重写此方法,自定义下载请求(可添加请求头、修改URL等) def get_media_requests(self, item, info): # 遍历图片URL,为每个URL生成下载请求,并携带Item字段 for image_url in item['image_urls']: yield scrapy.Request( image_url, meta={ 'title': item['title'], # 携带标题字段 'spider_name': info.spider.name # 携带爬虫名 } ) # 重写此方法,自定义文件路径和文件名 def file_path(self, request, response=None, info=None, *, item=None): # 1. 解析URL获取文件后缀 url_path = urlparse(request.url).path file_ext = os.path.splitext(url_path)[-1] # 处理无后缀的情况,默认.jpg if not file_ext: file_ext = '.jpg' # 2. 获取meta中的自定义字段 spider_name = request.meta['spider_name'] title = request.meta['title'].replace('/', '_').replace('\\', '_') # 过滤非法字符 # 3. 构造自定义路径:spider名/标题/标题+后缀 # 避免重复,可添加序号(此处简化,实际可结合哈希) file_name = f"{title}{file_ext}" return os.path.join(spider_name, title, file_name) # 重写此方法,处理下载完成后的Item def item_completed(self, results, item, info): # results格式:[(success, {'url': '', 'path': '', 'checksum': ''}), ...] image_paths = [x['path'] for ok, x in results if ok] if not image_paths: # 无图片下载成功,丢弃该Item raise DropItem(f"Item {item['title']} 无有效图片") # 将下载后的路径存入Item item['images'] = image_paths return item

对应 FilesPipeline 的自定义实现(仅需替换继承类):

python

运行

from scrapy.pipelines.files import FilesPipeline class CustomFilesPipeline(FilesPipeline): def get_media_requests(self, item, info): for file_url in item['file_urls']: yield scrapy.Request( file_url, meta={ 'file_name': item['file_name'], 'category': item['category'] } ) def file_path(self, request, response=None, info=None, *, item=None): category = request.meta['category'] file_name = request.meta['file_name'] url_path = urlparse(request.url).path file_ext = os.path.splitext(url_path)[-1] return os.path.join(category, f"{file_name}{file_ext}")

修改settings.py启用自定义管道:

python

运行

ITEM_PIPELINES = { # 替换默认管道为自定义管道 'your_project_name.pipelines.CustomImagesPipeline': 1, # 'your_project_name.pipelines.CustomFilesPipeline': 2, # 文件管道同理 } IMAGES_STORE = './custom_images' # 自定义存储根目录 # FilesPipeline需配置FILES_STORE # FILES_STORE = './custom_files'

场景 2:过滤无效文件 / 自定义下载条件

需求:仅下载大小超过 10KB 的图片,过滤损坏或过小的图片。

扩展自定义管道,添加文件大小校验:

python

运行

# 在CustomImagesPipeline中新增方法 def item_completed(self, results, item, info): valid_images = [] for ok, result in results: if not ok: continue # 获取文件绝对路径 file_path = os.path.join(self.store.basedir, result['path']) # 校验文件大小(10KB = 10 * 1024 字节) if os.path.getsize(file_path) < 10 * 1024: os.remove(file_path) # 删除小文件 continue valid_images.append(result['path']) if not valid_images: raise DropItem(f"Item {item['title']} 无有效大图片") item['images'] = valid_images return item

场景 3:生成图片缩略图

ImagesPipeline内置缩略图生成功能,仅需在settings.py配置:

python

运行

# 启用缩略图 IMAGES_THUMBS = { 'small': (50, 50), # 小图:宽50,高50(按比例缩放) 'big': (200, 200), # 大图:宽200,高200 } # 缩略图存储路径默认在原文件路径同级的thumbs目录下,可通过file_path重写

三、常见问题与注意事项

  1. URL 格式问题:部分图片 URL 为相对路径,需在get_media_requests中拼接完整域名:

    python

    运行

    def get_media_requests(self, item, info): base_url = 'https://example.com' for image_url in item['image_urls']: if not image_url.startswith('http'): image_url = base_url + image_url yield scrapy.Request(image_url, meta={'title': item['title']})
  2. 反爬处理:下载请求需携带 User-Agent、Cookie 等,可在settings.py配置:

    python

    运行

    USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...' # 或在get_media_requests中为Request添加headers
  3. 异常处理:网络超时、文件不存在等异常可通过errback处理:

    python

    运行

    def get_media_requests(self, item, info): for image_url in item['image_urls']: yield scrapy.Request( image_url, meta={'title': item['title']}, errback=self.handle_download_error # 异常回调 ) def handle_download_error(self, failure): self.logger.error(f"下载失败:{failure.request.url},原因:{failure.value}")
  4. 并发控制:避免下载过快被封 IP,配置下载并发数:

    python

    运行

    # settings.py CONCURRENT_REQUESTS = 16 # 全局并发 CONCURRENT_REQUESTS_PER_DOMAIN = 4 # 单域名并发 DOWNLOAD_DELAY = 1 # 下载延迟1秒

四、ImagesPipeline vs FilesPipeline 核心区别

特性ImagesPipelineFilesPipeline
处理对象仅图片(JPG/PNG/GIF 等)任意文件(PDF/zip/ 视频等)
依赖需要安装 Pillow无额外依赖
特有功能图片校验、缩略图生成无特有功能,通用文件下载
核心配置IMAGES_STORE、IMAGES_THUMBSFILES_STORE、FILES_ALLOWED_EXTENSIONS
必选 Item 字段image_urls、imagesfile_urls、files

总结

  1. ImagesPipelineFilesPipeline的自定义核心是继承原类,重写get_media_requests(定制请求)、file_path(定制路径)、item_completed(处理结果)三个方法。
  2. 自定义路径时需过滤文件名非法字符,避免路径错误;下载文件时建议添加异常处理和文件有效性校验。
  3. ImagesPipeline适用于图片场景(支持缩略图、格式校验),FilesPipeline适用于通用文件下载,二者自定义逻辑高度复用。

通过灵活定制这两个管道,可满足爬虫中文件 / 图片下载的绝大多数个性化需求,同时遵循 Scrapy 的框架规范,保证代码的可维护性和稳定性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 13:39:36

一键部署中文多情感TTS:云端GPU环境下的极速体验

一键部署中文多情感TTS&#xff1a;云端GPU环境下的极速体验 你是否也遇到过这样的问题&#xff1f;数字营销团队要测试不同情绪风格的广告配音对用户点击率的影响&#xff0c;但每次调用商业语音API成本太高&#xff0c;长期使用不现实&#xff1b;自己从头训练一个TTS模型吧…

作者头像 李华
网站建设 2026/6/10 14:00:04

别再乱选logo设计工具!4款好用的在线设计工具全面测评

对于中小企业主、创业者或个人品牌而言&#xff0c;logo是品牌认知的核心载体&#xff0c;但缺乏专业设计能力、担心版权风险、想要高效产出成了普遍痛点——选对一款在线工具&#xff0c;能快速解决设计难、出稿慢、版权忧的问题。本文测评4款主流logo设计在线工具&#xff0c…

作者头像 李华
网站建设 2026/6/10 11:18:42

Hunyuan-MT-7B-WEBUI语音字幕:视频内容多语言实时字幕生成技术探索

Hunyuan-MT-7B-WEBUI语音字幕&#xff1a;视频内容多语言实时字幕生成技术探索 1. 技术背景与应用场景 随着全球化进程的加速&#xff0c;跨语言信息传播已成为数字内容生态的重要组成部分。尤其在视频内容领域&#xff0c;多语言字幕的生成能力直接影响内容的可及性与传播效…

作者头像 李华
网站建设 2026/6/10 12:57:14

语音活动检测入门首选:FSMN VAD开箱即用体验

语音活动检测入门首选&#xff1a;FSMN VAD开箱即用体验 1. 引言&#xff1a;为什么选择 FSMN VAD&#xff1f; 在语音识别&#xff08;ASR&#xff09;、会议转录、电话录音分析等实际应用中&#xff0c;语音活动检测&#xff08;Voice Activity Detection, VAD&#xff09;…

作者头像 李华