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

Python Requests请求仅偶尔成功获取图片问题排查

解决图片下载随机403/部分成功的问题

你的情况是典型的动态反爬拦截——网站不是靠固定请求头或Cookie验证,而是通过检测请求的行为特征(比如固定间隔、单一请求标识、异常请求字段)来随机拦截。以下是针对性的修复方案:

一、清理冗余请求头

你当前的请求头里混了method、credentials、mode这些属于浏览器Fetch API的内部参数,HTTP请求头中根本不存在这些字段,直接暴露了请求并非来自真实浏览器,必须删掉。

二、请求头随机化

固定的User-Agent、Accept字段会被标记为爬虫,要准备多组候选值随机选择:

  • 收集不同浏览器的User-Agent列表
  • 随机切换Accept、Accept-Language的组合

三、会话保持+随机请求间隔

  • 用requests.Session()复用连接,模拟浏览器的会话状态,避免每次请求新建连接的特征
  • 不要用固定的sleep(1),改用0.8-2.5秒的随机间隔,规律的时间间隔是爬虫的典型标识

四、增加重试机制

遇到403、5xx等非成功响应时自动重试2-3次,很多时候只是临时拦截


修改后的代码示例

import requests
import random
from time import sleep
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# 准备多组请求头候选
USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15"
]

ACCEPT_HEADERS = [
    "image/avif,image/webp,*/*",
    "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
]

def get_random_headers():
    return {
        "User-Agent": random.choice(USER_AGENTS),
        "Accept": random.choice(ACCEPT_HEADERS),
        "Accept-Language": random.choice(["en-US,en;q=0.5", "zh-CN,zh;q=0.9,en;q=0.8"]),
        "Referrer": "https://DOMAIN",
        "Connection": "keep-alive"
    }

# 配置带重试的会话
def create_session():
    session = requests.Session()
    retry = Retry(
        total=3,  # 总重试次数
        backoff_factor=0.5,  # 重试间隔递增(0.5,1,2秒)
        status_forcelist=[403, 500, 502, 503]  # 需要重试的状态码
    )
    adapter = HTTPAdapter(max_retries=retry)
    session.mount("https://", adapter)
    return session

def download_image(session, url, dst):
    headers = get_random_headers()
    try:
        response = session.get(url, stream=True, allow_redirects=True, headers=headers)
        response.raise_for_status()  # 状态码非200时触发异常
        with open(dst, 'wb') as f:
            for chunk in response.iter_content(1024):
                if chunk:
                    f.write(chunk)
        print(f"成功下载: {dst}")
    except requests.exceptions.RequestException as e:
        print(f"下载失败 {dst}: {str(e)}")

if __name__ == "__main__":
    urls = [
        "https://DOMAIN/covers/full/ta/FILENAME1.webp",
        "https://DOMAIN/covers/full/vr/FILENAME2.webp",
        "https://DOMAIN/covers/full/ui/FILENAME3.webp",
    ]
    session = create_session()
    for i, url in enumerate(urls, start=1):
        dst = f'{i}.webp'
        # 随机间隔
        sleep(random.uniform(0.8, 2.5))
        download_image(session, url, dst)

关于Selenium的补充修复

如果用Selenium仍出现问题,需要禁用自动化检测特征:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--headless=new")  # 无头模式
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
# 随机User-Agent
options.add_argument(f"user-agent={random.choice(USER_AGENTS)}")

driver = webdriver.Chrome(options=options)
# 先访问首页,再获取图片,模拟真实用户路径
driver.get("https://DOMAIN")
sleep(random.uniform(1, 3))
# 后续执行图片下载逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:24:21