lua - 在 Splash 中使用 Lua 脚本访问 google.com 的 DOM
问题描述
我正在尝试在 Splash 中运行 Lua 脚本来执行 Google 搜索并截取搜索结果的屏幕截图。当我尝试在 Lua 脚本中使用 xpath 或 css 选择器选择 Google 搜索框时,出现此错误:
{
"error": 400,
"type": "ScriptError",
"description": "Error happened while executing Lua script",
"info": {
"message": "[string \"function main(splash, args)\r...\"]:9: cannot select the specified element {'type': 'JS_ERROR', 'js_error_type': 'SyntaxError', 'js_error_message': 'SyntaxError: DOM Exception 12', 'js_error': 'Error: SyntaxError: DOM Exception 12', 'message': \"JS error: 'Error: SyntaxError: DOM Exception 12'\"}",
"type": "SPLASH_LUA_ERROR",
"splash_method": "select",
"source": "[string \"function main(splash, args)\r...\"]",
"line_number": 9,
"error": "cannot select the specified element {'type': 'JS_ERROR', 'js_error_type': 'SyntaxError', 'js_error_message': 'SyntaxError: DOM Exception 12', 'js_error': 'Error: SyntaxError: DOM Exception 12', 'message': \"JS error: 'Error: SyntaxError: DOM Exception 12'\"}"
}
}
这是我的 Lua 脚本:
function main(splash, args)
splash.private_mode_enabled = false
splash:set_user_agent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0")
assert(splash:go(args.url))
assert(splash:wait(1.0))
search_box = assert(splash:select("//div[@class='a4bIc']/input"))
search_box:focus()
search_box:send_text('my user agent')
search_box:send_keys('<Enter>')
assert(splash:wait(2.0))
return splash:png()
end
我尝试设置自定义标头,以私有模式运行脚本,但没有任何效果。但是,使用duckduckgo.com 时,相同的脚本运行没有错误并且输出正确。当目标 URL 是 google.com 时,问题就来了。我认为谷歌检测到浏览器正在由机器人(脚本)控制,因此它禁用了对 DOM 树的访问。
知道如何使它工作吗?
解决方案
也许页面还没有完全下载/渲染
function main(splash, args)
splash.private_mode_enabled = false
splash:set_user_agent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0")
local ok, reason = assert( splash:go(args.url) )
if ok then
local wait, increment, maxwait = 0, 0.1, 10
while wait < maxwait and not splash:select("//div[@class='a4bIc']/input") do
splash:wait(increment) -- wait until it exists, or times out
wait = wait +increment
end
if wait >= maxwait then
print('Timed out')
else
search_box = splash:select("//div[@class='a4bIc']/input")
search_box:focus()
search_box:send_text('my user agent')
search_box:send_keys('<Enter>')
splash:wait(2.0)
return splash:png()
end
else
print( reason ) -- see if it tells you why
end
end
推荐阅读
- sql - 如何在 SQL Server 中将数据从 prod 服务器插入到 dev 服务器
- python - 动态规划,最小硬币数量
- java - Android 权限 ACCESS_FINE_LOCATION 始终被拒绝
- ios - MapBox 用户位置图标 | iOS
- javascript - 获取当前 tbody 下方的 tbody
- java - 将一些 JSON 从 php 解析到 android 时出现问题
- android - 离子 3 谷歌登录
- javascript - 如何解析数组(electron/node.js)中 JSON 文件中的值?
- redirect - WSFederation ADFS 登录循环.Net Core 2.1
- d3.js - 使用 d3 创建 InnerWidth 和 InnerHeight 使网格不在边框上