使用Playwright爬取kick.com无法触发无限滚动的问题求助
问题描述
爬取https://kick.com/browse/categories页面时,页面滚动会动态加载新分类卡片,但使用Playwright时,无论尝试哪种滚动方法,page.content()始终仅返回初始加载的64个分类链接。在Chrome调试控制台执行div.scrollBy(0, window.innerHeight); document.documentElement.outerHTML;时,HTML会逐步变长,能获取更多带/category/的href链接。
初始化代码如下:
async with async_playwright() as p: browser = await p.chromium.launch( args=[f"--proxy-server={PROXY}"], headless=True, executable_path=CHROME ) context = await browser.new_context( user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" ) page = await context.new_page() await page.goto("https://kick.com/browse/categories")
已尝试的方法:
- 调用
scrollBy滚动指定容器 - 发送PageDown按键
- 鼠标滚轮滚动
- 滚动到列表最后一个元素
解决方案
1. 定位正确的滚动容器
你之前使用的#main-container可能不是实际负责滚动的元素。打开Chrome控制台执行document.querySelectorAll('[style*="overflow-y: auto"]'),找到真正承载分类列表的滚动容器(实际页面中为div#categories-grid)。
修改滚动逻辑,针对正确容器操作:
const scrollContainer = document.querySelector('div#categories-grid'); scrollContainer.scrollTop = scrollContainer.scrollHeight; // 直接滚动到底部
2. 滚动后等待新元素加载,而非依赖networkidle
networkidle会在网络请求完成后触发,但页面渲染新元素仍需时间。改为等待分类卡片数量增加,确保新内容加载完成:
await page.wait_for_selector("#main-container") previous_count = await page.locator('a[href*="/category/"]').count() for _ in range(20): # 按需调整滚动次数 # 滚动到容器底部 await page.evaluate(""" const scrollContainer = document.querySelector('div#categories-grid'); scrollContainer.scrollTop = scrollContainer.scrollHeight; """) # 等待新分类出现,超时10秒 try: await page.wait_for_function( "document.querySelectorAll('a[href*=\"/category/\"]').length > arguments[0]", args=[previous_count], timeout=10000 ) except: break # 无新元素加载,停止循环 # 更新计数 previous_count = await page.locator('a[href*="/category/"]').count()
3. 调整Headless模式设置
旧版Headless模式可能存在渲染限制,尝试使用Playwright的新版Headless模式(1.32+支持),或暂时关闭Headless测试:
browser = await p.chromium.launch( args=[f"--proxy-server={PROXY}"], headless="new", executable_path=CHROME )
4. 模拟真实滚动行为
快速滚动可能被页面的懒加载逻辑忽略,尝试分多次小幅度滚动并添加短等待:
await page.wait_for_selector("#main-container") scroll_container = page.locator("div#categories-grid") for _ in range(50): await scroll_container.evaluate("el => el.scrollBy(0, 500)") await page.wait_for_timeout(500) # 等待500ms,给页面加载时间
5. 排查代理与UA问题
确保代理未被网站拦截,可暂时移除代理测试;或更换UA为当前主流浏览器的最新版本,避免被识别为爬虫。
内容的提问来源于stack exchange,提问作者Ginni Song
相关产品推荐
相关产品推荐

