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

Python requests爬取图片时部分文件损坏无法打开的问题如何解决

问题原因及修复方案

1. 优先排查图片下载逻辑的Header配置

你贴的代码仅配置了爬取列表页的请求头,大概率download_image函数下载单张图片时未携带和列表页一致的User-Agent、Referer参数,触发了目标站的防盗链校验:前67张为无防盗链限制的公共资源,第68张开始的资源做了防盗链校验,返回的是403错误的HTML页面而非图片二进制内容,直接保存为jpg自然无法打开。
修复方法:下载图片时复用列表页的请求头配置,Referer参数填当前图片所属的列表页URL即可。

2. 校验图片URL的完整性

排查第68张开始的img标签src属性是否为相对路径:如果前67张是带http/https前缀的绝对路径,后续为相对路径,直接请求相对路径会返回404错误页面,保存后就是损坏的文件。
修复方法:用urllib.parse.urljoin把相对路径拼接成完整的绝对路径再加入下载队列,示例:

from urllib.parse import urljoin
# 拼接图片完整URL
image_src = urljoin(url, item["src"])
image_info.append((image_src, imageID))

3. 新增响应合法性校验

你当前的逻辑不管请求返回的内容是什么都会直接写入文件,被反爬拦截返回的验证码页、错误提示页都会被当做图片保存。
修复方法:下载图片时先校验响应状态码和内容类型,符合要求再写入:

def download_image(image_info, folder_name, page_url):
    img_url, img_id = image_info
    # 下载时携带正确请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36',
        'Referer': page_url
    }
    resp = requests.get(img_url, headers=headers, timeout=10)
    # 校验状态码和内容类型
    if resp.status_code == 200 and 'image' in resp.headers.get('Content-Type', ''):
        save_path = os.path.join("C:/data/images/", folder_name, f"{img_id}.jpg")
        # 必须用wb二进制模式写入,文本模式w会转码二进制内容导致损坏
        with open(save_path, 'wb') as f:
            f.write(resp.content)
    else:
        print(f"下载失败:{img_url}, 状态码:{resp.status_code}, 内容类型:{resp.headers.get('Content-Type')}")

调用时传入当前列表页的URL即可:

download_image(image_info[i], folder_name, url)

4. 规避反爬频率限制

前67张下载正常后续全部损坏,也有可能是请求频率过高触发了目标站的反爬阈值,被临时拦截。
修复方法:

  • 每下载一张图片加1~2秒的随机延时:import time; import random; time.sleep(random.uniform(1,2))
  • 高频爬取建议搭配代理IP池轮换IP

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 18:45:03