requests 拿不到页面真实数据是因为目标网页依赖 javascript 渲染,而 requests 仅获取静态 html,不执行 js,导致 vue/react 动态插入的内容根本不存在于响应中。

为什么 requests 拿不到页面真实数据
因为目标网页用 JavaScript 渲染内容,requests 只下载初始 HTML,不执行 JS,所以 document.getElementById、Vue.mount 或 React.render 生成的 DOM 根本不存在于响应体里。你用 BeautifulSoup 查 div.product-list 却返回空,不是 selector 写错,是它压根还没被 JS 插进去。
- 典型现象:
response.text里搜不到页面上明明可见的商品标题或价格 - 快速验证:浏览器打开开发者工具 → 网络(Network)→ 刷新 → 看
index.html的响应体是否含目标数据;再禁用 JS 后刷新,若页面空白或只剩骨架,基本可断定依赖 JS 渲染 - 别硬扛:强行分析 AJAX 接口虽可行,但遇到加密参数、时间戳校验、登录态绑定时,逆向成本远高于启动一个可控浏览器
用 Selenium 启动 Chrome 必须加的三个参数
不加就卡死、报错、被识别为自动化程序——这不是配置问题,是反爬机制直接拦截了默认行为。
-
--no-sandbox:Linux/CI 环境下不加会因权限失败;Windows/macOS 虽不报错,但建议统一加上 -
--disable-dev-shm-usage:避免共享内存不足导致 Chrome 崩溃(尤其 Docker 容器里) -
--disable-blink-features=AutomationControlled:隐藏navigator.webdriver这个最常被检测的标志位 - 漏掉任意一个,都可能遇到
TimeoutException、白屏、或被跳转到验证码页
等待元素出现不能只靠 time.sleep()
time.sleep(3) 看似简单,实则让脚本变脆弱:网速快时浪费时间,慢时又等不够,还掩盖了真实加载逻辑。
- 优先用
WebDriverWait+expected_conditions,例如等商品列表容器可见:WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.product-grid"))) - 避免
presence_of_element_located:它只检查 DOM 存在,不管是否渲染完成或可交互 - 超时设为 10 秒足够,设太长会让失败延迟暴露;设太短(如 2 秒)容易误判网络抖动为失败
- 如果页面用懒加载,还得额外滚动触发:
driver.execute_script("arguments[0].scrollIntoView(true);", element)
关闭浏览器前记得清理 session 和 cookies
多次运行脚本后突然被要求登录、IP 被限流,大概率是上一次的 localStorage 或 cookies 残留干扰了新会话。
- 退出前调用
driver.delete_all_cookies(),再执行driver.quit() - 不要用
driver.close()关闭标签页就完事——后台进程还在,下次启动可能复用旧上下文 - 更稳妥的做法:每次启动都指定干净用户目录,加参数
--user-data-dir=/tmp/chrome-profile-$$($$ 是随机数),避免任何状态继承 - headless 模式下尤其要注意,无界面时错误不易察觉,残留状态会悄悄累积
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











