加了 user-agent 仍被封是因为header组合不完整或不匹配,如缺失sec-ch-ua等现代浏览器必传字段、accept-language与ua不一致、大小写错误或硬编码cookie等,导致服务端识别为自动化请求。

为什么加了 User-Agent 还被封?
很多同学以为只要塞个 User-Agent 就算“像人”,实际封禁常源于 Header 组合暴露了自动化特征。比如只设 User-Agent 却没带 Accept、Accept-Language 或 Sec-Ch-Ua 等现代浏览器必传字段,服务端通过 UA 与 Sec-* 字段不匹配直接判定为伪造请求。
常见错误现象:403 Forbidden 或响应内容为空但状态码是 200;抓取几页后突然全部返回登录页或验证码页。
- Chrome 120+ 的真实请求中,
Sec-Ch-Ua、Sec-Ch-Ua-Mobile、Sec-Ch-Ua-Platform几乎必现,缺一即触发风控 -
Accept-Encoding: gzip, deflate若缺失,部分 CDN(如 Cloudflare)会拒绝响应或降级处理 - Header 中键名大小写敏感:用
user-agent(全小写)在某些 aiohttp 版本下会被忽略,必须用User-Agent
aiohttp.ClientSession 中正确构造 Header 的实操要点
异步场景下不能复用全局 Header 字典——因为 aiohttp 会缓存并复用连接,Header 若含动态值(如时间戳、随机 token),必须在每次 session.get() 时单独传入 headers= 参数,而非初始化 ClientSession 时固定设置。
推荐做法是封装一个 header 生成函数:
def get_headers():
return {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Sec-Ch-Ua": '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Windows"',
"Upgrade-Insecure-Requests": "1",
"Accept-Encoding": "gzip, deflate",
}
- 不要把
Cookie写死在 headers 里——改用session.cookie_jar.update_cookies()管理会话态 - 避免在 headers 中硬编码
Referer,除非你明确控制跳转链路;否则留空更安全 - 若目标站校验
Origin,只在 POST 请求中按需添加,GET 请求通常不需要
如何验证 Header 是否“足够像人”?
最可靠的方式不是看能否拿到 HTML,而是比对真实浏览器请求的原始 Header。打开 Chrome DevTools → Network → 刷一次目标页面 → 点开第一个 HTML 请求 → Headers → Request Headers,复制全部内容,逐项对照你的代码输出。
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
关键检查点:
- 是否存在
Sec-*字段且值格式合规(带双引号、逗号分隔、平台标识匹配) -
Accept和Accept-Language是否与 UA 描述的操作系统/语言一致(例如 UA 写 Windows,Sec-Ch-Ua-Platform却是"macOS"就露馅) - 有没有多余字段,比如
X-Requested-With: XMLHttpRequest—— 这种明显是 Ajax 请求的标记,爬首页时出现反而可疑
可以用 curl -v 模拟请求,把你的 headers 粘贴进去,观察响应头中的 Server 或 CF-RAY(Cloudflare 标识)是否异常变化。
被封后 Header 调试的最小闭环
封禁发生后,不要立刻换 IP 或加延时——先确认是不是 Header 问题。建立一个最小可验证单元:
- 用
requests(同步)发一次完全相同的 Header 请求,对比响应状态和内容,排除异步库本身 bug - 把
aiohttp的timeout设为 30 秒,启用raise_for_status=True,捕获具体 HTTP 错误 - 打印实际发出的请求 header:
print(dict(req.headers))(在aiohttp的on_request_starttrace config 中获取)
真正容易被忽略的是:某些站点会根据请求频率动态升级检测粒度——第一次只看 UA,高频后开始校验 Sec-* 字段组合甚至 TLS 指纹。所以 Header 修复必须配合合理并发控制(建议初始 semaphore=3)和随机 delay(300–1200ms),否则修好 Header 也撑不过十次请求。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










