Node.js 使用 chrome-远程接口抓取

Node.js scraping with chrome-remote-interface

我一直在尝试抓取受 Distil Networks 保护的网站, 其中使用硒(Python)总是会失败。

我进行了一些搜索,我的结论是该站点可以通过某种 javascript 检测到您正在使用 Selenium。然后我在 chrome-remote-interface 抢了一把,好像这是我想要的东西,但后来我卡住了。

我想做的是自动执行以下步骤:

  1. 打开一个Chrome实例
  2. 导航到页面
  3. 运行一些javascript
  4. 收集数据并保存到文件
  5. 重复步骤 2 - 4

我知道我可以通过以下方式打开 Chrome 的实例进行调试:

google-chrome --remote-debugging-port=9222

我可以通过以下方式在节点上打开控制台:

chrome-remote-interface -t 127.0.0.1 -p 9222 inspect -r

我也可以 运行 像

这样的简单脚本
Page.navigate({url:"https://google.com"})
Runtime.evaluate({expression:"1+1"})

但是我无法像在 Chrome 开发人员工具控制台上那样直接在 Node.js 上获取 DOM。基本上我想要的是 Node 上的 运行 脚本,就像我可以在 Chrome 开发人员工具控制台上做的那样。

此外,chrome-remote-interface 上没有足够的文档可供抓取。有什么好的链接吗?

JavaScript 由 Runtime.evaluate 评估的表达式在页面上下文中执行,就像在 DevTools 控制台中发生的一样。

您可以使用 DOM domain, e.g., DOM.getDocument, DOM.querySelector 等与 DOM 互动

还要记住 chrome-remote-interface 主要是一个库,意思是它允许您编写自己的 Node.js 应用程序,chrome-remote-interface inspect 只是一个实用程序。

您可以在几个地方获得帮助:

如果您有更具体的问题,我很乐意为您提供帮助。

最后你可能想看一下 automated-chrome-profiling,我认为它在结构上与你要实现的目标相似。

我知道两年前有人问过这个问题,但出于文档目的,让我把它写在这里。

-- 交易工具 --
我尝试了与您相同的技术(使用远程调试器进行抓取)但是我没有使用 Python 我使用了 Node.js 因为它是异步的,因此更容易使用远程调试器所依赖的 websockets上。

-- Runtime.evaluate --
我注意到的一件事是,如果您的表达式涉及异步调用,Runtime.evaluate 不是恢复任何数据的有效选项,因为它 returns 是调用函数的结果,而不是回调函数的结果。你必须坚持使用同步表达式。
示例:

Array.from(document.getElementByTagName('tr'))
    .map((e)=>e.children[2].innerHTML)
    .filter((e)=>e.length>0)

另一件事是当你的表达式 returns 一个数组 Runtime.evaluate 只是提到表达式返回一个数组而不是数组本身! (真气我知道) 我通过简单地将数组编码为页面上下文中的 JSON 字符串然后在它到达 Node.js 时将其解码回对象来绕过它。例如,上面的表达式需要是:

JSON.stringify(
    Array.from(document.getElementByTagName('tr'))
        .map((e)=>e.children[2].innerHTML)
        .filter((e)=>e.length>0)
)

-- 导航--
当您使用 "Page.navigate"、“.click()”、“.submit()”、"window.location.href=..." 或任何其他方式触发页面加载时,在发送之前了解下一页何时完全加载非常重要Runtime.evaluate 更多说明。 我做了一个技巧,要求调试器向我发送页面加载事件(在文档中查找 Page.enable 方法),然后在发送更多表达式之前等待 "Page.loadEventFired" 事件。