19

要么我的 google-fu 让我失望了,要么真的没有太多人这样做。如您所知,Backbone.js 有一个致命弱点——它无法将它呈现的 html 提供给诸如 googlebot 之类的页面爬虫,因为它们不运行 JavaScript(尽管考虑到它的 Google 拥有他们的资源、V8 引擎以及一个发人深省的事实: JavaScript 应用程序正在兴起,我希望这有一天会发生)。我知道谷歌有一个 hashbang 变通政策,但这只是一个坏主意。另外,我正在使用 PushState。这对我来说是一个极其重要的问题,我希望对其他人也是如此。SEO 是不可忽视的东西,因此对于许多需要或依赖它的应用程序来说,它不能被考虑。

输入 node.js。我才刚刚开始进入这种热潮,但似乎有可能让客户端上存在的相同 Backbone.js 应用程序与 node.js 手牵手的服务器上。然后 node.js 将能够将 Backbone.js 应用程序呈现的 html 提供给页面爬虫。这似乎是可行的,但我正在寻找对 node.js 更有经验的人,或者甚至更好的人,真正做到这一点的人,为我提供建议。

我需要采取哪些步骤才能允许我使用 node.js 将我的 Backbone.js 应用程序提供给网络爬虫?此外,我的 Backbone 应用程序使用了一个用 Rails 编写的 API,我认为这会让这不那么令人头疼。

编辑:我没有提到我已经有一个用 Backbone.js 编写的生产应用程序。我希望将此技术应用于该应用程序。

4

6 回答 6

1

首先,让我添加一个免责声明,我认为使用 node.js 是一个坏主意。第二个免责声明:我做过类似的黑客攻击,但只是为了自动化测试,而不是爬虫。

有了这个,我们走吧。如果您打算在服务器上运行客户端应用程序,则需要在服务器上重新创建浏览器环境:

  1. 最明显的是,您缺少 DOM(文档对象模型) - 基本上是已解析 HTML 文档之上的 AST。对此的 node.js 解决方案是jsdom

  2. 然而,这还不够。您的浏览器还公开 BOM(浏览器对象模型) - 访问浏览器功能,例如history.pushState. 这就是棘手的地方。有两种选择:您可以尝试弯曲phantomjscasperjs来运行您的应用程序,然后从其中刮掉 HTML。它很脆弱,因为您正在运行一个巨大的完整 WebKit 浏览器,并且 UI 部分被锯掉了。

  3. 另一个选项是Zombie - 它是在 Javascript 中对浏览器功能的轻量级重新实现。根据它支持pushState的页面,但我的经验是浏览器仿真远未完成 - 但是尝试一下,看看你能走多远。

于 2012-10-11T08:32:27.753 回答
0

可行的解决方案是在任何地方都使用 Backbone https://github.com/Morriz/backbone-everywhere但它会强制您使用 Node 作为后端。

另一种选择是在服务器和前端使用相同的模板。前端使用 require.js 文本插件加载 Mustache 模板,服务器也使用相同的 Mustache 模板呈现页面。

另一个附加功能是将 javascript 标记中的引导模块数据呈现为 JSON 数据,以便 Backbone 立即使用来填充模型和集合。

于 2012-10-13T13:34:02.723 回答
0

我相信您可以采用后备策略类型的方法。考虑一下关闭 javascript 并单击链接与打开 js 会发生什么。当 javascript 关闭时,您在页面上所做的任何可以被抓取的操作都应该有一些合理的后备程序。您的链接应始终将指向服务器的链接作为 href,并且应使用 javascript 防止发生默认操作。

我不会说这必然是骨干的责任。我的意思是,骨干在这里唯一可以帮助您的是在页面更改时修改您的 URL,并且您的模型/集合既是客户端又是服务器端。我相信视图和路由器将是严格的客户端。

不过,您可以做的是让您的翡翠页面和部分可从客户端或服务器端渲染,无论是否注入内容。通过这种方式,可以以任何一种方式呈现相同的页面。也就是说,如果您替换了大部分页面并更改了 url,那么您抓取的 html 可以来自同一个模板,就好像有人直接访问了该页面一样。

当您的服务器收到请求时,它应该直接将您带到该页面,而不是通过主入口点和加载主干并让它操纵页面并以用户希望使用 url 的方式设置它。

我认为你应该能够通过在你的应用程序中重新安排一些东西来实现这一点。没有真正的重写,只是移动了很多东西。您可能需要编写一个控制器,该控制器将为您提供注入或未注入内容的 html 文件。这将为您的主干应用程序提供与模型数据耦合所需的 html。就像我说的,当您通过 express/node.js 中定义的路由器直接点击这些链接时,可以使用这些相同的模板

于 2012-10-09T22:39:47.887 回答
0

我将由您来决定将您的渲染引擎推到服务器端是否是一个合理的决定。

因为 Nodejs 是基于 V8(Chrome 的引擎)构建的,所以它会像 Backbone.js 一样运行 javascript。创建模型等将以完全相同的方式完成。

Nodejs 环境当然缺少 DOM。所以这是您需要重新创建的部分。我相信最受欢迎的模块是:

https://github.com/tmpvar/jsdom

在 Nodejs 中拥有可访问的 DOM api 后,您只需像为典型的浏览器客户端(可能使用 jQuery)一样构建其节点并使用呈现的 HTML(通过 $("myDOM").html() 或类似方法)响应服务器请求)。

于 2012-10-09T11:27:42.130 回答
0

这是我与我们的应用程序要做的事情的待办事项列表:让 Node.js 解析 Backbone 路由(在应用程序启动时存储在内存中)并至少以直接 HTML 提供主页模板 - 可能还有更多当您考虑到成千上万的用户访问您的网站时,BE 的开销/处理过多。

我相信像 AirBnB 这样的 Backbone 应用程序也是这样做的,但仅适用于像 Google Crawler 这样的机器人。对于 Facebook 喜欢的内容,您也需要这种情况,因为 Facebook 会发送一个爬虫来读取您的 og:tags。

于 2012-10-09T22:49:13.207 回答
-1

基本上你需要决定你所服务的是什么:它是一个真正的应用程序(即可以替代专用桌面应用程序的东西),还是它是内容的呈现(即经典的“网页” )? 如果您担心 SEO,很可能实际上是后者(“内容网站”),在这种情况下,“单页应用程序”模型不合适;你真的想要“渐进增强的网站”模型(查找诸如“不显眼的 JavaScript”、“渐进增强”和“自适应网页设计”之类的短语)。

稍微放大一点,“服务器只发送序列化数据,客户端完成所有渲染”只适用于“真正的应用程序”场景。对于“内容站点”场景,合适的模型是“服务器进行主要渲染,客户端使其看起来更好,并进行一些小规模渲染,以尽可能避免破坏性的页面转换”。

而且,顺便说一句,反对渐进增强意味着“确保用户能看到的东西不会比使用文本转语音的盲人用户更好”是一种政治不满的表达,而不是现实。从拥有高端渲染系统的用户的角度来看,逐步增强的网站可以随心所欲。

于 2012-09-16T10:43:34.503 回答