【编者的话】Prerender 服务可以为网络爬虫提供预先渲染的动态页面内容,解决了用 JavaScript 框架构建的 Web 站点不支持爬虫抓取的问题。本文详细描述了一种解决方案,尤为是提供了集成 Prerender 服务的 Docker 容器镜像。
若是你正在使用 AngularJS 构建一个面向大众消费者的应用,你确定但愿用户能把它分享到社交媒体上。对于特定的应用而言,丰富的社交分享差很少是最重要的营销渠道。所谓「丰富的社交分享」,是指像下面这样的分享:
能够看到, Facebook, Twitter 等社交站点可以获取很是丰富的内容,不只限于网页标题和图片。为何能够作到这一点?由于在网页 HTML 文档的
head
部分包含了有特别含义的元数据标记。像 Facebook 以及 Pinterest 和 Google+ 等社交站点能读取遵循
开放图协议标准的元数据,例如,
<head>
<meta property="og:title" content="My Page" />
<meta property="og:description" content="A description of my page." />
<meta property="og:image" content="http://www.mysite.com/images/my_lovely_face.jpg" />
<!-- etc. -->
</head>
Twitter 也支持相似的机制,不过它用的元数据属性前缀是
twitter:
,而不是
og:
。
当用户在社交站点上分享一个 URL 时,社交站点会启动一个网络爬虫去抓取该页面的内容。网络爬虫首先在网页源文档中找出各类元数据标记,而后才会查看常规 HTML 元素的内容,例如,
<head>
标记和网页中的图像等。
用 AngularJS(以及其它 JavaScript 框架)开发的 Web 站点不支持爬虫的抓取
我已经在
Earlyclaim 站点的网页中添加了全部必需的遵循开放图协议标准的元数据标记。可是,当我把 Earlyclaim 站点的一个连接分享到 Facebook 时,显示的结果倒是很是使人失望的:
致使如此糟糕的结果的缘由很简单:抓取网页时,网络爬虫并不会执行网页中的 JavaScript 代码。所以,爬虫抓取到的内容是这样的:
<head>
<meta property="og:title" content="{{meta.title}} - earlyclaim.com" />
<meta property="og:description" content="{{meta.description}}" />
<meta property="og:image" content="{{meta.image}}" />
<!-- etc. -->
</head>
解决方案
解决方案的基本思想是:应用一种在服务器端执行的用户代理探测方法,识别出当前请求来自于社交站点的爬虫;此时,服务器不会像处理浏览器请求那样返回一个 AngularJS 模板文件,而是重定向到一个服务器端生成的页面,页面中包含了但愿提供的元数据标记以及正确填写的信息。
通过 Google 搜索,以及与其它创业公司
startypchile 的技术人员的讨论,咱们发现了
prerender.io 服务,它可以预先渲染好动态页面的内容。这为问题的解决奠基了良好的开端。
Prerender 的开发者提供了不少
中间件, 还把
prerender 引擎开源,由于他们认为
咱们相信搜索引擎优化(SEO)是一种权利,而非一种特权!
固然,若是你愿意,也能够付费使用他们提供的 Prerender 托管服务。
支撑
Earlyclaim 的基础设施是以
Docker 为基础构建的。为了集成 Prerender 服务,咱们首先在 Docker Hub 中找出相关的几个容器镜像,而后进行试用,结果难以使人感到满意。
咱们的需求包括:
这些也是咱们自行构建容器镜像的缘由!
为何公开咱们的解决方案
首先,咱们信仰「协同智能」:
协同智能是多主体、分布式系统的特征,其中每一个主体(人或者机器)都有惟一的位置,自主地为问题解决网络做贡献。在生态系统中,有机体的协同自治使得演化成为可能。在天然生态系统中,每一个有机体的惟一标识来自于自身的基因、环境以及它在生态系统中的行为和位置。天然生态系统为设计下一代社交网络提供原则,使之可以支持协同智能、众包我的的专长、偏好以及在问题解决过程当中的独特贡献。
- 摘自
维基百科
咱们的解决方案是创建在开源的
prerender.io 引擎 的基础之上:没有它,就不会有咱们的解决方案。 Prerender 团队太棒了。
其次,一样重要的是,在与不少创业公司的开发者交流以后,咱们了解到:他们不少人都在使用 AngularJS 或者其它框架构建 Web 应用,也须要解决搜索引擎优化/丰富的社交分享问题。然而,因为不知道解决方法,或者感受解决起来太耗费时间,或许会影响更为重要的产品发布时间,他们暂时搁置这个问题,留待之后解决。还有些开发者甚至没有意识到有这个问题,当从咱们这里据说了以后,他们请求咱们把解决方案分享出来。
咱们相信这个方案可以加速整个开发进程,由于它解决了一个广泛的问题。很高兴可以分享这个方案。
实现
若是技术人员想把咱们构建的容器镜像添加到本身的基础设施中,请参考 Docker Hub 上的文档:
https://registry.hub.docker.co ... edis/
AngularJS 服务
若是是 AngularJS 应用,首先实现下面的代码:
'use strict';
!(function (window, document, undefined) {
var getModule = function (angular) {
return angular.module('seo', [])
.run([
'$rootScope',
function ($rootScope) {
$rootScope.htmlReady = function () {
$rootScope.$evalAsync(function () { // fire after $digest
setTimeout(function () { // fire after DOM rendering
if (typeof window.callPhantom === 'function') {
window.callPhantom();
}
}, 0);
});
};
}
]);
};
if (typeof define === 'function' && define.amd) {
define(['angular'], getModule);
} else {
getModule(angular);
}
})(window, document);
而后经过
angular.module('youApp', ['seo'])
调用。
结论
若是你使用咱们的容器,以为还不错,请必定告知咱们(
@Earlyclaim)。
若是你以为有人会对此感兴趣,请转发给他们(点击社交分享按钮)!
任何建议,请发推特并通知
@Earlyclaim :很是期待您的观点和文字!
任何代码改进,请经过
GitHub 推送合并请求!
顺便说一句,咱们热爱创业公司,咱们热爱开发者,咱们热爱社区!开放生态系统万岁!
原文:
Get your Javascript website perfectly crawled with Docker (翻译:柳泉波 校对:佚名) ===================================== 译者介绍 柳泉波,读书喝茶踢球写程序,目前在华南师范大学广东高校计算机网络与信息系统工程中心工做。