python standard library urllib robotparser

python 标准库 urllib.robotparser

一切终将过去,我们仍旧前行,如同黑暗中的舞者。

​ – 临风语录

源码

源代码: Lib/urllib/robotparser.py

robotparser 实现了一个用于分析 robots.txt 文件格式的解析器, 它含有一个检查给定用户代理是否可以访问给定资源的函数。它的目的是给那些品行端正的爬虫用的,或用来指导需要节流,否则就会被限制访问的其他抓取器。

robots.txt

robots.txt 文件是一个简单的基于文本的访问控制系统,用于控制那些自动访问网络资源的程序(如「爬虫」,「抓取器」,等等)。文件由特定的用户代理程序标识的记录以及代理不允许访问的 URLs (或 URL 前缀) 的一个列表组成。

以我的博客为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# hexo robots.txt
User-agent: *
Allow: /
Allow: /archives/

Disallow: /vendors/
Disallow: /js/
Disallow: /css/
Disallow: /fonts/
Disallow: /vendors/
Disallow: /fancybox/

Sitemap: https://pinghailinfeng.gitee.io/sitemap.xml
Sitemap: https://pinghailinfeng.gitee.io/baidusitemap.xml

允许所有爬虫访问内容

1
2
3
User-Agent:  *
Allow: /
Allow: /archives/

不允许爬虫访问的内容

1
2
3
4
5
6
Disallow: /vendors/
Disallow: /js/
Disallow: /css/
Disallow: /fonts/
Disallow: /vendors/
Disallow: /fancybox/

函数

class urllib.robotparser.RobotFileParser(url=’’)

核心类通过下面方法读取、解析 通过url访问的robots.txt文件

  • set_url(url)

    设定需要读取 robots.txt文件url路径

  • read()

    读取制定URL路径对应的 robots.txt 文件

  • parse(lines)

    解析参数指定的行

  • can_fetch(useragent, url)

    如果useragent被允许抓取url对应的robots.txt文件中包含了允许的规则,则返回True

  • mtime()

    返回最后一次抓取robots.txt文件的时间。这是一个对长时间运行的网络爬虫用检查周期性robots.txt文件是否更新的很有用的方法。

  • modified()

    设定最后一次抓取 robots.txt 文件的时间。

  • crawl_delay(useragent)

    返回 从robots.txtuseragent定义的 Crawl-delay 的值。如果没有这个参数或 在useragent中声明的参数格式不正确,返回None

    3.6 新版功能.

  • request_rate(useragent)

    返回作为命名元组类型的从 robots.txt 文件中 定义的 Request-rate参数内容。如果没有这个参数或在 robots.txt 文件中定义的useragent参数格式不正确,则返回None

    3.6 新版功能.

  • site_maps()

    返回 list() 类型的Sitemap参数内容。如果参数不存在或参数格式不正确,都返回None

官方栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> import urllib.robotparser
>>> rp = urllib.robotparser.RobotFileParser()
>>> rp.set_url("http://www.musi-cal.com/robots.txt")
>>> rp.read()
>>> rrate = rp.request_rate("*")
>>> rrate.requests
3
>>> rrate.seconds
20
>>> rp.crawl_delay("*")
6
>>> rp.can_fetch("*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco")
False
>>> rp.can_fetch("*", "http://www.musi-cal.com/")
True

分析知乎

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
"""
分析知乎 Robots 协议
"""
import urllib.robotparser


rp = urllib.robotparser.RobotFileParser()

# 设置 robots.txt 文件 URL
rp.set_url('https://www.zhihu.com/robots.txt')

# 读取操作必须有, 不然后面解析不到
rp.read()

# 判断网址是否运行爬取
print(rp.can_fetch('Googlebot', 'https://www.zhihu.com/question/264161961/answer/278828570'))
print(rp.can_fetch('*', 'https://www.zhihu.com/question/264161961/answer/278828570'))

# 返回上次抓取分析 robots.txt 时间
print(rp.mtime())

# 将当前时间设置为上次抓取和分析 robots.txt 的时间
rp.modified()
print(rp.mtime()) # 再次打印时间会有变化

# 返回 robots.txt 文件对请求速率限制的值
print(rp.request_rate('*'))
print(rp.request_rate('MSNBot').requests)

# 返回 robotx.txt 文件对抓取延迟限制的值
print(rp.crawl_delay('*'))
print(rp.crawl_delay('MSNBot'))

分析我自己博客

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import urllib.robotparser

blog_url = 'https://pinghailinfeng.gitee.io/robots.txt'
rp = urllib.robotparser.RobotFileParser()

# 设置 robots.txt 文件 URL
rp.set_url(blog_url)

# 读取操作必须有, 不然后面解析不到
rp.read()

# 判断网址是否运行爬取
print(rp.can_fetch('*','https://pinghailinfeng.gitee.io/archives/'))


# 返回上次抓取分析 robots.txt 时间
print(rp.mtime())

# 将当前时间设置为上次抓取和分析 robots.txt 的时间
rp.modified()
print(rp.mtime()) # 再次打印时间会有变化


>>> print(rp.crawl_delay('*'))
>>> print(rp.site_maps())

>>> True
>>> 1580804333.889091
>>> 1580804333.889091
>>> None
>>> ['https://pinghailinfeng.gitee.io/sitemap.xml', 'https://pinghailinfeng.gitee.io/baidusitemap.xml']
坚持原创技术分享,您的支持将鼓励我继续创作!