requests无法获取动态渲染文本,因目标内容由JS执行后插入DOM;需用Selenium等待元素可见再提取,或正则解析script标签中的JSON数据。

静态 requests + BeautifulSoup 拿不到的文本,基本都藏在 JavaScript 渲染之后——这不是你 selector 写错了,是页面根本没生成那些 DOM 节点。
为什么 requests.get() 返回的 HTML 里没有目标文字?
因为目标内容由前端框架(如 React/Vue)或 AJAX 请求动态插入,原始响应体中只有一段空壳 HTML 和一堆 <script> 标签。浏览器执行 JS 后才把数据挂到 DOM 上,而 requests 不执行 JS,自然看不到。
- 常见现象:用
soup.find_all("div", class_="content")返回空列表,但浏览器开发者工具里明明能看到该元素 - 检查方法:对比
response.text和浏览器“查看网页源代码”(不是“检查元素”),两者一致就说明是纯静态;不一致,大概率是动态渲染 - 注意:有些网站会服务端渲染(SSR)一部分内容,但关键字段仍由客户端 JS 补全,此时仍需等待 JS 执行完成
用 Selenium 等待并提取动态文本的实操要点
核心不是“启动浏览器”,而是“等真实内容出现后再取”。盲目调用 driver.page_source 或 element.text 很容易拿到空值或旧数据。
- 别用
time.sleep()硬等:网络波动、JS 加载时长不固定,太不可靠 - 优先用
WebDriverWait+expected_conditions:例如presence_of_element_located((By.CSS_SELECTOR, ".article-title")) - 提取文本前确认元素已可见:
visibility_of_element_located比presence更严格,避免拿到display: none的节点 - 如果目标是父元素里的孤立文本节点(比如
<p><strong>Time:</strong> "13:45"</p>中的"13:45"),直接element.text会连带把<strong>文本拼进去,得用driver.execute_script("return arguments[0].lastChild.textContent.trim();", element)
从 script 标签里提取 JSON 嵌入数据的注意事项
不少 SPA 网站把初始数据塞进 <script> 标签的全局变量里(如 window.__INITIAL_STATE__ 或 window.DATA),这是比 Selenium 更轻量、更稳定的提取路径。
立即学习“前端免费学习笔记(深入)”;
- 正则要写宽泛些:
r"window\.__INITIAL_STATE__\s*=\s*(\{.*?\});",加\s*处理空格/换行,.*?防止贪婪匹配跨段 - 别假设 JSON 一定以
};结尾:有的用}),有的末尾无分号,建议用re.search(r"window\.__INITIAL_STATE__\s*=\s*({.*?});?\s* 并手动补全括号再 <code>json.loads() - 提取后务必检查 key 是否存在:
data.get("articlesList", {}).get("articlesList", {}),避免KeyError - 注意编码:如果页面是 GBK 编码但
response.text自动解成了 UTF-8,正则可能匹配失败,此时应改用response.content.decode("gbk")
最常被忽略的一点:动态内容可能依赖登录态或特定 Cookie。Selenium 启动的是干净会话,若目标数据需要鉴权,得先手动登录或注入已有 Session Cookie,否则等再久也拿不到真实数据。



















