Scrapy+Splash渲染页面不完全求助:目标站点产品列表为空
解决Scrapy+Splash抓取动态页面产品列表为空的问题
嘿,我之前爬动态渲染站点时也踩过类似的坑,给你几个实用的调整方向和脚本优化方案,应该能搞定这个问题:
1. 先补全反爬特征模拟
很多站点会识别Splash的默认请求特征(比如UA太生硬),先给Splash设置一个真实的浏览器UA,同时确保JS功能正常启用:
function main(splash, args) -- 设置真实Chrome浏览器UA splash:set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") splash:set_javascript_enabled(true) -- 保险起见,明确开启JS(默认已开启) splash:go(args.url) -- 先等基础框架加载完成 assert(splash:wait(3)) -- 后续滚动和等待逻辑 return { html = splash:html(), png = splash:png() } end
2. 优化滚动加载逻辑
单次滚动300像素大概率触发不了站点的加载机制,大部分电商站点需要滚动到页面底部才会加载更多产品,试试循环滚动的方式:
function main(splash, args) splash:set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") splash:go(args.url) assert(splash:wait(3)) -- 定义JS工具函数:滚动到底部、获取页面总高度 local scroll_to = splash:jsfunc("window.scrollTo") local get_page_height = splash:jsfunc("function() { return document.body.scrollHeight; }") -- 循环滚动5次(可根据实际加载速度调整次数) for i = 1, 5 do scroll_to(0, get_page_height()) -- 每次滚动后等待2秒,让产品内容加载完成 assert(splash:wait(2)) end return { html = splash:html(), png = splash:png() } end
3. 等待特定元素而非固定时长
固定等20秒太盲目,更精准的方式是等待产品列表的DOM元素出现——先去目标站点里确认产品项的选择器(比如.product-item),然后用wait_for_selector等待:
function main(splash, args) splash:set_user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") splash:go(args.url) -- 等待产品列表元素出现,超时15秒 assert(splash:wait_for_selector(".product-item", 15)) -- 再滚动加载更多内容 local scroll_to = splash:jsfunc("window.scrollTo") local get_page_height = splash:jsfunc("function() { return document.body.scrollHeight; }") scroll_to(0, get_page_height()) assert(splash:wait(2)) return { html = splash:html(), png = splash:png() } end
额外小技巧
- 先通过Splash的Web界面(比如本地的
http://localhost:8050)测试你的Lua脚本,直接看渲染后的页面是否有产品列表,能快速判断是脚本问题还是站点反爬限制。 - 可以尝试添加
splash:set_viewport_full(),让Splash渲染完整视口,避免因为视口太小导致内容不加载。
内容的提问来源于stack exchange,提问作者marcins
相关产品推荐
相关产品推荐

