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

Scrapy下载.MPO格式图片报错PIL.UnidentifiedImageError,求解决方案

解决Scrapy下载MPO图片时PIL无法识别的问题

错误原因:Pillow原生不支持MPO(多图片对象)格式,而Scrapy的ImagesPipeline默认会调用Pillow打开下载的图片进行处理,因此触发PIL.UnidentifiedImageError。

以下是两种解决方案:

方案1:跳过MPO图片的Pillow处理,直接保存原始文件

如果仅需要下载保存MPO文件,不需要裁剪、格式转换等处理,可以自定义ImagesPipeline,对MPO格式文件直接保存,跳过Pillow解析步骤:

from scrapy.pipelines.images import ImagesPipeline
import os

class CustomImagesPipeline(ImagesPipeline):
    def get_images(self, response, request, info, item=None):
        # 判断请求URL是否以.mpo结尾
        if response.url.lower().endswith('.mpo'):
            # 生成保存路径,保留原始文件名
            path = self.file_path(request, response=response, info=info, item=item)
            # 返回路径、None(跳过Pillow处理)、原始文件内容
            return [(path, None, response.body)]
        # 非MPO格式按原有逻辑处理
        return super().get_images(response, request, info, item=item)

修改项目settings.py中的ITEM_PIPELINES,替换默认的图片管道:

ITEM_PIPELINES = {
    # 注释掉默认管道,启用自定义管道
    # 'scrapy.pipelines.images.ImagesPipeline': 1,
    '你的项目名.pipelines.CustomImagesPipeline': 1,
}

方案2:解析MPO提取图片后再处理

如果需要对MPO中的图片进行格式转换、裁剪等操作,先安装支持MPO解析的第三方库mpo:

pip install mpo

然后自定义管道解析MPO文件,提取其中的图片内容交给Pillow处理:

from scrapy.pipelines.images import ImagesPipeline
import mpo
from io import BytesIO
import os

class MPOImagesPipeline(ImagesPipeline):
    def get_images(self, response, request, info, item=None):
        if response.url.lower().endswith('.mpo'):
            # 解析MPO文件
            mpo_obj = mpo.MPO(BytesIO(response.body))
            # 遍历MPO中的所有图片(MPO可能包含多张图片)
            for img_idx, img_data in enumerate(mpo_obj.images):
                img_buffer = BytesIO(img_data)
                # 生成带序号的文件名,避免覆盖
                base_name = os.path.splitext(os.path.basename(request.url))[0]
                save_path = f"{base_name}_{img_idx+1}.jpg"
                # 返回路径、Pillow图片对象、图片缓冲
                yield (save_path, self._Image.open(img_buffer), img_buffer)
        else:
            # 非MPO格式按原有逻辑处理
            yield from super().get_images(response, request, info, item=item)

同样在settings.py中替换默认管道为上述自定义管道即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 15:02:26