尊重 robots.txt

许多网站都希望被抓取。 这是野兽的本性:网络托管商将内容放在其网站上以供人类查看。 但其他计算机能够看到这些内容也很重要。 一个很好的例子是搜索引擎优化 (SEO)。 SEO 是一个过程,您实际上将网站设计为可以被 Google 等蜘蛛抓取,因此您实际上是在鼓励抓取。 但同时,发布者可能只希望抓取其网站的特定部分,并告诉抓取工具让蜘蛛远离网站的某些部分,要么不用于共享,要么不够重要而无法被抓取和浪费 Web 服务器资源。

允许爬网和不允许爬网的规则通常包含在大多数网站上称为 robots.txt 的文件中。 robots.txt 是一个人类可读但可解析的文件,可用于识别允许和不允许抓取的位置。

不幸的是,robots.txt 文件的格式不是标准的,任何人都可以进行自己的修改,但对于格式有非常强烈的共识。 robots.txt 文件通常可以在网站的根 URL 中找到。 为了演示 arobots.txt 文件,以下代码包含 Amazon 在 http://amazon.com/robots.txt 提供的代码的摘录。 我对其进行了编辑以仅显示重要概念:

User-agent: *
Disallow: /exec/obidos/account-access-login
Disallow: /exec/obidos/change-style
Disallow: /exec/obidos/flex-sign-in
Disallow: /exec/obidos/handle-buy-box
Disallow: /exec/obidos/tg/cm/member/
Disallow: /gp/aw/help/id=sss
Disallow: /gp/cart
Disallow: /gp/flex
...
Allow: /wishlist/universal*
Allow: /wishlist/vendor-button*
Allow: /wishlist/get-button*
...
User-agent: Googlebot
Disallow: /rss/people/*/reviews
Disallow: /gp/pdp/rss/*/reviews
Disallow: /gp/cdp/member-reviews/
Disallow: /gp/aw/cr/
...
Allow: /wishlist/universal*
Allow: /wishlist/vendor-button*
Allow: /wishlist/get-button*

可以看到,该文件中主要包含三个内容:

  • 将应用以下行的用户代理声明,直到文件末尾或下一个用户代理声明

  • 允许抓取的一组 URL

  • 禁止抓取一组 URL

语法实际上非常简单,Python 库的存在可以帮助我们实现 robots.txt 中包含的规则。我们将使用 reppy 库来促进尊重 robots.txt。

准备工作

让我们看看如何演示如何将 robots.txt 与reppy 库一起使用。 有关 reppy 的更多信息,请参阅其 GitHub 页面:https://github.com/seomoz/reppy。

repy 可以这样安装:

pip install reppy

然而,我发现在我的 Mac 上安装时出现错误,需要执行以下命令:

CFLAGS=-stdlib=libc++ pip install reppy

一般信息/在 Google 上搜索 robots.txt Python 解析库通常会引导您使用 robotsparser 库。 该库适用于 Python 2.x。 对于 Python 3,它已移至 urllib 库中。 但是,我发现该库在特定场景下报告的值不正确。 我将在我们的示例中指出这一点。

如何做

要运行该示例,请执行 05/01_sitemap.py 中的代码。 该脚本将检查是否允许在 amazon.com 上抓取多个 URL。 运行它时,您将看到以下输出:

True: http://www.amazon.com/
False: http://www.amazon.com/gp/dmusic/
True: http://www.amazon.com/gp/dmusic/promotions/PrimeMusic/
False: http://www.amazon.com/gp/registry/wishlist/

工作原理

  1. 该脚本首先导入 reppy.robots:

    from reppy.robots import Robots
  2. 然后,代码使用 Robots 获取 amazon.com 的 robots.txt。

    url = "http://www.amazon.com"
    robots = Robots.fetch(url + "/robots.txt")
  3. 使用获取的内容,脚本检查多个 URL 的可访问性:

    paths = [
        '/',
        '/gp/dmusic/',
        '/gp/dmusic/promotions/PrimeMusic/',
        '/gp/registry/wishlist/'
    ]
    
    for path in paths:
        print("{0}: {1}".format(robots.allowed(path, '*'), url + path))

这段代码的结果如下:

True: http://www.amazon.com/
False: http://www.amazon.com/gp/dmusic/
True: http://www.amazon.com/gp/dmusic/promotions/PrimeMusic/
False: http://www.amazon.com/gp/registry/wishlist/

对 robots.allowed 的调用会给出 URL 和用户代理。 它根据是否允许抓取该 URL 返回 True 或 False。 在本例中,指定 URL 的结果为 True、False、True 和 False。 让我们来看看如何。

/ URL 在 robots.txt 中没有条目,因此默认情况下是允许的。 但在*用户代理组下的文件中有以下两行:

Disallow: /gp/dmusic/
Allow: /gp/dmusic/promotions/PrimeMusic

/gp/dmusic 是不允许的,因此返回 False。 /gp/dmusic/promotions/PrimeMusic 是明确允许的。 如果未指定“Allowed:”条目,则“Disallow:/gp/dmusic/”行也将禁止从/gp/dmusic/向下的任何其他路径。 这实质上是说,任何以 /gp/dmusic/ 开头的 URL 都是不允许的,除非您可以抓取 /gp/dmusic/promotions/PrimeMusic。

这是使用 robotsparser 库时存在的差异。 robotsparser 报告不允许使用 /gp/dmusic/promotions/PrimeMusic。 该库无法正确处理这种类型的情况,因为它在第一个匹配时停止扫描 robots.txt,并且不会继续进一步进入文件以查找此类的任何覆盖。

还有更多

首先,有关 robots.txt 的详细信息,请参阅 https://developers.google.com/search/reference/robots_txt

请注意,并非所有网站都有 robots.txt,它的缺失并不意味着您有自由抓取所有内容的权利。

此外,robots.txt 文件可能包含有关在何处查找网站的站点地图的信息。 我们将在下一个秘籍中检查这些站点地图。

Scrapy 还可以读取 robots.txt 并为您查找站点地图。