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

如何避免图片绝对URL不含http时触发ValueError(Missing scheme url)?

解决Scrapy抓取base64图片时的ValueError: Missing scheme错误

我来帮你搞定这个问题!你碰到的报错本质是Scrapy的ImagesPipeline默认只认带HTTP/HTTPS这类协议(scheme)的图片URL,而base64格式的data:image/... URI完全不满足这个要求,所以触发了缺失scheme的错误。另外还有个小细节要提醒你:Scrapy要求image_urls字段必须是列表类型,你原代码里直接赋值单个字符串也可能埋下隐患,我一起帮你修正。

下面分两种场景给出针对性解决方案:


场景1:不需要保存base64格式的图片

如果这类base64图片对你的需求没用,直接过滤掉就好:

img_urls = response.xpath('//table/tbody/tr/td/span/a/img/@src').extract()
for url in img_urls:
    # 跳过所有以"data:"开头的base64图片URL
    if not url.startswith('data:'):
        # 注意这里image_urls是列表,符合Scrapy的要求
        yield {"image_urls": [url]}

场景2:需要保存base64格式的图片

如果要保留这类图片,你得手动解析base64数据并保存,因为ImagesPipeline不支持处理data URI。可以按以下步骤操作:

第一步:编写base64图片保存工具函数

先写一个专门处理base64解码和保存的函数:

import base64
import os
from scrapy.exceptions import DropItem

def save_base64_image(base64_uri, save_dir='downloaded_images'):
    # 自动创建保存目录(不存在则生成)
    os.makedirs(save_dir, exist_ok=True)
    
    # 分割data URI,分离头部信息和图片二进制数据
    try:
        header, img_data = base64_uri.split(',', 1)
    except ValueError:
        # 格式错误的base64 URI直接丢弃
        raise DropItem(f"Invalid base64 image URI: {base64_uri}")
    
    # 提取图片格式(比如jpeg、png)
    try:
        img_format = header.split(';')[0].split('/')[1]
    except IndexError:
        raise DropItem(f"Cannot parse image format from URI: {base64_uri}")
    
    # 生成唯一文件名(避免重复覆盖)
    filename = f"{base64.b64encode(img_data[:10].encode()).decode()}.{img_format}"
    save_path = os.path.join(save_dir, filename)
    
    # 解码并写入本地文件
    with open(save_path, 'wb') as f:
        f.write(base64.b64decode(img_data))
    
    return save_path

第二步:在爬虫中区分处理两种图片

在你的爬虫代码里,判断URL类型,分别处理:

img_urls = response.xpath('//table/tbody/tr/td/span/a/img/@src').extract()
for url in img_urls:
    if url.startswith('data:'):
        # 处理base64图片,返回本地保存路径
        try:
            local_path = save_base64_image(url)
            yield {"local_image_path": local_path}
        except DropItem as e:
            print(f"Skipping invalid base64 image: {e}")
    else:
        # 正常HTTP/HTTPS图片交给ImagesPipeline处理
        yield {"image_urls": [url]}

要是你想把两种图片的处理逻辑整合到Pipeline中,还可以自定义一个Pipeline类,在process_item方法里判断item字段,分别处理base64数据和普通URL。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:53:03