ReactJS 与许多其他 Javascript 库/框架一样,使用客户端代码 (Javascript) 来呈现最终的 HTML。这意味着当您、Jaunt 或您的浏览器从服务器获取 HTML 源代码时,它尚未包含用户将看到的最终代码。浏览器需要运行页面中包含的 Javascript 程序,以生成您希望抓取的最终内容。
我最喜欢的这类工作的工具是CasperJS
它(或者更确切地说是 CasperJS 使用的 PhantomJS 工具)是一个无头浏览器,这意味着它是一个 Webkit 版本(如 Chrome 或 Safari),已经去除了所有 GUI(窗口、按钮、菜单)。剩下的是一个工具您可以从终端或 Java 程序运行。它不会在屏幕上显示任何窗口,但会获取您要求的网页;运行它们包含的任何 Javascript;然后响应您的命令,例如“单击此链接”、“给我该文本”、“截取屏幕截图”等。
让我们从一个简单的ReactJS 示例开始:
我们想抓取“Hello John”文本,但是如果您查看纯 HTML 源代码(Ctrl+U或Alt+ Ctrl+ U),您将看不到它。另一方面,如果您在浏览器中打开控制台并使用以下选择器,您将获得文本:
> document.querySelector('#helloExample .playgroundPreview').textContent
"Hello John"
这是一个简单的 CasperJS 脚本来做同样的事情:
var casper = require("casper").create();
casper.start("http://facebook.github.io/react/index.html", function() {
this.echo(this.fetchText("#helloExample .playgroundPreview"));
});
casper.run();
您可以将其另存为hello.js
并casperjs hello.js
从终端执行,或使用等效的 Java 代码Runtime.getRuntime().exec(...)
这是一个更好的脚本,它避免加载图像和第三方资源(例如 Facebook 按钮、Twitter 按钮、Google Analytics 等),从而将加载时间减少了一半。它还添加了一个waitForSelector
步骤,因此我们不会冒险尝试在 ReactJS 有机会创建文本之前获取文本。
var casper = require("casper").create({
pageSettings: {
loadImages: false
}
});
casper.on('resource.requested', function(requestData, request) {
if (requestData.url.indexOf("http://facebook.github.io/") != 0) {
request.abort();
}
});
casper.start("http://facebook.github.io/react/index.html", function() {
this.waitForSelector("#helloExample .playgroundPreview", function() {
this.echo(this.fetchText("#helloExample .playgroundPreview"));
});
});
casper.run();
如何安装 CasperJS
我在使用旧版本的 PhantomJS 和 CasperJS 抓取 ReactJS 和其他现代 Javascript 页面时遇到了一些麻烦,因此我建议从 GitHub 安装 PhantomJS 2.0 和最新的 CasperJS。
对于 PhantomJS,您可以下载官方 2.0 包。
对于 CasperJS,由于它是一个 Python 脚本,您应该能够从 GitHub 中查看最新提交并链接bin/casperjs
到您的 PATH。这是适用于 Linux 或 Mac OS X 的脚本:
> git clone git://github.com/n1k0/casperjs.git
> cd casperjs
> ln -sf `pwd`/bin/casperjs /usr/local/bin/casperjs
您可能还需要注释掉该行打印Warning PhantomJS v2.0 ...
您的bin/bootstrap.js
文件。