谷歌搜索控制台中的爬虫无法在使用Github Page的React应用程序中找到路由。

12

我的问题是在 Google 搜索控制台 中的 Crawl 无法找到 React 中的子路由。

URL 是 https://huynhsamha.github.io/crypto,爬虫可以 获取和渲染 主页(路由/)和静态文件,例如 /robots.txt/favicon.ico,但它无法找到由 React 渲染的子路由(SPA,使用 Redux),例如 /algorithm/sha256。例如,https://huynhsamha.github.io/crypto/algorithm/sha256 爬虫无法找到,但它是可以访问的。

这是我在 Google 搜索控制台中尝试的截图。

enter image description here

谁能解释为什么,并说明如何解决我的问题?我正在使用 react-router-domreact-redux。我的 Github 存储库 在这里

编辑 1

我还尝试了这个问题里的答案https://dev59.com/JVQJ5IYBdhLWcg3wZU__#53966338,但不起作用。我在index.html文件中添加了脚本 (https://github.com/huynhsamha/crypto/blob/gh-pages/index.html),但搜索控制台仍然找不到,因此也无法在屏幕上呈现任何错误。

编辑2

我还尝试了这个问题里的答案https://dev59.com/JVQJ5IYBdhLWcg3wZU__#54040745https://dev59.com/JVQJ5IYBdhLWcg3wZU__#54048119,但不起作用。我创建了404.html文件,并按照答案的指示添加了脚本,但仍然没有效果。

编辑3

我还尝试了这个问题里的答案https://dev59.com/JVQJ5IYBdhLWcg3wZU__#54044148,通过创建一个简单的sitemap.xml,googlebot可以找到这个文件并发现我在网站地图中定义的所有网址。但它仍然无法获取和呈现提到的网址。

5个回答

5
我发现当我打开https://huynhsamha.github.io/crypto/algorithm/sha256时,实际上收到了一个404作为响应。我认为你在GitHub上使用404.html来托管SPA的解决方法是问题所在。虽然我们人类可以正确地在浏览器中看到您的应用程序正在提供服务,但Googlebot并不关心,只看响应代码并确认它已经收到了404。您需要一个不涉及直接使用404.html作为入口点的不同解决方法。

相反,尝试跟随rafrex提供的这个解决方法,它使用404.html将浏览器重定向到index.html,同时保留原始路由。据称,Googlebot会将其注册为301,而不是404,对于您的情况,这意味着将以下更改添加到您的站点,请注意下面的脚本:<!-- ------Single Page Apps GitHub Pages Workaround------ -->

<!-- 404.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Cryptography</title>

    <!-- ------Single Page Apps GitHub Pages Workaround------ -->
    <script type="text/javascript">
      // Single Page Apps for GitHub Pages
      // https://github.com/rafrex/spa-github-pages
      // Copyright (c) 2016 Rafael Pedicini, licensed under the MIT License
      // ----------------------------------------------------------------------
      // This script takes the current url and converts the path and query
      // string into just a query string, and then redirects the browser
      // to the new url with only a query string and hash fragment,
      // e.g. http://www.foo.tld/one/two?a=b&c=d#qwe, becomes
      // http://www.foo.tld/?p=/one/two&q=a=b~and~c=d#qwe
      // Note: this 404.html file must be at least 512 bytes for it to work
      // with Internet Explorer (it is currently > 512 bytes)
      // If you're creating a Project Pages site and NOT using a custom domain,
      // then set segmentCount to 1 (enterprise users may need to set it to > 1).
      // This way the code will only replace the route part of the path, and not
      // the real directory in which the app resides, for example:
      // https://username.github.io/repo-name/one/two?a=b&c=d#qwe becomes
      // https://username.github.io/repo-name/?p=/one/two&q=a=b~and~c=d#qwe
      // Otherwise, leave segmentCount as 0.
      var segmentCount = 1;
      var l = window.location;
      l.replace(
        l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
        l.pathname.split('/').slice(0, 1 + segmentCount).join('/') + '/?p=/' +
        l.pathname.slice(1).split('/').slice(segmentCount).join('/').replace(/&/g, '~and~') +
        (l.search ? '&q=' + l.search.slice(1).replace(/&/g, '~and~') : '') +
        l.hash
      );
    </script>
  </head>
  <body>
  </body>
</html>

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="theme-color" content="#000000">
  <meta name="description" content="Cryptography Algorithms: Secure Hash Algorithm (sha256, sha512, ...), Message Digest Algorithm (md5, ripemd160), HMAC-SHA, HMAC-MD, pbkdf2, Advanced Encryption Standard (AES), Triple Data Encryption Standard, (TripleDES, DES), RC4, Rabbit, ...">
  <meta name="keywords" content="crypto, algorithms, secure hash, sha, sha512, sha256, message digest, md5, hmac-sha, aes, des, tripledes, pbkdf2, rc4, rabbit, encryption, descryption">
  <meta name="author" content="huynhsamha">

  <!-- Open Graph -->
  <meta property="fb:app_id" content="440168923127908">
  <meta property="og:url" content="https://huynhsamha.github.io/crypto">
  <meta property="og:title" content="Cryptography Algorithms">
  <meta property="og:description" content="Cryptography Algorithms: Secure Hash Algorithm (sha256, sha512, ...), Message Digest Algorithm (md5, ripemd160), HMAC-SHA, HMAC-MD, pbkdf2, Advanced Encryption Standard (AES), Triple Data Encryption Standard, (TripleDES, DES), RC4, Rabbit, ...">
  <meta property="og:type" content="website">
  <meta property="og:image" content="%PUBLIC_URL%/img/main.jpeg">
  <meta property="og:site_name" content="Cryptography">
  <meta property="og:locale" content="vi_VN">

  <!-- Twitter Card -->
  <meta name="twitter:card" content="summary">
  <meta name="twitter:site" content="@huynhsamha">
  <meta name="twitter:creator" content="@huynhsamha">
  <meta name="twitter:url" content="https://huynhsamha.github.io/crypto">
  <meta name="twitter:title" content="Cryptography Algorithms">
  <meta name="twitter:description" content="Cryptography Algorithms: Secure Hash Algorithm (sha256, sha512, ...), Message Digest Algorithm (md5, ripemd160), HMAC-SHA, HMAC-MD, pbkdf2, Advanced Encryption Standard (AES), Triple Data Encryption Standard, (TripleDES, DES), RC4, Rabbit, ...">
  <meta name="twitter:image:src" content="%PUBLIC_URL%/img/main.jpeg">

  <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
  <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
  <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
  <link rel="author" href="//github.com/huynhsamha">
  <link rel="canonical" href="//huynhsamha.github.io/crypto">
  <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.
      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
  <link href="//fonts.googleapis.com/css?family=Open+Sans:400,600,700&amp;subset=vietnamese" rel="stylesheet">
  <link rel="stylesheet" href="%PUBLIC_URL%/css/bootstrap.min.css">
  <link rel="stylesheet" href="%PUBLIC_URL%/lib/font-awesome/css/font-awesome.min.css">

  <!-- ------Single Page Apps GitHub Pages Workaround------ -->
  <script type="text/javascript">
    // Single Page Apps for GitHub Pages
    // https://github.com/rafrex/spa-github-pages
    // Copyright (c) 2016 Rafael Pedicini, licensed under the MIT License
    // ----------------------------------------------------------------------
    // This script checks to see if a redirect is present in the query string
    // and converts it back into the correct url and adds it to the
    // browser's history using window.history.replaceState(...),
    // which won't cause the browser to attempt to load the new url.
    // When the single page app is loaded further down in this file,
    // the correct url will be waiting in the browser's history for
    // the single page app to route accordingly.
    (function(l) {
      if (l.search) {
        var q = {};
        l.search.slice(1).split('&').forEach(function(v) {
          var a = v.split('=');
          q[a[0]] = a.slice(1).join('=').replace(/~and~/g, '&');
        });
        if (q.p !== undefined) {
          window.history.replaceState(null, null,
            l.pathname.slice(0, -1) + (q.p || '') +
            (q.q ? ('?' + q.q) : '') +
            l.hash
          );
        }
      }
    }(window.location))
   </script>


  <title>Cryptography</title>

</head>

<body>
  <noscript>
    You need to enable JavaScript to run this app.
  </noscript>

  <div id="root"></div>

  <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.
      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.
      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->

  <script src="%PUBLIC_URL%/js/jquery-3.3.1.slim.min.js" type="text/javascript"></script>
  <script src="%PUBLIC_URL%/js/popper.min.js" type="text/javascript"></script>
  <script src="%PUBLIC_URL%/js/bootstrap.min.js" type="text/javascript"></script>

  <!-- Google Adsense -->
  <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

</body>

</html>

更多信息和关于GitHub支持单页应用程序的讨论 在此处


chrsep -- 抱歉,我完全复制了你的答案。一开始我没有注意到它。作为参考,Stack Overflow的答案最好综合用户问题的直接答案并提供解决方案,而不仅仅是提供资源链接。然而,这个答案是正确的。 - Jonny Asmar
1
嗨@Jonny,没关系,这不是完全的重复,我链接的解决方法以不同的方式进行重定向。谢谢你的建议,我会更新我的答案,使其更加直接和具体。 - chrsep
我尝试了你的解决方案,但仍然没有起作用,不过我也感谢你提供了一个解决方案。 - Ha. Huynh

4
我查看了你的源代码,没有发现任何异常;然而,我找到了一些关于类似问题的帖子(1) (2)。第二个帖子似乎特别有用,所以我在这里重复一下。感谢Reddit上的@Zerotorescue。
打开Google搜索控制台,转到“抓取”->“作为Google提取”并进行提取和呈现。
将此添加到您的站点中,可以作为HTML文件中标签的一部分或作为捆绑包的一部分:

https://gist.github.com/mstijak/715fa2dd3f495a98386c3ebbadbabb8c

我建议使用前者,因为这样更容易改变,如果需要使其更易读(无需重新编译应用程序)。

将此推送到您的站点,然后再次获取并显示。导致Google无法运行您的应用程序的错误现在将显示。搜索控制台分辨率相当低,因此您可能需要增加错误的字体大小并再次获取。不要担心,Google不介意重复调用。

您可能会发现,由于使用了一些ES6功能,Google的爬虫无法处理您的代码。您可以通过填充来解决此问题。我尝试过一些东西,例如https://polyfill.io/,但事实证明它并不真正支持Googlebot,虽然它有时可能有效,但它非常不可靠。相反,我建议使用babel-polyfill。它将为每个人增加一点捆绑大小,但根据我的经验,它提供了最广泛的浏览器支持,而且麻烦很小。只需打开它,您就完成了。

如果您正在使用create-react-app,则是我使用的polyfills.js文件,您可以复制:

https://github.com/WoWAnalyzer/WoWAnalyzer/blob/2c67a970f8bd9026fa816d31201c42eb860fe2a3/config/polyfills.js#L1

请注意,有很多评论解释了polyfill服务引入的所有问题,如果您使用babel-polyfill,则无需处理这些问题。


我已经尝试过了,但仍然无法正常工作。我已经在index.html中添加了脚本https://github.com/huynhsamha/crypto/blob/gh-pages/index.html,但搜索控制台找不到它,因此也无法在屏幕上呈现任何错误。 - Ha. Huynh

3

因为React应用程序是单页Web应用程序,所以您需要一个网站地图文件。您可以在此处找到如何制作一个网站地图,也可以制作一个404页面,并且每个路由都添加具有锚点的属性,例如:

<a title="This my Route One" href="https://myreactapp/routeOne" alt="Route One"/>

我尝试了您提供的解决方案,创建了一个简单的sitemap.xml文件,但仍然无法正常工作。Googlebot可以找到/sitemap.xml并发现我在此文件中列出的所有URL,但它无法获取和呈现所提到的URL。谢谢。 - Ha. Huynh
you can add it to robots.txt - Soleil
文件 robots.txt 我使用 User-agent: * 允许它,这样做有问题吗? - Ha. Huynh
用户代理:Googlebot,作为首选项,但我不知道您是否需要添加元标记刷新,例如“无缓存”。 - Soleil
你能告诉我一些关于你想法的偏好吗? - Ha. Huynh

2
问题在于您正在使用 404 页面来捕获除 / 以外的其他路由传入的流量。这意味着这些路由提供了一个 404 状态码(如果您打开开发工具中的网络并尝试访问其中一个深层 URL,您可以看到这一点)。Google 在响应头中看到 404 状态码,就会立即放弃。您可能已经注意到,在 Webmaster 工具中,“未找到”消息出现得非常快。
在普通服务器上,您将捕获这些路由并返回成功的状态代码,如 200301,然后 Google 将继续爬取。但是,由于您使用的是 GitHub Pages,因此您需要绕过此限制。
您应该能够通过设置从该 404 模板到您的索引模板的即时重定向来解决此问题。浏览器将即时重定向解释为 301。要执行此操作,请将您的 404.html 的内容替换为以下内容:
<html>
<head>
  <script>
    sessionStorage.redirect = location.href; // we'll use this later
  </script>
  <meta http-equiv="refresh" content="0;URL='/crypto'">
</head>
<body></body>
</html>

请确保404.html的文件大小大于512b,否则IE会丢弃它(该死的微软...)。

最后,您需要确保index.html可以捕获原始路由。为此,请在index.html的头部使用以下脚本:

<script>
  (function(){
    var redirect = sessionStorage.redirect; // remember me?
    delete sessionStorage.redirect;
    if (redirect && redirect != location.href) {
      history.replaceState(null, null, redirect);
    }
  })();
</script>

供参考,我从以下网站学到了这个聪明的技巧:

https://www.smashingmagazine.com/2016/08/sghpa-single-page-app-hack-github-pages/


(注:本文是关于it技术的翻译)

我尝试了你的解决方案,但仍然没有起作用,不过我也感谢你提供了一个解决方案。 - Ha. Huynh

0

我认为你的代码没有什么值得担心的地方(虽然我不确定你是否需要在<Route />中使用baseUrl,但我可能是错的,而且我也不认为这是问题所在,但如果不必要的话,消除它可能是值得的)。

仅仅是猜测,但是当我在链接之间跳转时查看网络选项卡时,我注意到了服务工作者。我承认,当涉及到服务工作者时,我还不是很精通(但我会努力的!),然而通过一些谷歌搜索,我发现谷歌爬虫尚不支持服务工作者,正如这篇文章这篇文章谷歌所断言的那样... 我还注意到,如果我在应用内导航中到达的某个链接上运行Lighthouse测试(例如,我从主页上的导航栏单击/algorithm选项卡,然后运行Lighthouse测试),我会得到以下错误:

此次Lighthouse运行受到的问题:Chrome扩展程序对该页面的加载性能产生了负面影响。请尝试在无痕模式下或使用没有扩展程序的Chrome配置文件审核该页面。

还有更有趣的

Lighthouse 无法可靠地加载您请求的页面。请确保您正在测试正确的 URL,并且服务器正常响应所有请求。状态代码:404。尽管在浏览器中清楚地看到它呈现,但似乎有问题。因此,如果这是导航发生的一部分(根据您存储库中的 registerServiceWorker.js 文件,似乎很可能是),它可能是链接未被找到/跟随的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接