31

在阅读了 Google 关于使 Ajax 生成的内容可抓取的政策,以及许多开发人员的博客文章和有关该主题的 Stackoverflow 问答线程之后,我得出的结论是,没有办法制作一个仅使用 JavaScript/Ajax 生成的网站可抓取的 HTML。我目前正在工作的网站没有获得相当数量的内容索引。我们的非索引内容的所有表示层都是用 JavaScript 构建的,通过从基于 Ajax 的 Web 服务调用返回的 JSON 生成 HTML,我们相信 Google 不会因此而对内容进行索引。那是对的吗?

唯一的解决方案似乎是也为搜索引擎(特别是谷歌)提供一个“后备”版本的网站,其中所有的 HTML 和内容都将按照传统方式在服务器端生成。对于启用了 JavaScript 的客户端,我们似乎可以使用与现在基本相同的方法:使用 JavaScript 从异步加载的 JSON 生成 HTML。

环顾四周,我的理解是,当前在创建如上所述的可抓取 Ajax 生成的网站时应用DRY 原则的最佳实践是使用可以在客户端和服务器端使用相同模板的模板引擎。对于启用了 JavaScript 的客户端,客户端模板引擎(例如mustache.js)将从服务器发送的 JSON 数据转换为由其模板文件副本定义的 HTML。对于禁用 JavaScript 的搜索爬虫和客户端,相同模板引擎的服务器端实现(例如mustache.java)将类似地对其完全相同的模板文件副本进行操作以输出 HTML。

如果该解决方案是正确的,那么这与 4 或 5 年前前端重型网站使用的方法有何不同,在这些方法中,网站基本上必须维护模板代码的两份副本,一份用于启用 JavaScript 的用户(几乎每个人)以及没有启用 JavaScript 的搜索引擎和浏览器的另一个副本(例如在FreeMarkerVelocity中)(几乎没有人)?似乎应该有更好的方法。

这是否意味着需要维护两个模板模型层,一个在客户端,一个在服务器端?将这些客户端模板与Backbone.jsEmber.jsYUI App Library等前端 MVC (MV/MVVC) 框架结合起来有多可取?这些解决方案如何影响维护成本?在不向开发团队的技术堆栈中引入更多框架(新的模板引擎和前端 MVC 框架)的情况下尝试这样做会更好吗?有没有办法减少冗余?

如果该解决方案不正确,那么我们是否缺少某些东西,并且可以使用 JavaScript 做得更好,以保持我们现有的异步 HTML-from-JSON 结构并将其编入索引,因此我们不需要引入新的东西到架构堆栈?当业务需求发生变化时,我们真的宁愿不必更新表示层的两个版本。

4

5 回答 5

10

我以前怎么没想到!只需使用http://phantomjs.org。这是一个无头 webkit 浏览器。您只需构建一组操作来抓取 UI 并在您想要的每个状态下捕获 html。Phantom 可以为您将捕获的 html 转换为 .html 文件并将它们保存到您的 Web 服务器。

每次构建/提交时,整个事情都会自动化(PhantomJS 是命令行驱动的)。您编写的用于抓取 UI 的 JS 代码会在您更改 UI 时中断,但它不应该比自动化 UI 测试更糟糕,而且它只是 Javascript,因此您可以使用 jQuery 选择器来抓取按钮并单击它们。

如果我必须解决 SEO 问题,这绝对是我制作原型的第一种方法。爬行并保存,宝贝。是的先生。

于 2012-04-23T03:00:28.987 回答
3

我认为结合一些技术和一个你可以重复使用的手动编码的黑客技术可以解决你的问题。这是我疯狂的、半生不熟的想法。这是理论上的,可能不完整。步骤1:

  • 按照您的建议,使用客户端模板。将每个模板放在一个单独的文件中(以便您可以在客户端和服务器之间轻松地重用它们)
  • 使用 underscore.js 模板,或重新配置 Mustache。这样,您将在模板中获得 ERB 样式分隔符,与 Java 的 <%= %> 内容相同。
  • 由于它们是单独的文件,因此您需要使用 curl.js 或 require.js 等模块加载器在 CommonJS 模块中开始开发,以便在客户端代码中加载模板。如果您不进行模块化开发,那真是太棒了。我开始〜一个月前。一开始似乎很难,但这只是包装代码的另一种方式:http: //addyosmani.com/writing-modular-js/

好的,现在您有了独立的模板。现在我们只需要弄清楚如何在服务器上用它们构建一个平面页面。我只看到两种方法。第2步:

  • 您可以注释您的 JS,以便服务器可以读取它并查看 ajax 调用的默认路径以及它们链接到的模板,然后服务器可以使用注释以正确的顺序调用控制器方法并填写一个平面页面。
  • 或者您可以注释您的模板以指示它们应该调用哪个控制器并提供示例调用参数。这将很容易维护,并且会让像我这样必须一直查找控制器 URL 的前端开发人员受益。它还会告诉你的后端代码调用什么。

希望这可以帮助。很想听到这个问题的最佳答案。一个有趣的问题。

于 2012-04-23T02:56:18.937 回答
1

使用远端模板。您的网站是可抓取的静态 HTML,并且 Distal 将静态 HTML 视为模板。

于 2012-04-24T02:10:50.800 回答
0

我们确实为此目的使用了 PhantomJS,就像可以说的那样简单。如果您有权在主机上使用它,那将非常有用。

如果这不是一个选择,或者如果你只是不想自己处理。我们确实有这样做的免费服务。有关更多信息,请参阅此帖子:http ://rogeralsing.com/2013/08/06/seo-indexing-angularjs-sites-or-other-ajax-sites-with-wombit-crawlr/

于 2013-08-06T22:20:49.090 回答
0

我找到了一个不需要任何 Java、Node.js 或任何其他方式来制作 JS 代码生成网站的冗余副本的解决方案。它还支持所有浏览器。

所以你需要做的是为谷歌提供快照。这是最好的解决方案,因为您不需要弄乱其他 URL 等等。另外:您不会在基本网站中添加 noscript,因此它更轻巧。

如何制作快照?Phantomjs、HTMLUnit 等需要一个可以放置和调用的服务器。您需要对其进行配置,并与您的网站结合使用。这是一团糟。不幸的是,没有 PHP 无头浏览器。由于 PHP 的特殊性,这一点很明显。

那么获取快照的另一种方法是什么?好吧...如果用户打开网站,您可以通过 JS (innerHTML) 获得他所看到的快照。

所以你需要做的是:

  • 检查您是否需要网站快照(如果有,则无需再拍摄)
  • 您将此快照发送到服务器以保存到文件(PHP 使用快照处理 POST 请求,并保存到文件)

如果 Google Bot 访问您的 hash bang 网站,您将获得所请求页面的快照文件。

要解决的事情:

  • 安全性:您不希望用户或他的浏览器(注入)的任何脚本保存到快照,也许最好的办法只有您可以生成快照(参见下面的站点地图)
  • 兼容性:您不想从任何浏览器中保存,而是从最支持您的网站的浏览器中保存
  • 不要打扰移动设备:只是不要使用移动用户来生成快照,这样页面对他们来说不会变慢
  • 故障转移:如果你没有快照输出标准网站——它对谷歌没有好处,但总比没有好

还有一件事:并非所有页面都会被用户访问,但在他们访问之前您需要 Google 的快照。

那么该怎么办?对此也有解决方案:

  • 生成包含您网站上所有页面的站点地图(必须即时生成才能保持最新,而爬虫软件无济于事,因为它不执行 JS)
  • 以任何方式访问站点地图中没有快照的页面。这将调用快照代码并正确生成它
  • 定期(每天?)

但是,嘿,如何访问所有这些页面?出色地。有一些解决方案:

  • 用 Java、C# 或其他语言编写一个应用程序,以从服务器获取要访问的页面,并使用内置的浏览器控件访问它。将此添加到您在服务器上的日程安排中。
  • 编写一个 JS 脚本,在 iFRAME 中逐个打开所需的页面。将此添加到您在计算机上的日程安排中。
  • 如果您的网站大部分是静态的,只需手动打开上述脚本

还记得偶尔刷新旧快照以使它们保持最新。

我希望听到您对此解决方案的看法。

于 2013-11-07T15:05:35.580 回答