如何避免图片绝对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
相关产品推荐
相关产品推荐

