Headless Chrome入门

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Headless Chrome入门相关的知识,希望对你有一定的参考价值。

原文地址:Getting Started with Headless Chrome  By Eric Bidelman  Engineer @ Google working on web tooling: Headless Chrome, Puppeteer, Lighthouse

Headless Chrome在Chrome59中发布,用于在headless环境中运行Chrome浏览器,也就是在非Chrome环境中运行Chrome。它将Chromium和Blink渲染引擎提供的所有现代Web平台功能引入命令行。

它有什么用处呢?

headless浏览器是自动测试和服务器环境的绝佳工具,您不需要可见的UI shell。例如,针对真实的网页进行测试,创建网页的PDF,或者只是检查浏览器如何呈现URL。

0. 开始

最简单的开始使用headless模式的方法是从命令行打开Chrome。如果你已经安装了Chrome59+的版本,可以使用 --headless 标签:

chrome   --headless \                   # 在headless模式运行Chrome
  --disable-gpu \                # 在Windows上运行时需要--remote-debugging-port=9222   https://www.chromestatus.com   # 打开URL. 默认为about:blank

注意:若在Windows中运行,则需要在命令行添加 --disable-gpu 。

 chrome 命令需要指向Chrome的安装路径。(即在Chrome的安装路径下运行)

1. 命令行功能

在某些情况下,您可能不需要以编程方式编写Headless Chrome脚本。下面是一些有用的命令行标志来执行常见任务。

1.1 打印DOM --dump-dom 

将 document.body.innerhtml 在stdout打印出来:

chrome --headless --disable-gpu --dump-dom https://www.chromestatus.com/

1.2 创建PDF --print-to-pdf :

chrome --headless --disable-gpu --print-to-pdf https://www.chromestatus.com/

1.3 截屏 --screenshot 

chrome --headless --disable-gpu --screenshot https://www.chromestatus.com/

# 标准屏幕大小
chrome --headless --disable-gpu --screenshot --window-size=1280,1696 https://www.chromestatus.com/

# Nexus 5x
chrome --headless --disable-gpu --screenshot --window-size=412,732 https://www.chromestatus.com/

运行 --screenshot将会在当前运行目录下生成一个 screenshot.png 文件。若想给整个页面的截图,那么会比较复杂。来自 David Schnurr 的一篇很棒的博文介绍了这一内容。请查看 使用 headless Chrome 作为自动截屏工具

1.4 REPL模式(read-eval-print loop) --repl 

在REPL模式运行Headless,该模式允许通过命令行在浏览器中评估JS表达式:

$ chrome --headless --disable-gpu --repl --crash-dumps-dir=./tmp https://www.chromestatus.com/
[0608/112805.245285:INFO:headless_shell.cc(278)] Type a javascript expression to evaluate or "quit" to exit.
>>> location.href
{"result":{"type":"string","value":"https://www.chromestatus.com/features"}}
>>> quit
$

注意:使用repl模式时需要添加 --crash-dumps-dir 命令。

2. 在没有浏览器界面情况下调试Chrome

当使用 --remote-debugging-port=9222 运行Chrome时,会启用DevTools协议的实例。该协议用于与Chrome通信并且驱动headless浏览器实例。除此之外,它还是一个类似于 Sublime, VS Code, 和Node的工具,可用于远程调试一个应用。

由于没有浏览器UI来查看页面,因此需要在另一个浏览器中导航到http:// localhost:9222以检查一切是否正常。这将看到一个可查看页面的列表,可以在其中单击并查看Headless正在呈现的内容:

技术分享图片

DevTools远程调试界面

在这里,你可以使用熟悉的DecTools功能来查看、调试、修改页面。若以编程方式(programmatically)使用Headless,该页面的功能更强大,可以用于查看所有的DecTools协议的命令,并与浏览器进行通信。

3. 使用编程模式(Node)

3.1 Puppeteer

Puppeteer 由Chrome团队开发的Node库。它提供了控制headless Chrome的高阶API。类似于 Phantom 和 NightmareJS这样的自动测试库,但它只用于最新版本的Chrome。

除此之外,Puppeteer还可用于截屏,创建PDF,页面导航,以及获取有关这些页面的信息。如果需要快速进行浏览器的自动化测试,建议使用该库。它隐藏了DevTools协议的复杂性,并负责启动Chrome的调试实例等冗余任务。

安装:

npm i --save puppeteer

例子-打印用户代理信息:

const puppeteer = require(puppeteer);

(async() => {
  const browser = await puppeteer.launch();
  console.log(await browser.version());
  await browser.close();
})();

例子-截屏

const puppeteer = require(puppeteer);

(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(https://www.chromestatus.com, {waitUntil: networkidle2});
await page.pdf({path: page.pdf, format: A4});

await browser.close();
})();

查看 Puppeteer‘s 文档 学习Puppeteer的更多用法。

3.2 CRI库

相对于Puppeteer‘s API来说,chrome-remote-interface 是一个低阶的库,推荐使用它更接近底层地直接使用DevTools协议。

打开Chrome

chrome-remote-interface不能打开Chrome,因此需要自己打开Chrome。

在CLI部分,我们使用--headless --remote-debugging-port = 9222手动打开Chrome。但是,要实现完全自动化测试,您可能希望从应用程序中生成Chrome。

使用 child——process 的一种方式:

const execFile = require(child_process).execFile;

function launchHeadlessChrome(url, callback) {
  // Assuming MacOSx.
  const CHROME = /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome;
  execFile(CHROME, [--headless, --disable-gpu, --remote-debugging-port=9222, url], callback);
}

launchHeadlessChrome(https://www.chromestatus.com, (err, stdout, stderr) => {
  ...
});

但是如果你想要一个适用于多个平台的可移植解决方案,那么事情会变得棘手。看看Chrome的硬编码路径吧:(

使用ChromeLaucher

Lighthouse 是测试web应用质量绝佳工具。用于启动Chrome的强大的模块就是在Lighthouse中开发的,现在可以单独使用。  chrome-launcher NPM module 可以找到Chrome的安装路径,设置调试实例,打开浏览器,并且当程序运行完成时关掉它。最棒的是,由于Node,它可以跨平台工作!

默认情况下,chrome-launcher会尝试启动Chrome Canary(如果已安装),但可以更改它以手动选择要使用的Chrome。要使用它,首先从npm安装:

npm i --save chrome-launcher

例子-使用 chrome-launcher 启动Headless模式

const chromeLauncher = require(chrome-launcher);

// 可选: 设置launcher的日志记录级别以查看其输出
// 安装:: npm i --save lighthouse-logger
// const log = require(‘lighthouse-logger‘);
// log.setLevel(‘info‘);

/**
 * 启动Chrome的调试实例
 * @param {boolean=} headless True (default) 启动headless模式的Chrome.
 *     False 启动Chrome的完成版本.
 * @return {Promise<ChromeLauncher>}
 */
function launchChrome(headless=true) {
  return chromeLauncher.launch({
    // port: 9222, // Uncomment to force a specific port of your choice.
    chromeFlags: [
      --window-size=412,732,
      --disable-gpu,
      headless ? --headless : ‘‘
    ]
  });
}

launchChrome().then(chrome => {
  console.log(`Chrome debuggable on port: ${chrome.port}`);
  ...
  // chrome.kill();
});

运行此脚本并没有太大作用,但在任务管理器中应该可以看到Chrome实例已启动,内容为 about:blank 。但是没有浏览器界面。因为是headless模式。

要控制浏览器,我们需要DevTools协议!

检索有关页面的信息

安装:

npm i --save chrome-remote-interface

 例子-打印用户代理

const CDP = require(chrome-remote-interface);

...

launchChrome().then(async chrome => {
  const version = await CDP.Version({port: chrome.port});
  console.log(version[User-Agent]);
});

结果类似于: HeadlessChrome/60.0.3082.0 

例子-检查网站是否有应用列表

const CDP = require(chrome-remote-interface);

...

(async function() {

const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});

// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page} = protocol;
await Page.enable();

Page.navigate({url: https://www.chromestatus.com/});

// Wait for window.onload before doing stuff.
Page.loadEventFired(async () => {
  const manifest = await Page.getAppManifest();

  if (manifest.url) {
    console.log(Manifest:  + manifest.url);
    console.log(manifest.data);
  } else {
    console.log(Site has no app manifest);
  }

  protocol.close();
  chrome.kill(); // Kill Chrome.
});

})();

例子-使用DOM API提取页面的<title>

const CDP = require(chrome-remote-interface);

...

(async function() {

const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});

// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page, Runtime} = protocol;
await Promise.all([Page.enable(), Runtime.enable()]);

Page.navigate({url: https://www.chromestatus.com/});

// Wait for window.onload before doing stuff.
Page.loadEventFired(async () => {
  const js = "document.querySelector(‘title‘).textContent";
  // Evaluate the JS expression in the page.
  const result = await Runtime.evaluate({expression: js});

  console.log(Title of page:  + result.result.value);

  protocol.close();
  chrome.kill(); // Kill Chrome.
});

})();

4. 使用Selenium,W??ebDriver和ChromeDriver

现在,Selenium打开了一个完整地Chrome的实例,也就是说,换句话说,它是一种自动化解决方案,但并非完全headless。但是,Selenium可以通过一些配置来运行headless Chrome。我建议使用headless Chrome运行Selenium,若你还是想要如何自己设置的完整说明,我已经在下面的一些例子中展示了如何让你放弃。

使用ChromeDriver

ChromeDriver 2.32使用了Chrome61,并且在headless Chrome运行的更好。

安装:

npm i --save-dev selenium-webdriver chromedriver

例子

const fs = require(fs);
const webdriver = require(selenium-webdriver);
const chromedriver = require(chromedriver);

const chromeCapabilities = webdriver.Capabilities.chrome();
chromeCapabilities.set(chromeOptions, {args: [--headless]});

const driver = new webdriver.Builder()
  .forBrowser(chrome)
  .withCapabilities(chromeCapabilities)
  .build();

// Navigate to google.com, enter a search.
driver.get(https://www.google.com/);
driver.findElement({name: q}).sendKeys(webdriver);
driver.findElement({name: btnG}).click();
driver.wait(webdriver.until.titleIs(webdriver - Google Search), 1000);

// Take screenshot of results page. Save to disk.
driver.takeScreenshot().then(base64png => {
  fs.writeFileSync(screenshot.png, new Buffer(base64png, base64));
});

driver.quit();

使用WebDriverIO

WebDriverIO 是Selenium WebDriver之上的更高阶的API。

安装:

npm i --save-dev webdriverio chromedriver

例子-chromestatus.com上的CSS filter功能

const webdriverio = require(webdriverio);
const chromedriver = require(chromedriver);

const PORT = 9515;

chromedriver.start([
  --url-base=wd/hub,
  `--port=${PORT}`,
  --verbose
]);

(async () => {

const opts = {
  port: PORT,
  desiredCapabilities: {
    browserName: chrome,
    chromeOptions: {args: [--headless]}
  }
};

const browser = webdriverio.remote(opts).init();

await browser.url(https://www.chromestatus.com/features);

const title = await browser.getTitle();
console.log(`Title: ${title}`);

await browser.waitForText(.num-features, 3000);
let numFeatures = await browser.getText(.num-features);
console.log(`Chrome has ${numFeatures} total features`);

await browser.setValue(input[type="search"], CSS);
console.log(Filtering features...);
await browser.pause(1000);

numFeatures = await browser.getText(.num-features);
console.log(`Chrome has ${numFeatures} CSS features`);

const buffer = await browser.saveScreenshot(screenshot.png);
console.log(Saved screenshot...);

chromedriver.stop();
browser.end();

})();

5. 更多资源

以下是一些有用的资源,可帮助您入门:

文档:

工具:

演示:

6. FAQ

6.1 是否需要 --disable-gpu 命令?

仅Windows平台需要。其他平台不需要。--disable-gpu命令是一个临时解决一些错误的方案。在将来的Chrome版本中,不再需要此命令。有关更多信息,请参阅 crbug.com/737678

6.2 是否需要 Xvfb

不需要。Headless Chrome不使用窗口,因此不再需要像Xvfb这样的显示服务器。没有它,也可以愉快地运行自动化测试。

什么是Xvfb?Xvfb是一种用于类Unix系统的内存显示服务器,它使您能够运行图形应用程序(如Chrome)而无需附加物理显示设备。许多人使用Xvfb运行早期版本的Chrome进行“headless”测试。

6.3 如何创建运行Headless Chrome的Docker容器?

看看lighthouse-ci。它有一个示例 Dockerfile ,它使用node:8-slim作为基本映像,在App Engine Flex上安装+ 运行Lighthouse 

6.4 Headless Chrome与PhantomJS有什么关系?

Headless Chrome与PhantomJS等工具类似。两者都可用于headless环境中的自动化测试。两者之间的主要区别在于Phantom使用较旧版本的WebKit作为其渲染引擎,而Headless Chrome使用最新版本的Blink。

目前,Phantom还提供了比DevTools 协议更高级别的API。

6.5 在哪里提交bugs?

对于Headless Chrome的bugs,请在crbug.com上提交。

对于DevTools协议中的错误,请将它们发送到github.com/ChromeDevTools/devtools-protocol

tech & looking ahead to the platform‘s future.

Getting Started with Headless Chrome

技术分享图片

TL;DR

Headless Chrome is shipping in Chrome 59. It‘s a way to run the Chrome browser in a headless environment. Essentially, running Chrome without chrome! It brings all modern web platform features provided by Chromium and the Blink rendering engine to the command line.

Why is that useful?

A headless browser is a great tool for automated testing and server environments where you don‘t need a visible UI shell. For example, you may want to run some tests against a real web page, create a PDF of it, or just inspect how the browser renders an URL.

Note: Headless mode has been available on Mac and Linux since Chrome 59Windows support came in Chrome 60.

Starting Headless (CLI)

The easiest way to get started with headless mode is to open the Chrome binary from the command line. If you‘ve got Chrome 59+ installed, start Chrome with the --headless flag:

 
chrome \
 
--headless \                   # Runs Chrome in headless mode.
 
--disable-gpu \                # Temporarily needed if running on Windows.
 
--remote-debugging-port=9222\
  https
://www.chromestatus.com   # URL to open. Defaults to about:blank.
Note: Right now, you‘ll also want to include the --disable-gpu flag if you‘re running on Windows. See crbug.com/737678.

chrome should point to your installation of Chrome. The exact location will vary from platform to platform. Since I‘m on Mac, I created convenient aliases for each version of Chrome that I have installed.

If you‘re on the stable channel of Chrome and cannot get the Beta, I recommend using chrome-canary:

 
alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
alias chrome-canary="/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary"
alias chromium="/Applications/Chromium.app/Contents/MacOS/Chromium"

Download Chrome Canary here.

Command line features

In some cases, you may not need to programmatically script Headless Chrome. There are some useful command line flags to perform common tasks.

Printing the DOM

The --dump-dom flag prints document.body.innerHTML to stdout:

 
chrome --headless --disable-gpu --dump-dom https://www.chromestatus.com/

Create a PDF

The --print-to-pdf flag creates a PDF of the page:

 
chrome --headless --disable-gpu --print-to-pdf https://www.chromestatus.com/

Taking screenshots

To capture a screenshot of a page, use the --screenshot flag:

 
chrome --headless --disable-gpu --screenshot https://www.chromestatus.com/

# Size of a standard letterhead.
chrome
--headless --disable-gpu --screenshot --window-size=1280,1696 https://www.chromestatus.com/

# Nexus 5x
chrome
--headless --disable-gpu --screenshot --window-size=412,732 https://www.chromestatus.com/

Running with --screenshot will produce a file named screenshot.png in the current working directory. If you‘re looking for full page screenshots, things are a tad more involved. There‘s a great blog post from David Schnurr that has you covered. Check out Using headless Chrome as an automated screenshot tool .

REPL mode (read-eval-print loop)

The --repl flag runs Headless in a mode where you can evaluate JS expressions in the browser, right from the command line:

 
$ chrome --headless --disable-gpu --repl --crash-dumps-dir=./tmp https://www.chromestatus.com/
[0608/112805.245285:INFO:headless_shell.cc(278)]Type a Javascript expression to evaluate or"quit" to exit.
>>> location.href
{"result":{"type":"string","value":"https://www.chromestatus.com/features"}}
>>> quit
$
Note: the addition of the --crash-dumps-dir flag when using repl mode.

Debugging Chrome without a browser UI?

When you run Chrome with --remote-debugging-port=9222, it starts an instance with the DevTools protocol enabled. The protocol is used to communicate with Chrome and drive the headless browser instance. It‘s also what tools like Sublime, VS Code, and Node use for remote debugging an application. #synergy

Since you don‘t have browser UI to see the page, navigate to http://localhost:9222 in another browser to check that everything is working. You‘ll see a list of inspectable pages where you can click through and see what Headless is rendering:

技术分享图片DevTools remote debugging UI

From here, you can use the familiar DevTools features to inspect, debug, and tweak the page as you normally would. If you‘re using Headless programmatically, this page is also a powerful debugging tool for seeing all the raw DevTools protocol commands going across the wire, communicating with the browser.

Using programmatically (Node)

Puppeteer

Puppeteer is a Node library developed by the Chrome team. It provides a high-level API to control headless (or full) Chrome. It‘s similar to other automated testing libraries like Phantom and NightmareJS, but it only works with the latest versions of Chrome.

Among other things, Puppeteer can be used to easily take screenshots, create PDFs, navigate pages, and fetch information about those pages. I recommend the library if you want to quickly automate browser testing. It hides away the complexities of the DevTools protocol and takes care of redundant tasks like launching a debug instance of Chrome.

Install it:

 
npm i --save puppeteer

Example - print the user agent

 
const puppeteer =require(‘puppeteer‘);

(async()=>{
 
const browser = await puppeteer.launch();
  console
.log(await browser.version());
  await browser
.close();
})();

Example - taking a screenshot of the page

 
const puppeteer =require(‘puppeteer‘);

(async()=>{
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page
.goto(‘https://www.chromestatus.com‘,{waitUntil:‘networkidle2‘});
await page
.pdf({path:‘page.pdf‘, format:‘A4‘});

await browser
.close();
})();

Check out Puppeteer‘s documentation to learn more about the full API.

The CRI library

chrome-remote-interface is a lower-level library than Puppeteer‘s API. I recommend it if you want to be close to the metal and use the DevTools protocol directly.

Launching Chrome

chrome-remote-interface doesn‘t launch Chrome for you, so you‘ll have to take care of that yourself.

In the CLI section, we started Chrome manually using --headless --remote-debugging-port=9222. However, to fully automate tests, you‘ll probably want to spawn Chrome from your application.

One way is to use child_process:

 
const execFile =require(‘child_process‘).execFile;

function launchHeadlessChrome(url, callback){
 
// Assuming MacOSx.
 
const CHROME =‘/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome‘;
  execFile
(CHROME,[‘--headless‘,‘--disable-gpu‘,‘--remote-debugging-port=9222‘, url], callback);
}

launchHeadlessChrome
(‘https://www.chromestatus.com‘,(err, stdout, stderr)=>{
 
...
});

But things get tricky if you want a portable solution that works across multiple platforms. Just look at that hard-coded path to Chrome :(

Using ChromeLauncher

Lighthouse is a marvelous tool for testing the quality of your web apps. A robust module for launching Chrome was developed within Lighthouse and is now extracted for standalone use. The chrome-launcher NPM modulewill find where Chrome is installed, set up a debug instance, launch the browser, and kill it when your program is done. Best part is that it works cross-platform thanks to Node!

By default, chrome-launcher will try to launch Chrome Canary (if it‘s installed), but you can change that to manually select which Chrome to use. To use it, first install from npm:

 
npm i --save chrome-launcher

Example - using chrome-launcher to launch Headless

 
const chromeLauncher =require(‘chrome-launcher‘);

// Optional: set logging level of launcher to see its output.
// Install it using: npm i --save lighthouse-logger
// const log = require(‘lighthouse-logger‘);
// log.setLevel(‘info‘);

/**
 * Launches a debugging instance of Chrome.
 * @param {boolean=} headless True (default) launches Chrome in headless mode.
 *     False launches a full version of Chrome.
 * @return {Promise<ChromeLauncher>}
 */

function launchChrome(headless=true){
 
return chromeLauncher.launch({
   
// port: 9222, // Uncomment to force a specific port of your choice.
    chromeFlags
:[
     
‘--window-size=412,732‘,
     
‘--disable-gpu‘,
      headless
?‘--headless‘:‘‘
   
]
 
});
}

launchChrome
().then(chrome =>{
  console
.log(`Chrome debuggable on port: ${chrome.port}`);
 
...
 
// chrome.kill();
});

Running this script doesn‘t do much, but you should see an instance of Chrome fire up in the task manager that loaded about:blank. Remember, there won‘t be any browser UI. We‘re headless.

To control the browser, we need the DevTools protocol!

Retrieving information about the page

Warning: The DevTools protocol can do a ton of interesting stuff, but it can be a bit daunting at first. I recommend spending a bit of time browsing the DevTools Protocol Viewer, first. Then, move on to thechrome-remote-interface API docs to see how it wraps the raw protocol.

Let‘s install the library:

 
npm i --save chrome-remote-interface
Examples

Example - print the user agent

 
const CDP =require(‘chrome-remote-interface‘);

...

launchChrome
().then(async chrome =>{
 
const version = await CDP.Version({port: chrome.port});
  console
.log(version[‘User-Agent‘]);
});

Results in something like: HeadlessChrome/60.0.3082.0

Example - check if the site has a web app manifest

 
const CDP =require(‘chrome-remote-interface‘);

...

(async function(){

const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});

// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const{Page}= protocol;
await
Page.enable();

Page.navigate({url:‘https://www.chromestatus.com/‘});

// Wait for window.onload before doing stuff.
Page.loadEventFired(async ()=>{
 
const manifest = await Page.getAppManifest();

 
if(manifest.url){
    console
.log(‘Manifest: ‘+ manifest.url);
    console
.log(manifest.data);
 
}else{
    console
.log(‘Site has no app manifest‘);
 
}

  protocol
.close();
  chrome
.kill();// Kill Chrome.
});

})();

Example - extract the <title> of the page using DOM APIs.

 
const CDP =require(‘chrome-remote-interface‘);

...

(async function(){

const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});

// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const{Page,Runtime}= protocol;
await
Promise.all([Page.enable(),Runtime.enable()]);

Page.navigate({url:‘https://www.chromestatus.com/‘});

// Wait for window.onload before doing stuff.
Page.loadEventFired(async ()=>{
 
const js ="document.querySelector(‘title‘).textContent";
 
// Evaluate the JS expression in the page.
 
const result = await Runtime.evaluate({expression: js});

  console
.log(‘Title of page: ‘+ result.result.value);

  protocol
.close();
  chrome
.kill();// Kill Chrome.
});

})();

Using Selenium, WebDriver, and ChromeDriver

Right now, Selenium opens a full instance of Chrome. In other words, it‘s an automated solution but not completely headless. However, Selenium can be configured to run headless Chrome with a little work. I recommend Running Selenium with Headless Chrome if you want the full instructions on how to set things up yourself, but I‘ve dropped in some examples below to get you started.

Using ChromeDriver

ChromeDriver 2.32 uses Chrome 61 and works well with headless Chrome.

Install:

 
npm i --save-dev selenium-webdriver chromedriver

Example:

 
const fs =require(‘fs‘);
const webdriver =require(‘selenium-webdriver‘);
const chromedriver =require(‘chromedriver‘);

const chromeCapabilities = webdriver.Capabilities.chrome();
chromeCapabilities
.set(‘chromeOptions‘,{args:[‘--headless‘]});

const driver =new webdriver.Builder()
 
.forBrowser(‘chrome‘)
 
.withCapabilities(chromeCapabilities)
 
.build();

// Navigate to google.com, enter a search.
driver
.get(‘https://www.google.com/‘);
driver
.findElement({name:‘q‘}).sendKeys(‘webdriver‘);
driver
.findElement({name:‘btnG‘}).click();
driver
.wait(webdriver.until.titleIs(‘webdriver - Google Search‘),1000);

// Take screenshot of results page. Save to disk.
driver
.takeScreenshot().then(base64png =>{
  fs
.writeFileSync(‘screenshot.png‘,newBuffer(base64png,‘base64‘));
});

driver
.quit();

Using WebDriverIO

WebDriverIO is a higher level API on top of Selenium WebDriver.

Install:

 
npm i --save-dev webdriverio chromedriver

Example: filter CSS features on chromestatus.com

 
const webdriverio =require(‘webdriverio‘);
const chromedriver =require(‘chromedriver‘);

const PORT =9515;

chromedriver
.start([
 
‘--url-base=wd/hub‘,
 
`--port=${PORT}`,
 
‘--verbose‘
]);

(async ()=>{

const opts ={
  port
: PORT,
  desiredCapabilities
:{
    browserName
:‘chrome‘,
    chromeOptions
:{args:[‘--headless‘]}
 
}
};

const browser = webdriverio.remote(opts).init();

await browser
.url(‘https://www.chromestatus.com/features‘);

const title = await browser.getTitle();
console
.log(`Title: ${title}`);

await browser
.waitForText(‘.num-features‘,3000);
let numFeatures
= await browser.getText(‘.num-features‘);
console
.log(`Chrome has ${numFeatures} total features`);

await browser
.setValue(‘input[type="search"]‘,‘CSS‘);
console
.log(‘Filtering features...‘);
await browser
.pause(1000);

numFeatures
= await browser.getText(‘.num-features‘);
console
.log(`Chrome has ${numFeatures} CSS features`);

const buffer = await browser.saveScreenshot(‘screenshot.png‘);
console
.log(‘Saved screenshot...‘);

chromedriver
.stop();
browser
.end();

})();

Further resources

Here are some useful resources to get you started:

Docs

Tools

Demos

  • "The Headless Web" - Paul Kinlan‘s great blog post on using Headless with api.ai.

FAQ

































































































































































































































以上是关于Headless Chrome入门的主要内容,如果未能解决你的问题,请参考以下文章

Selenium – Headless Chrome 无效语法

基于headless chrome的游戏资源下载实现 (初版)

反爬虫——使用chrome headless时一些需要注意的细节

chrome headless Manual 模式渲染网页

使用 `google-chrome --headless` 时如何设置浏览器窗口大小?

Python 爬虫杂记 - Chrome Headless