尝试使用 Node.js 中的无头 Google Chrome
你好。
我是Mandai,负责Wild 开发团队。
之前写过一篇题为《
Headless 模式现已成为 Google Chrome 59 标准,我们来试试吧》的文章 | Beyond Co., Ltd. Google Chrome 更新是在后台自动完成的,因此您可能不会定期注意到它们,因此我想经常检查它们。
这次,我想从 Node.js 以无头模式启动 Google Chrome,并通过 chrome-remote-interface 模块控制它。
示例程序无法运行!
在上一篇文章中,我们了解了如何在命令行中以无头模式启动 Google Chrome 并捕获屏幕,但由于仅通过 shell 脚本很难与其他系统集成,因此我们决定使用 Node.js 来启动它。从 .js 并尝试按原样检索内容的部分。
基本上,Headless Chrome | Web | Google Developers,但它不起作用,所以我尝试使用此代码作为基础并对其进行了一些修改。
const ChromeLauncher = require('chrome-launcher'); const CDP = require('chrome-remote-interface'); const url = 'https://beyondjapan.com'; var launcherKill = (client, launcher, args = null ) => { console.log(args); } ChromeLauncher.launch({ port: 9222, chromeFlags: [ // '--disable-gpu', // 必要时启用 '- -headless' , // '--no-sandbox', // 必要时启用 ], }).then(launcher => { CDP(client => { const {Page, DOM} = client; Promise.all([ Page.enable (), DOM.enable(), ]).then(() => { Page.navigate({url : url}); Page.loadEventFired(() => { DOM.getDocument(( error, params) => { if (error){ console.log(params); return; } const opts = { nodeId : params.root.nodeId, 选择器 : 'a' }; params) => { if (error){ launcher.kill() } var Promise = []; var getDomAttribute = (DOM, nodeId, count) => { return new Promise((解析,拒绝)=>{ const opts = { nodeId : nodeId }.getAttributes(opts, (error, params) => { if (!error) console.log(count, params.attributes [1]); (); }) }) }; console.log(params.nodeIds.forEach(elm => { Promise.push(getDomAttribute(DOM, elm, Promise.length)); }); .all(promises).then(()=>{ launcher.kill(); }) }) }) }) }) }).on('error', error => { console.error(error) 启动器。杀死();})})
工艺流程如下:
- 使用 chrome-launcher 模块启动 Google Chrome
- 启动后,使用 chrome-remote-interface 模块连接到 DevTools 协议。
- 从DevTools客户端对象移动到指定的URL并获取数据
- 从 DOM 获取所有 A 标签并在标准输出上显示 href 值
就变成了。
我无法正确调查,但似乎第 49 行附近的 DOM.getAttributes 方法正在异步运行,如果我在运行 forEach 后立即停止 Google Chrome,我将无法读取 DOM 的内容。
这次,我使用 Promise 等待读取所有 DOM,然后再停止 Google Chrome。
发生错误
如果您在启动脚本时遇到如下错误,您可能需要稍微调整一下 Google Chrome 的启动选项。
没有可用的沙箱!如果您想要危险地生活并且需要,请更新您的内核或参阅 https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md 以获取有关使用 SUID 沙箱进行开发的更多信息。一个立即的解决方法,您可以尝试使用 --no-sandbox。
似乎有一个使用 Google Chrome 沙箱环境的库版本,其硬编码了 Google Chrome 可执行文件的路径,因此无法使用沙箱。
为了正确避免此错误,看来您需要更改 sandbox/linux/suid/sandbox.cc 中的硬编码路径并重建。
另外,在紧急情况下或者如果您只是临时需要它,您可以通过取消注释启动选项“--no-sandbox”来启动它。
请注意,在这种情况下,您将在不使用沙箱的环境中启动 Google Chrome,这会增加安全风险。
现在,你用它做什么? (概括)
由于 DevTools 可以直接干扰 Google Chrome,因此似乎可以执行比以前更真实的抓取。
根据您的操作方式,也可以测试 JavaScript 的行为,因此我认为能够使用代码库在后台自动运行这些测试会很方便。
由于网站的结构,似乎可以创建一个系统,可以监控用curl等无法监控的内容是否正常运行。
就是这样。