【翻译】怎么在 macOS 上安装和使用 Headless Chrome
这个教程会用详细的步骤教你在 macOS 上怎么去获取和运行 Headless Chrome 和怎么去使用 Chrome 团队提供的示例代码。
Headless Chrome 解决了什么样的问题?
什么版本的 Chrome 支持 Headless ?
brew install Caskroom/versions/google-chrome-canary
我怎么找到 Headless Chrome?
很多例子在使用 Headless Chrome 时,只用了一个简单的 chrome
命令。这可以在 Linux 下很好的工作,但是在 macOS 上不行,因为命令没有被安装在你的 PATH
中。
所以你需要找到 Chrome 的路径,让我们启动我们的终端去找 Chrome Canary 安装在我们系统的哪里。
sudo find / -type d -name "*Chrome Canary.app"
你可能会得到一些权限错误,但是你还是会得到一个路径长得像这样:
/Applications/Google Chrome Canary.app
我们找到了 Chrome Canary 的路径,我们可以使用它启动 Chrome 并使它运行在 Headless 模式。
我怎么启动 Headless Chrome?
我们得到 Chrome Canary 的路径以后,我们需要用一个命令启动 Chrome 作为一个 Headless 服务。
/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --headless --remote-debugging-port=9222 --disable-gpu https://chromium.org
我怎么使用 Headless Chrome 抓取数据?
我将要使用 Node.js 去连接我们运行中的 Chrome Canary 实例。你需要确保你已经安装了 Node,才可以继续这个步骤。
让我们生成一个普通的 Node 项目,只有一个依赖那就是 Chrome Remote Interface 包,它可以帮助我们与 Chrome 沟通。然后我们创建一个空白的 index.js
文件。
mkdir my-headless-chrome && cd my-headless-chrome
npm init --yes
npm install --save chrome-remote-interface
touch index.js
const CDP = require("chrome-remote-interface");
CDP(client => {
// extract domains
const { Network, Page } = client;
// setup handlers
Network.requestWillBeSent(params => {
console.log(params.request.url);
});
Page.loadEventFired(() => {
client.close();
});
// enable events then start!
Promise.all([Network.enable(), Page.enable()])
.then(() => {
return Page.navigate({ url: });
})
.catch(err => {
console.error(err);
client.close();
});
}).on("error", err => {
// cannot connect to the remote endpoint
console.error(err);
});
最后启动我们的 Node 应用。
node index.js
我们可以看到 Chrome 发出的所有的网络请求,然而并没有一个实际的浏览器窗口。
const CDP = require("chrome-remote-interface");
CDP(chrome => {
chrome.Page
.enable()
.then(() => {
return chrome.Page.navigate({ url: });
})
.then(() => {
chrome.DOM.getDocument((error, params) => {
if (error) {
console.error(params);
return;
}
const options = {
nodeId: params.root.nodeId,
selector: "img"
};
chrome.DOM.querySelectorAll(options, (error, params) => {
if (error) {
console.error(params);
return;
}
params.nodeIds.forEach(nodeId => {
const options = {
nodeId: nodeId
};
chrome.DOM.getAttributes(options, (error, params) => {
if (error) {
console.error(params);
return;
}
console.log(params.attributes);
});
});
});
});
});
}).on("error", err => {
console.error(err);
});
我们可以得到以下的数据结构展现了页面上标签包含所有图片的链接。
[ 'src',
'alt',
'',
'width',
'360',
'class',
'd-block width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block width-fit mx-auto mb-4' ]
[ 'src',
'alt',
'',
'class',
'd-block integrations-collage-img width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block integrations-collage-img width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block integrations-collage-img width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block integrations-collage-img width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block integrations-collage-img width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block integrations-collage-img width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block integrations-collage-img width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block integrations-collage-img width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block integrations-collage-img width-fit mx-auto' ]
[ 'src',
'alt',
'',
'class',
'd-block integrations-collage-img width-fit mx-auto' ]
[ 'src',
'alt',
'Airbnb',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'SAP',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'IBM',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'Google',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'PayPal',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'Bloomberg',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'Spotify',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'Swift',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'Rails',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'Node',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'Nasa',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
[ 'src',
'alt',
'Walmart',
'class',
'logo-img px-2 px-sm-4 px-md-5 px-lg-0' ]
让我们愉快的抓取吧!