编写Python爬虫很容易,不过要想安全地编写Python爬虫,就需要了解更多的至少,不光是技术上的,还有法律上的,Robots协议就是其中之一,如果不了解Robots协议,抓取了不该抓取的东西,可能会面临牢狱之灾哦!
1. Robots协议简介
Robots协议也称作爬虫协议、机器人协议,它的全名是网络爬虫排除标准(Robots Exclusing Protocol),用来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以抓取。该协议的内容通常放在一个名为robots.txt的文本文件中,该文件一般位于网站的根目录下。
注意,robots.txt文件中的内容只是告诉爬虫应该抓取什么,不应该抓取什么,但并不是通过技术手段阻止爬虫抓取那些被禁止的资源,而只是通知爬虫而已。尽管编写爬虫可以不遵循robots.txt文件的描述,但作为一只有道德、有文化、有纪律的爬虫,应该尽量遵循robots.txt文件描述的规则。否则,有可能会引起法律纠纷。
当爬虫访问一个网站时,首先会检查这个网址根目录下是否存在robots.txt文件,如果存在,爬虫就会根据该文件中定义的抓取范围来抓取Web资源。如果这个文件并不存在,爬虫就会抓取这个网站所有可直接访问的页面。下面来看一个robots.txt文件的例子:
- User-agent:*
- Disallow:/
- Allow:/test/
这个抓取规则首先告诉爬虫对所有的爬虫有效,而且除了test目录外的任何资源都不允许抓取。如果将这个robots.txt文件放在某个网站的根目录,那么搜索引擎的爬虫就会只抓取test目录下的资源,我们会发现搜索引擎中再也查不到其他目录下的资源了。
上面的User-agent描述了爬虫的名字,这里将其设置为*,则表示对所有的爬虫有效,我们还可以特指某些爬虫,如下面的设置明确指定百度爬虫。
- User-agent:BaiduSpider
robots.txt文件中有2个重要的授权指令:Disallow和Allow,前者表示禁止抓取,后者表示运行抓取。也就是说,Disallow是黑名单,Allow是白名单。 例如,下面是一些Robots协议的例子。
1. 禁止所有爬虫抓取网站所有的资源
- User-agent:*
- Disallow:/
2. 禁止所有爬虫抓取网站/private和/person目录中的资源
- User-agent: *
- Disallow: /private/
- Disallow:/person/
3. 只禁止百度爬虫抓取网站资源
- User-agent:BaiduSpider
- Disallow:/
很多搜索引擎的爬虫都有特定的名称,表1列出了一些常用的爬虫名称。
表1 常用的爬虫名称
2. 分析Robots协议
Robots协议并不需要我们自己去分析,urllib库的robotparser模块提供了相应的API来解析robots.txt文件,这就是RobotFileParser类。可以用多种方式使用RobotFileParser类。例如,可以通过set_url方法设置robots.txt文件的URL,然后进行分析,代码如下:
- form urllib.robotparser import RobotFileParser
- robot = RobotFileParser()
- robot.set_url('https://www.jd.com/robots.txt')
- robot.read()
- print(robot.can_fetch('*','https://www.jd.com/test.js'))
其中can_fetch方法用来获得该网站某一个URL根据Robots协议是否有权抓取,如果可以抓取,返回True,否则返回False。
RobotFileParser类的构造方法也可以接受一个URL,然后使用can_fetch方法判断是否可以抓取某一个页面。
- robot = RobotFileParser('https://www.jd.com/robots.txt')
- print(robot.can_fetch('*','https://www.jd.com/test.js'))
下面的案例使用了parse方法指定robots.txt文件的数据,并输出不同的URL是否允许抓取,这是另外一种使用RobotFileParser类的方式。
- from urllib.robotparser import RobotFileParser
- from urllib import request
- robot = RobotFileParser()
- url = 'https://www.jianshu.com/robots.txt'
- headers = {
- 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
- 'Host': 'www.jianshu.com',
- }
- req = request.Request(url=url, headers=headers)
- # 抓取robots.txt文件的内容,并提交给parse方法进行分析
- robot.parse( request.urlopen(req).read().decode('utf-8').split('\n'))
- # 输出True
- print(robot.can_fetch('*','https://www.jd.com'))
- # 输出True
- print(robot.can_fetch('*','https://www.jianshu.com/p/92f6ac2c350f'))
- # 输出False
- print(robot.can_fetch('*','https://www.jianshu.com/search?q=Python&page=1&type=note'))
运行结果如下:
- True
- True
- False
本文转载自微信公众号「极客起源」,可以通过以下二维码关注。转载本文请联系极客起源公众号。