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
相关产品推荐
相关产品推荐

