无头Chrome:自动化Web测试和抓取的强大工具
核心要点
chrome-remote-interface
模块(用于简化命令和通知的抽象)和chrome-launcher
模块(用于跨多个平台从Node.js中启动Chrome)。captureScreenshot
函数在导航网站时捕获页面截图。在我们的工作中,经常需要反复复制用户旅程,以确保在更改网站时页面提供一致的体验。实现这一目标的关键是允许我们编写这些测试脚本的库,以便我们可以对它们运行断言并维护结果文档。这就是无头浏览器的作用:命令行工具,使您可以以编程方式模拟用户与网站的交互,并捕获结果用于测试。
多年来,许多人一直在使用PhantomJS、CasperJS和其他工具来完成这项工作。但是,正如爱情一样,我们的心可能会转移到其他地方。从Chrome 59版本(Windows用户为60版本)开始,Chrome自带了它自己的无头浏览器。虽然它目前不支持Selenium,但它使用Chromium和Blink引擎,也就是说,它模拟了在Chrome中的实际用户体验。
本文的代码可以在我们的GitHub仓库中找到。
从命令行运行无头Chrome
从命令行运行无头Chrome相对容易。在Mac上,您可以为Chrome设置别名,并使用--headless
命令行参数运行:
<code class="language-bash">alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome" chrome --headless --disable-gpu --remote-debugging-port=9090 https://www.sitepoint.com/</code>
在Linux上,它甚至更容易:
<code class="language-bash">google-chrome --headless --disable-gpu --remote-debugging-port=9090 https://www.sitepoint.com/</code>
--headless
:无需UI或显示服务器依赖项运行--disable-gpu
:禁用GPU硬件加速。目前暂时需要此参数。--remote-debugging-port
:在指定的端口上启用通过HTTP进行的远程调试。您还可以与请求的页面交互,例如,要将document.body.innerHTML
打印到标准输出,您可以执行以下操作:
<code class="language-bash">google-chrome --headless --disable-gpu --dump-dom http://endless.horse/</code>
如果您好奇还有什么可能性,可以在这里找到完整的参数列表。
在Node.js中运行无头Chrome
然而,本文的重点不是命令行,而是如何在Node.js中运行无头Chrome。为此,我们需要以下模块:
chrome-remote-interface
:JavaScript API提供命令和通知的简单抽象。chrome-launcher
:允许我们在多个平台上的Node.js中启动Chrome。然后我们可以设置我们的环境。这假设您的机器上已安装Node.js和npm。如果不是这种情况,请查看我们的教程。
<code class="language-bash">alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome" chrome --headless --disable-gpu --remote-debugging-port=9090 https://www.sitepoint.com/</code>
之后,我们要使用headless-chrome实例化一个会话。让我们从在项目文件夹中创建一个index.js
文件开始:
<code class="language-bash">google-chrome --headless --disable-gpu --remote-debugging-port=9090 https://www.sitepoint.com/</code>
首先,我们正在引入依赖项,然后创建一个自调用函数,该函数将实例化Chrome会话。请注意,在撰写本文时需要--disable-gpu
标志,但在您阅读本文时可能不需要,因为它只是一个解决方法(正如Google推荐的那样)。我们将使用async/await
来确保我们的应用程序在执行后续步骤之前等待无头浏览器启动。
接下来,我们需要公开测试所需的域:
<code class="language-bash">google-chrome --headless --disable-gpu --dump-dom http://endless.horse/</code>
这里最重要的Page对象——我们将使用它来访问呈现到UI的内容。这将也是我们指定导航位置、交互元素以及运行脚本的位置。
探索Page
初始化会话并定义域后,我们可以开始导航网站。我们要选择一个起点,因此我们使用上面启用的Page域进行导航:
<code class="language-bash">mkdir headless cd headless npm init -y npm install chrome-remote-interface --save npm install chrome-launcher --save</code>
这将加载页面。然后,我们可以使用loadEventFired
方法定义要运行应用程序的步骤,以执行代码来复制我们的用户旅程。在这个例子中,我们只是获取第一段的内容:
<code class="language-javascript">const chromeLauncher = require('chrome-launcher'); const CDP = require('chrome-remote-interface'); (async function() { async function launchChrome() { return await chromeLauncher.launch({ chromeFlags: [ '--disable-gpu', '--headless' ] }); } const chrome = await launchChrome(); const protocol = await CDP({ port: chrome.port }); // 所有后续代码片段都位于此处 })();</code>
如果您使用node index.js
运行脚本,您应该会看到类似于以下输出的结果:
更进一步——抓取截图
这很好,但我们可以同样轻松地将任何代码替换为script1
值,以使用查询选择器点击链接、填写表单字段和运行一系列交互。每个步骤都可以存储在JSON配置文件中,并加载到您的Node.js脚本中以顺序执行。可以使用Mocha等测试平台验证这些脚本的结果,允许您交叉引用捕获的值是否满足UI/UX要求。
作为测试脚本的补充,您可能希望在导航网站时捕获页面的截图。幸运的是,提供的域具有一个captureScreenshot
函数,它可以准确地做到这一点。
<code class="language-javascript">const { DOM, Page, Emulation, Runtime } = protocol; await Promise.all([Page.enable(), Runtime.enable(), DOM.enable()]);</code>
fromSurface
标志是另一个在撰写本文时需要进行跨平台支持的标志,在未来的迭代中可能不需要。
使用node index.js
运行脚本,您应该会看到类似于以下输出的结果:
结论
如果您正在编写自动化脚本,您现在应该开始使用Chrome的无头浏览器。虽然它仍然没有完全集成到Selenium等工具中,但模拟Chrome渲染引擎的好处不容低估。这是以完全自动化方式重现用户体验的最佳方式。
我将为您提供一些进一步阅读的资料:
请在下面的评论中告诉我您使用无头Chrome的经验。
(此处省略了FAQs部分,因为与原文重复,且篇幅过长。可以根据需要选择性保留或重新组织FAQs内容。)
以上是快速提示:从node.js开始使用无头铬的详细内容。更多信息请关注PHP中文网其他相关文章!