动态内容单页应用SEO

时间:2015-01-15 09:20:27

标签: angularjs seo search-engine single-page-application

我是SEO的新手,只想了解它如何适用于带有动态内容的单页应用程序。

在我的情况下,我有一个单页面应用程序(由AngularJS提供支持,使用路由器显示不同的状态),提供一些基于位置的搜索功能,类似于ZillowRedfin或{ {3}}。在mt站点上,用户可以输入位置名称,站点将根据位置返回一些结果。

我正试图想办法让它与Google合作。例如,如果我输入" Apartment San Francisco"在谷歌,结果将是:

enter image description here

当用户点击这些链接时,网站将显示正确的结果。我正在考虑为我的网站提供类似的搜索引擎优化。

问题是,页面内容完全取决于用户的查询。用户可以按城市名称,州名,邮政编码等进行搜索,以显示不同的结果,并且无法将它们全部放入站点地图中。谷歌如何抓取这些动态页面结果的内容?

我没有SEO经验,也不知道如何为我的网站做这件事。请分享一些经验或指示,以帮助我开始。非常感谢!

===========

跟进问题:
我看到Googlebot可以Yelp。我想了解更多这方面的内容。
当我的SPA应用程序的特定网址被打开时,它将进行一些网络查询(XHR请求)几秒钟,然后将显示页面内容。在这种情况下,GoogleBot会等待http响应吗?

我看到一些教程说我们需要专门为搜索引擎准备静态html。如果我只想与Google打交道,那是否意味着我不再需要提供静态HTML,因为Google可以运行Javascript?

再次感谢。

1 个答案:

答案 0 :(得分:3)

如果搜索引擎应该遇到您的JavaScript应用程序,那么我们就有权将搜索引擎重定向到另一个提供该页面完全呈现版本的URL。

这项工作

  1. 你可以使用Thomas Davis在github上提供的这个工具
  2. SEOSERVER

    1. 您可以使用下面的代码执行相同的工作,此代码也可用here
    2. 使用Phantom.js实现

      我们可以设置一个给定URL的node.js服务器,它将完全呈现页面内容。然后我们将机器人重定向到此服务器以检索正确的内容。

      我们需要将node.js和phantom.js安装到一个盒子上。然后在下面启动此服务器。有两个文件,一个是Web服务器,另一个是渲染页面的phantomjs脚本。

      // web.js
      
      // Express is our web server that can handle request
      var express = require('express');
      var app = express();
      var getContent = function(url, callback) {
        var content = '';
        // Here we spawn a phantom.js process, the first element of the 
        // array is our phantomjs script and the second element is our url 
        var phantom = require('child_process').spawn('phantomjs',['phantom-server.js', url]);
        phantom.stdout.setEncoding('utf8');
        // Our phantom.js script is simply logging the output and
        // we access it here through stdout
        phantom.stdout.on('data', function(data) {
          content += data.toString();
        });
        phantom.on('exit', function(code) {
          if (code !== 0) {
            console.log('We have an error');
          } else {
            // once our phantom.js script exits, let's call out call back
            // which outputs the contents to the page
            callback(content);
          }
        });
      };
      
      var respond = function (req, res) {
        // Because we use [P] in htaccess we have access to this header
        url = 'http://' + req.headers['x-forwarded-host'] + req.params[0];
        getContent(url, function (content) {
          res.send(content);
        });
      }
      app.get(/(.*)/, respond);
      app.listen(3000);
      

      下面的脚本是phantom-server.js,负责完全呈现内容。在页面完全呈现之前,我们不会返回内容。我们挂钩资源监听器来做到这一点。

      var page = require('webpage').create();
      var system = require('system');
      
      var lastReceived = new Date().getTime();
      var requestCount = 0;
      var responseCount = 0;
      var requestIds = [];
      var startTime = new Date().getTime();
      
      page.onResourceReceived = function (response) {
          if(requestIds.indexOf(response.id) !== -1) {
              lastReceived = new Date().getTime();
              responseCount++;
              requestIds[requestIds.indexOf(response.id)] = null;
          }
      };
      page.onResourceRequested = function (request) {
          if(requestIds.indexOf(request.id) === -1) {
              requestIds.push(request.id);
              requestCount++;
          }
      };
      
      // Open the page
      page.open(system.args[1], function () {});
      var checkComplete = function () {
        // We don't allow it to take longer than 5 seconds but
        // don't return until all requests are finished
        if((new Date().getTime() - lastReceived > 300 && requestCount === responseCount) || new Date().getTime() - startTime > 5000)  {
          clearInterval(checkCompleteInterval);
          console.log(page.content);
          phantom.exit();
        }
      }
      // Let us check to see if the page is finished rendering
      var checkCompleteInterval = setInterval(checkComplete, 1);
      

      一旦我们启动并运行此服务器,我们只需将机器人重定向到客户端Web服务器配置中的服务器。

      重定向机器人 如果您使用的是apache,我们可以编辑.htaccess,以便将Google请求代理到我们的中间人phantom.js服务器。

      RewriteEngine on
      RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$
      RewriteRule (.*) http://webserver:3000/%1? [P]
      

      我们还可以包含其他RewriteCond,例如用户代理,以重定向我们希望编入索引的其他搜索引擎。

      虽然Google不会使用_escaped_fragment_,除非我们通过包含元标记告诉它; <meta name="fragment" content="!">或在我们的链接中使用#!网址。

      您很可能必须同时使用它们。

      这已经过Google网站管理员抓取工具的测试。使用提取工具时,请务必在网址上加{4}。