作者: Jogis
原文链接: https://github.com/yesvods/Blog/issues/10
也许最近已经听说 Chrome59 将支持headless
模式,PhantomJS
核心开发者Vitaly表示自己将会失业了。
3 年前,无头浏览器PhantomJS
已经如火如荼出现了,紧跟着NightmareJS
也成为一名巨星。无头浏览器带来巨大便利性:页面爬虫、自动化测试、 WebAutomation...
用过 PhantomJS 的都知道,它的环境是运行在一个封闭的沙盒里面,在环境内外完全不可通信,包括 API 、变量、全局方法调用等。一个之前写的微信页面爬虫,实现内外通信的方式极其 Hack ,为了达到目的,不择手段,令人发指,看过的哥们都会蛋疼。
So, 很自然的, Chrome59 版支持的特性,全部可以利用,简直不要太爽:
为了点亮技能树,我们需要以下配置:
大致来说,有那么个过程:
有各种脚本启动方式,本次我们使用 termial 参数方式来打开:
$ /Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --headless --remote-debugging-port=9222
在 Dock 中,一个黄色的东西就会被启动,但是他不会跳出来。
依旧有各种方式,我们先安装一个工具帮助我们来对黄色浏览器做点事情:
$ tnpm i -S chrome-remote-interface
Pretty Simple ,写一个 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: "https://github.com" });
})
.catch(err => {
console.error(err);
client.close();
});
}).on("error", err => {
// cannot connect to the remote endpoint
console.error(err);
});
AND run it :
$ node index.js
结果会展示一堆 url :
https://github.com/
https://assets-cdn.github.com/assets/frameworks-12d63ce1986bd7fdb5a3f4d944c920cfb75982c70bc7f75672f75dc7b0a5d7c3.css
https://assets-cdn.github.com/assets/github-2826bd4c6eb7572d3a3e9774d7efe010d8de09ea7e2a559fa4019baeacf43f83.css
https://assets-cdn.github.com/assets/site-f4fa6ace91e5f0fabb47e8405e5ecf6a9815949cd3958338f6578e626cd443d7.css
https://assets-cdn.github.com/images/modules/site/home-illo-conversation.svg
https://assets-cdn.github.com/images/modules/site/home-illo-chaos.svg
https://assets-cdn.github.com/images/modules/site/home-illo-business.svg
https://assets-cdn.github.com/images/modules/site/integrators/slackhq.png
https://assets-cdn.github.com/images/modules/site/integrators/zenhubio.png
https://assets-cdn.github.com/assets/compat-8a4318ffea09a0cdb8214b76cf2926b9f6a0ced318a317bed419db19214c690d.js
https://assets-cdn.github.com/static/fonts/roboto/roboto-medium.woff
...
这次轮到演示一下如何操控 DOM :
const CDP = require("chrome-remote-interface");
CDP(chrome => {
chrome.Page
.enable()
.then(() => {
return chrome.Page.navigate({ url: "https://github.com" });
})
.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',
'https://assets-cdn.github.com/images/modules/site/home-illo-conversation.svg',
'alt',
'',
'width',
'360',
'class',
'd-block width-fit mx-auto' ]
[ 'src',
'https://assets-cdn.github.com/images/modules/site/home-illo-chaos.svg',
'alt',
'',
'class',
'd-block width-fit mx-auto' ]
[ 'src',
'https://assets-cdn.github.com/images/modules/site/home-illo-business.svg',
'alt',
'',
'class',
'd-block width-fit mx-auto mb-4' ]
...
]
chrome-remote-interface 提供一套完整的 API 用于利用全量 Chrome 特性,更多使用方法参考: https://github.com/cyrus-and/chrome-remote-interface
Chrome Headless 特性,不仅仅革新了原有格局,而且提高开发效率,降低使用门槛,对于经常使用爬虫、自动化测试前端童鞋来说简直是巨大福音,对于新童鞋来说也是一个新潮的玩具。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.