Python robotsparser 模块不会加载“robots.txt”

Posted

技术标签:

【中文标题】Python robotsparser 模块不会加载“robots.txt”【英文标题】:Python robotparser module won't load 'robots.txt' 【发布时间】:2012-04-19 01:56:59 【问题描述】:

我正在编写一个非常简单的网络爬虫并尝试解析'robots.txt' 文件。我在标准库中找到了robotparser 模块,它应该可以做到这一点。我正在使用 Python 2.7.2。不幸的是,我的代码无法正确加载 'robots.txt' 文件,我不知道为什么。

这是我的代码的相关sn-p:

from urlparse import urlparse, urljoin
import robotparser

def get_all_links(page, url):
    links = []
    page_url = urlparse(url)
    base = page_url[0] + '://' + page_url[1]
    robots_url = urljoin(base, '/robots.txt')
    rp = robotparser.RobotFileParser()
    rp.set_url(robots_url)
    rp.read()
    for link in page.find_all('a'):
        link_url = link.get('href')
        print "Found a link: ", link_url
        if not rp.can_fetch('*', link_url):
            print "Page off limits!" 
            pass

这里的page是一个解析的BeautifulSoup对象,url是一个存储为字符串的URL。解析器读入一个空白的 'robots.txt' 文件,而不是指定 URL 处的文件,并向所有 can_fetch() 查询返回 True。看起来它要么没有打开 URL,要么无法读取文本文件。

我也在交互式解释器中尝试过。这就是发生的情况,使用与documentation 页面相同的语法。

Python 2.7.2 (default, Aug 18 2011, 18:04:39) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import robotparser
>>> url = 'http://www.udacity-forums.com/robots.txt'
>>> rp = robotparser.RobotFileParser()
>>> rp.set_url(url)
>>> rp.read()
>>> print rp

>>> 

print rp 行应该打印'robots.txt' 文件的内容,但它返回空白。更令人沮丧的是,theseexamples 两者都可以正常工作,但是当我尝试自己的 URL 时却失败了。我对 Python 很陌生,我不知道出了什么问题。据我所知,我使用该模块的方式与文档和示例相同。感谢您的帮助!

更新 1: 这里还有几行来自解释器,以防print rp 不是检查'robots.txt' 是否被读入的好方法。path、@987654344 @, 和 url 属性是正确的,但是来自'robots.txt' 的条目仍然没有被读入。

>>> rp
<robotparser.RobotFileParser instance at 0x1004debd8>
>>> dir(rp)
['__doc__', '__init__', '__module__', '__str__', '_add_entry', 'allow_all', 'can_fetch', 'default_entry', 'disallow_all', 'entries', 'errcode', 'host', 'last_checked', 'modified', 'mtime', 'parse', 'path', 'read', 'set_url', 'url']
>>> rp.path
'/robots.txt'
>>> rp.host
'www.udacity-forums.com'
>>> rp.entries
[]
>>> rp.url
'http://www.udacity-forums.com/robots.txt'
>>> 

更新 2: 我已经通过使用 this external library 解析 'robots.txt' 文件解决了这个问题。 (但我还没有回答最初的问题!)在终端中花费了更多时间后,我最好的猜测是robotparser 无法处理'robots.txt' 规范中的某些添加,例如Sitemap,并且有空白问题线。它将读取文件,例如Stack Overflow 和 Python.org,但不包括 Google、YouTube 或我的原始 Udacity 文件,其中包括 Sitemap 语句和空行。如果比我聪明的人能证实或解释这一点,我仍然会很感激!

【问题讨论】:

顺便说一句,你可以在上下文here 中看到这个 sn-p,以防我遗漏了一些相关的东西。 行 print rp 应该打印 'robots.txt' 文件的内容 - 你确定吗? 非常确定。当我使用我链接的外部示例时,这就是它的行为方式。以防万一,我用口译员提供的更多信息更新了我的问题。 URL 属性看起来都正确,但 entries 是一个空列表。 我遇到了同样的问题,我尝试使用您提到的库 (nikitathespider.com/python/rerp) 解析 google.com/robots.txt,当我尝试 can_fetch("*", "/catalogs/p?") 时返回我是假的,即使它是允许的。我在这里怀疑。有什么线索吗? 【参考方案1】:

我已经通过使用这个外部库来解析“robots.txt”文件解决了这个问题。 (但我还没有回答最初的问题!)在终端上花费了更多时间后,我最好的猜测是,robotparser 无法处理对“robots.txt”规范的某些添加,例如站点地图,并且在空白行方面存在问题。它将读取文件,例如Stack Overflow 和 Python.org,但不包括 Google、YouTube 或我的原始 Udacity 文件,其中包括站点地图语句和空行。如果比我聪明的人能证实或解释这一点,我仍然会很感激!

【讨论】:

【参考方案2】:

解决方案可能是使用reppy 模块

pip install reppy

这里有几个例子;

In [1]: import reppy

In [2]: x = reppy.fetch("http://google.com/robots.txt")

In [3]: x.atts
Out[3]: 
'agents': '*': <reppy.agent at 0x1fd9610>,
 'sitemaps': ['http://www.gstatic.com/culturalinstitute/sitemaps/www_google_com_culturalinstitute/sitemap-index.xml',
  'http://www.google.com/hostednews/sitemap_index.xml',
  'http://www.google.com/sitemaps_webmasters.xml',
  'http://www.google.com/ventures/sitemap_ventures.xml',
  'http://www.gstatic.com/dictionary/static/sitemaps/sitemap_index.xml',
  'http://www.gstatic.com/earth/gallery/sitemaps/sitemap.xml',
  'http://www.gstatic.com/s2/sitemaps/profiles-sitemap.xml',
  'http://www.gstatic.com/trends/websites/sitemaps/sitemapindex.xml']

In [4]: x.allowed("/catalogs/about", "My_crawler") # Should return True, since it's allowed.
Out[4]: True

In [5]: x.allowed("/catalogs", "My_crawler") # Should return False, since it's not allowed.
Out[5]: False

In [7]: x.allowed("/catalogs/p?", "My_crawler") # Should return True, since it's allowed.
Out[7]: True

In [8]: x.refresh() # Refresh robots.txt, perhaps a magic change?

In [9]: x.ttl
Out[9]: 3721.3556718826294

瞧!

【讨论】:

以上是关于Python robotsparser 模块不会加载“robots.txt”的主要内容,如果未能解决你的问题,请参考以下文章

不会吧,不会吧,不会还有人不知道❤️Python给图片加水印❤️超级简单哦

Python小技巧:两行代码实现批量给图片填加水印,这也太简单了

模块和包

python中进程间通讯——文件锁之fcntl模块的使用

python-关于OS模块的一些简单操作

python3--命令行执行加参数