使用Scrapy+Splash爬取Lider超市网站时无法获取搜索框元素的问题
解决Splash无法定位Lider超市官网搜索框的问题
问题背景
使用Scrapy结合Splash爬取智利Lider超市官网时,尝试通过Lua脚本定位class为ais-SearchBox-input的搜索框并输入关键词"fideos",但执行脚本时触发assertion failed!错误——尽管页面确实存在该元素。
原脚本:
function main(splash) local url = splash.args.url assert(splash:go(url)) splash:set_viewport_full() search_input = assert(splash:select('.ais-SearchBox-input')) search_input.focus() search_input:send_text("fideos") assert(splash:wait(3)) return { html = splash:html(), png = splash:png(), } end
错误信息:
Error happened while executing Lua script Lua error: [string " function main(splash) ..."]:7: assertion failed! { "error": 400, "type": "ScriptError", "description": "Error happened while executing Lua script", "info": { "source": "[string \" function main(splash)\r...\"]", "line_number": 7, "error": "assertion failed!", "type": "LUA_ERROR", "message": "Lua error: [string \" function main(splash)\r...\"]:7: assertion failed!" } }
错误原因
从元素class前缀ais-可判断,该搜索框是Algolia InstantSearch动态渲染的元素,并非页面初始HTML自带。原脚本中splash:go(url)后立即调用select,此时JavaScript还未完成元素渲染,导致select返回nil,触发assert断言失败。
解决方案
核心是等待目标元素完全加载后再进行定位操作,推荐使用Splash的splash:wait_for_selector方法(比固定时长等待更高效精准),确保元素存在后再执行后续操作。
修改后的完整脚本
function main(splash) local url = splash.args.url assert(splash:go(url)) splash:set_viewport_full() -- 等待目标搜索框元素加载完成,超时时间设为5秒(可按需调整) assert(splash:wait_for_selector('.ais-SearchBox-input', 5)) local search_input = assert(splash:select('.ais-SearchBox-input')) search_input:focus() search_input:send_text("fideos") -- 等待搜索请求完成、结果渲染 assert(splash:wait(3)) return { html = splash:html(), png = splash:png(), } end
关键修改点
- 添加
splash:wait_for_selector('.ais-SearchBox-input', 5):精准等待目标元素出现,超时时间可根据页面加载速度调整 - 给
search_input加上local修饰符,符合Lua局部变量规范 - 保留后续
wait(3)确保搜索结果完全渲染
额外排查点
如果仍无法定位元素,可检查以下内容:
- 元素是否嵌套在
iframe中:可通过splash:select_frame()切换到对应iframe后再定位 - 页面是否有反爬机制:比如需要模拟滚动页面等用户行为才能触发元素渲染
- Splash版本兼容性:确保使用的Splash版本支持当前页面的JavaScript特性
内容的提问来源于stack exchange,提问作者smith
相关产品推荐
相关产品推荐

