requests+BeautifulSoup拿不到瀑布流新内容,因初始HTML仅含首屏数据,后续由JavaScript通过AJAX动态插入;应先抓包分析XHR/Fetch接口,优先直调JSON接口,必要时用Playwright执行JS并显式等待。

为什么 requests + BeautifulSoup 拿不到瀑布流新加载的内容
因为无限滚动的瀑布流页面,初始 HTML 里只包含首屏数据,后续内容靠 JavaScript 发起 AJAX 请求(通常是 fetch 或 XMLHttpRequest)动态插入 DOM。而 requests 只下载原始 HTML,不执行 JS,BeautifulSoup 自然解析不到滚动后才出现的元素。
抓包定位真实数据接口比直接渲染网页更可靠
打开浏览器开发者工具(F12),切到 Network 标签页,下拉触发加载,观察新增的 XHR/Fetch 请求。重点看:
- 请求 URL 是否含分页参数(如
offset=20、page=2、cursor=abc123) - 响应格式是 JSON 还是 HTML 片段(多数为 JSON)
- 请求头是否带
Referer、X-Requested-With或认证 token - 是否有反爬字段(如
X-Api-Key、sign参数需动态计算)
一旦确认接口稳定且无强校验,用 requests 直接调用它,比启动整个浏览器快得多、稳得多。
需要执行 JS 时,优先选 Playwright 而非 Selenium
如果接口加密复杂(如 sign 由前端 JS 动态生成)、或页面依赖大量交互状态(如登录态嵌在 WebWorker 里),必须走真实浏览器。这时:
立即学习“Python免费学习笔记(深入)”;
-
Playwright启动更快、内存占用更低、API 更简洁,page.evaluate()可直接取 JS 执行结果 - 避免用
Selenium:默认等待策略容易误判“加载完成”,find_elements在动态节点上常返回空列表 - 关键操作必须加显式等待:
page.wait_for_selector(".item", state="attached"),不能只靠time.sleep() - 滚动到底部后,务必等新节点真正插入(用
page.locator配合count()判断数量变化)
示例:等瀑布流加载 3 批后停止
for _ in range(3):
page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
page.wait_for_timeout(800) # 短暂缓冲
page.wait_for_selector(".item", state="attached", timeout=5000)滚动加载失败的三个高频原因
不是代码写错,而是忽略了页面本身的机制:
- 接口返回
403或空数据?检查headers是否漏了User-Agent或Cookie,有些站点会校验Sec-Fetch-*头 - 滚动后没触发请求?目标元素可能被
display: none或visibility: hidden挡住,Playwright 的scroll_into_view_if_needed()比scrollTo更稳妥 - 数据重复或漏采?后端可能用
cursor分页,但下次请求必须用上一页响应里的新cursor值,不能简单递增数字
真实场景里,cursor 类型五花八门:base64 编码字符串、毫秒时间戳、甚至 AES 加密后的值——得先看清响应结构再决定怎么提取和复用。


















