Gab*_*Koo 5 python selenium screen-scraping google-chrome node.js
我一直在尝试抓取一个受 Distil Networks 保护的网站,其中使用 selenium(使用 Python)总是会失败。
我做了一些搜索,我的结论是该站点可以通过使用某种 javascript 检测到您正在使用 Selenium。然后我掠夺了chrome-remote-interface
,就像这是我想要的东西,但后来我被卡住了。
我想做的是自动化以下步骤:
我知道我可以通过以下方式打开 Chrome 实例进行调试:
google-chrome --remote-debugging-port=9222
Run Code Online (Sandbox Code Playgroud)
我可以通过以下方式在节点上打开控制台:
chrome-remote-interface -t 127.0.0.1 -p 9222 inspect -r
Run Code Online (Sandbox Code Playgroud)
我还可以运行简单的脚本,如
Page.navigate({url:"https://google.com"})
Runtime.evaluate({expression:"1+1"})
Run Code Online (Sandbox Code Playgroud)
但是就像我不能像在 Chrome 开发人员工具控制台上那样直接在 Node.js 上获取 DOM。基本上我想要的是在 Node 上运行脚本,就像我可以在 Chrome 开发者工具控制台上做的那样。
此外,没有足够的chrome-remote-interface
用于抓取的文档。有什么好的链接吗?
我知道两年前就有人问过这个问题,但为了文档目的,让我把它写在这里。
-- 行业工具 --
我尝试了与您相同的技术(使用远程调试器进行抓取),但我没有使用 Python,而是使用 Node.js,因为它具有异步性质,从而更容易使用远程的 Websockets调试器依赖。
-- Runtime.evaluate --
我注意到的一件事是,如果表达式涉及异步调用,则 Runtime.evaluate 不是恢复任何数据的有效选项,因为它返回调用函数的结果而不是回调函数的结果。您必须坚持使用同步表达式。
例子:
Array.from(document.getElementByTagName('tr'))
.map((e)=>e.children[2].innerHTML)
.filter((e)=>e.length>0)
Run Code Online (Sandbox Code Playgroud)
另一件事是,当您的表达式返回一个数组 Runtime.evaluate 时,只需提及该表达式返回一个数组,而不是数组本身!(我知道这很令人气愤)我通过简单地将数组编码为页面上下文中的 JSON 字符串,然后在到达 Node.js 时将其解码回对象来解决这个问题。例如,上面的表达式需要是:
JSON.stringify(
Array.from(document.getElementByTagName('tr'))
.map((e)=>e.children[2].innerHTML)
.filter((e)=>e.length>0)
)
Run Code Online (Sandbox Code Playgroud)
-- 导航 --
当您使用“Page.navigate”、“.click()”、“.submit()”、“window.location.href=...”或任何其他方式触发页面加载时,这一点很重要在使用 Runtime.evaluate 发送更多指令之前了解下一页何时完全加载。我做了一个技巧,要求调试器向我发送页面加载事件(在文档中查找 Page.enable 方法),然后等待“Page.loadEventFired”事件,然后再发送更多表达式。
归档时间: |
|
查看次数: |
2920 次 |
最近记录: |