requests无法获取无限滚动内容,因其不执行JS,仅返回初始HTML;后续数据需通过XHR接口动态加载,应优先逆向接口,必要时用Selenium配合显式等待和精准滚动控制。

为什么 requests 直接请求拿不到无限滚动后的内容
因为无限滚动页面的后续数据几乎都靠 JS 动态拉取,requests 只能拿到初始 HTML,不执行 JS,自然看不到滚动触发的接口响应或 DOM 插入结果。真实场景中,你用浏览器开发者工具 Network 面板看到的 /api/feed?offset=20 这类请求,requests 不会自动发——它没上下文,也不懂“滚到底部”这个动作。
实操建议:
- 先打开浏览器 DevTools → Network → 切到 XHR/Fetch,手动滚动几次,确认真实加载接口和参数规律(比如是否带
cursor、page或时间戳) - 如果接口规则清晰且无加密/签名,优先绕过 Selenium,直接用
requests+ 逆向参数模拟翻页(更快、更稳) - 若接口有 anti-bot 头、token 动态生成、或依赖页面内 JS 计算(如
document.querySelectorAll('.item').length),才必须上 Selenium
用 driver.execute_script() 滚动比 ActionChains 更可靠
ActionChains(driver).scroll_by_amount(0, 1000).perform() 在某些页面会失效——比如容器不是 body 而是某个带 overflow-y: auto 的 div,滚动对象错了就白忙活。而原生 JS 滚动能精准控制目标元素。
实操建议:
- 先定位滚动容器:
container = driver.find_element(By.CSS_SELECTOR, ".feed-container"),再执行:driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", container) - 滚动后必须等新内容出现,不能只靠
time.sleep();用WebDriverWait等待新节点数量增加或某个加载中提示消失:wait.until(lambda d: len(d.find_elements(By.CSS_SELECTOR, ".item")) > last_count) - 避免无限循环:加最大重试次数(比如最多滚动 10 次),并检查每次滚动后新增元素数是否为 0
find_elements 返回空列表?多半是没等 DOM 更新完
常见错误现象:滚动后立刻调 driver.find_elements(By.CLASS_NAME, "post"),结果还是旧数据甚至空列表。这不是 selector 写错了,而是 JS 还在解析、渲染、插入节点,Selenium 已经急着去查了。
实操建议:
- 别依赖
time.sleep(2)—— 网络快时浪费时间,慢时又不够;改用显式等待:WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".item:last-child"))) - 如果页面用 React/Vue,新内容可能先插入空容器,再异步填充文本;此时要等内部文本出现,而不是只等元素存在:
EC.text_to_be_present_in_element((By.CSS_SELECTOR, ".item .title"), "expected text") - 滚动前后记录元素数量做断言,方便定位卡点:
before = len(driver.find_elements(By.CSS_SELECTOR, ".item")),滚动后再查,差值为 0 就说明没加载成功
关闭图片加载和禁用 CSS 能明显提速,但小心布局错乱
Selenium 默认加载所有资源,图片、字体、CSS 文件拖慢速度,尤其在抓几百条数据时。关掉它们可让单次滚动从 3 秒降到 0.8 秒左右。但有些页面靠 CSS 控制显示逻辑(比如用 display: none 切换内容区),禁用后反而找不到目标元素。
实操建议:
- 启用无图模式:
chrome_options.add_argument("--blink-settings=imagesEnabled=false") - 禁用 CSS(谨慎):
chrome_options.add_argument("--disable-features=CSSStyling"),仅在确认页面结构不依赖样式时使用 - 更安全的提速方式:禁止加载字体和视频:
prefs = {"profile.managed_default_content_settings.images": 2, "profile.default_content_setting_values.fonts": 2, "profile.default_content_setting_values.video": 2},再通过chrome_options.add_experimental_option("prefs", prefs)注入
滚动加载这事,核心不在“怎么滚”,而在“怎么确认真的加载完了”。DOM 更新延迟、JS 执行时机、反爬策略变化——任何一个环节卡住,都会让看似稳定的脚本突然返回空结果。多打几个日志,少信一次 sleep。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











