butubb
21ff01b894
fix(douyin): 缺 sec-ch-ua 请求头,网关回 200 + 空 body(不是「账号被封」)
先纠正一个我上一轮给错的结论:日志里的 `account blocked` **不是抖音说的**,是
MediaCrawler 自己编的:
if response.text == "" or response.text == "blocked":
raise Exception("account blocked")
真实情况只是**抖音返回了空 body**。我把它读成了「账号被风控」,还写进了运行历史和
给用户的结论里 —— 用户质疑「我网页版和手机版都能正常登录」,一查,他是对的。
实测定位(同一 URL、同一 cookie、同一参数):
浏览器页面内 fetch : 200, 7077 字节 ✓
httpx : 200, 0 字节 ✗
带 a_bogus : 0 字节
不带 a_bogus : 0 字节
四种 msToken 变体 : 全部 200 有数据(所以不是它)
用浏览器那次的完整头重放 httpx : 200, 7077 字节 ✓
浏览器那次请求比爬虫多的,只有这三个头:
sec-ch-ua: "Google Chrome";v="155", "Chromium";v="155", "Not(A:Brand";v=24
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Linux"
爬虫的 UA 是从页面读的(声称是 Chrome 155)却不带 sec-ch-ua —— 「Chrome 的 UA +
没有 sec-ch-ua」是最典型的机器人特征。网关的回应方式是不报错、不给原因,回一个
200 + 空 body,HTTP 状态还写在成功那一栏。
修:media_platform/douyin/help.py 新增 client_hint_headers(),从
navigator.userAgentData 现算这三个头(现算而不是写死 —— 写死的版本号一旦和 UA 里的
对不上,就又是一个可疑特征);core.py 建客户端时带上。
诚实说明:我无法解释**为什么之前能跑**(run 34 还是成功的,40 分钟后同样的代码就
不行了)。最可能是字节那边收紧了这道校验,但我没有证据,别当结论。
测试 +8:还原出的头与真实浏览器抓到的值逐字一致;拿不到 userAgentData 时返回空而不
凭空编造(编一组和 UA 对不上的头比不带头更糟);mobile 标志;platform 缺失时仍发另两个。
2026-10-10 16:47:49 +08:00
..
2025-11-18 12:24:02 +08:00
2026-09-19 13:25:59 +08:00
2026-10-10 16:47:49 +08:00
2025-11-18 12:24:02 +08:00
2025-12-26 23:27:19 +08:00
2026-10-10 16:47:49 +08:00
2026-10-10 15:29:02 +08:00
2026-09-17 22:54:22 +08:00