需伪装真实浏览器行为:设置User-Agent、Referer、Accept-Language等请求头,使用Session维持会话,添加随机延时;代理需验证有效性并正确配置;Selenium需禁用webdriver特征并注入JS补丁;Cloudflare防护需过JS挑战,推荐Playwright或付费服务。

requests 发出请求直接返回 HTTPError 403: Forbidden 怎么办
这不是服务器“拒绝服务”,而是它一眼认出你不是浏览器——requests 默认发包太干净,User-Agent 是 python-urllib/3.x,没 Referer、没 Accept-Language、连 Cookie 都空着,等于穿睡衣去银行办业务。
实操建议:
- 必须覆盖三大基础头:
User-Agent(选 Chrome 最新 Win 版本)、Referer(设成目标站首页或 Google)、Accept-Language(如zh-CN,zh;q=0.9) - 别用固定 UA 字符串;每次请求随机轮换几个真实 UA,避免被 UA 指纹识别
- 加
time.sleep(1–3),尤其批量请求时;连续 5 次无延迟访问,很多站会立刻 403+IP 记录 - 如果目标站登录后才开放数据,
requests.Session()必须贯穿全程,且首次请求要先模拟登录拿到有效cookies
示例片段:
import requests, time
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": "https://example.com/",
"Accept-Language": "zh-CN,zh;q=0.9"
}
session = requests.Session()
resp = session.get("https://example.com/api/data", headers=headers)
time.sleep(1.5)
代理 IP 设置了还是 403?检查这三件事
代理不是万能钥匙,反而可能让问题更糟:免费代理大多已被标记,高匿≠可用;有些代理出口 IP 本身就在 Cloudflare 或 Akamai 的黑名单里,一发请求就触发 403。
立即学习“Python免费学习笔记(深入)”;
实操建议:
- 验证代理是否真生效:
requests.get("https://httpbin.org/ip", proxies=proxies)看返回 IP 是否匹配 - 确认代理协议一致:HTTP 站用
http://代理,HTTPS 站必须用支持 TLS 的代理,否则握手失败也可能被记为异常行为 - 商用代理务必带认证参数,格式必须是
http://user:pass@host:port;漏掉user:pass@或写成https://前缀,requests会静默降级,结果仍是本机 IP 出去
常见错误现象:ConnectionError 后紧接 403,说明代理根本没连上,流量实际走的是你本地出口。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
Selenium 启动后仍 403?你可能漏掉了无头模式的指纹特征
新版 Chrome 对无头浏览器检测极严:--headless 单独启用时,navigator.webdriver 为 true、缺少 plugins、languages 字段异常——这些都会被 JS 反爬脚本当场捕获并返回 403。
实操建议:
- 禁用自动化特征:加
--disable-blink-features=AutomationControlled和--disable-automation - 手动覆盖
navigator.webdriver:用driver.execute_cdp_cmd注入 JS 补丁(Chrome DevTools Protocol) - 别用默认 User-Agent;启动时通过
chrome_options.add_argument("--user-agent=...")覆盖,否则仍暴露 selenium 标识
关键补丁代码(必须在 driver.get() 前执行):
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})
Cloudflare 防护下 403 不是请求问题,是挑战没过
普通 403 是服务器拒绝,Cloudflare 的 403 往往是「JS 挑战失败」——页面返回一段加密 JS,要求浏览器执行后回传 token。requests 无法执行 JS,Selenium 若没等挑战完成就取源码,拿到的仍是防护页,状态码却显示 200,内容里却藏 403 文字或跳转逻辑。
实操建议:
- 先人工访问目标 URL,打开 DevTools → Network,刷新看是否有
/cdn-cgi/challenge-platform/类请求,有则确认是 Cloudflare - Selenium 必须显式等待挑战结束:监听 URL 变化、检查
document.title是否含 “Just a moment”、或等待某个正常页面元素出现 - 生产环境优先考虑
playwright(比 Selenium 更稳过 CF),或付费服务如zenrows.com,它们已内置挑战自动解析能力
容易被忽略的一点:Cloudflare 会根据请求频率动态升级挑战难度,同一 IP 5 分钟内发 10 次,第二次起可能从 JS 挑战升到验证码——这时所有自动化方案都得退场。

















