根本原因是requests不执行javascript、不加载iframe、不等待ajax响应,仅返回服务器原始html;动态内容需通过selenium/playwright执行js或分析xhr接口获取。

requests 拿不到浏览器“审查元素”里看到的内容,根本原因就一个:它不执行 JavaScript,也不加载 iframe,更不会等 AJAX 响应回来再拼 DOM —— 它只管把服务器吐出来的原始 HTML 字节流原样交给你。
requests.text 和 response.content 解码方式不同,中文直接变乱码
你写 response.text 看到一堆 或乱码,不是网站编码怪,是 requests 自动猜错了编码。它默认用 ISO-8859-1 解 UTF-8 字节,一解就崩。
- 永远优先用
response.content+ 显式解码,比如response.content.decode('utf-8', errors='replace') - 不确定编码时,用
chardet.detect(response.content)['encoding']探测(注意:小响应体可能不准) - 别信
response.encoding,它常为空或错——它是从响应头Content-Type里取的,而很多网站压根不写charset=utf-8
目标元素在 response.text 里完全搜不到
这是 JS 渲染页面的典型信号。禁用浏览器 JavaScript 后刷新,如果页面只剩骨架、loading 文字或空白,那内容 100% 是 JS 动态插入的。
- 打开 F12 → Network → 刷新 → 过滤 XHR / Fetch,找返回 JSON 的请求,那些才是真实数据源
- 点开对应请求 → Headers → 检查
Referer、Authorization、X-Requested-With是否被校验,漏一个就可能返回空或 403 - 参数可能是动态生成的(如
sign、timestamp),得去页面<script></script>里搜fetch(或axios.get(,看怎么算的 - 有些数据藏在
<script id="__NEXT_DATA__"></script>或window.__INITIAL_STATE__ = {...}里,用正则比硬等渲染快得多
response.url 和你请求的 URL 不一样,但你没发现
302 重定向后 requests 默认会自动跳转,response.url 是最终地址,但你可能还在按原 URL 解析——结果当然对不上。
- 加参数
allow_redirects=False,手动控制跳转逻辑:requests.get(url, allow_redirects=False) - 检查
response.status_code == 302和response.headers.get('Location') - 某些站点重定向后还带 token 或临时参数,直接拿
Location值可能失效,得模拟完整跳转链 - iframe 内容完全不会被
requests加载,它的src是另一个独立请求,必须单独抓
最麻烦的不是 JS 渲染,而是渲染之后又做了反自动化检测:比如 Selenium 启动的 Chrome 被识别出 navigator.webdriver === true,或者 Playwright 没关掉 accept_downloads 外的指纹特征——这时候连“能加载出来”都成问题。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











