编写爬虫竟然成了“面向监狱编程”,就是因为不懂Robots协议(爬虫协议)

2021-03-29 15:26:28 浏览数 (1)

编写Python爬虫很容易,不过要想安全地编写Python爬虫,就需要了解更多的至少,不光是技术上的,还有法律上的,Robots协议就是其中之一,如果不了解Robots协议,抓取了不该抓取的东西,可能会面临牢狱之灾哦!

1. Robots协议简介

Robots协议也称作爬虫协议、机器人协议,它的全名是网络爬虫排除标准(Robots Exclusing Protocol),用来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以抓取。该协议的内容通常放在一个名为robots.txt的文本文件中,该文件一般位于网站的根目录下。

注意,robots.txt文件中的内容只是告诉爬虫应该抓取什么,不应该抓取什么,但并不是通过技术手段阻止爬虫抓取那些被禁止的资源,而只是通知爬虫而已。尽管编写爬虫可以不遵循robots.txt文件的描述,但作为一只有道德、有文化、有纪律的爬虫,应该尽量遵循robots.txt文件描述的规则。否则,有可能会引起法律纠纷。

当爬虫访问一个网站时,首先会检查这个网址根目录下是否存在robots.txt文件,如果存在,爬虫就会根据该文件中定义的抓取范围来抓取Web资源。如果这个文件并不存在,爬虫就会抓取这个网站所有可直接访问的页面。

下面来看一个robots.txt文件的例子:

代码语言:javascript复制
User-agent:*Disallow:/Allow:/test/

这个抓取规则首先告诉爬虫对所有的爬虫有效,而且除了test目录外的任何资源都不允许抓取。如果将这个robots.txt文件放在某个网站的根目录,那么搜索引擎的爬虫就会只抓取test目录下的资源,我们会发现搜索引擎中再也查不到其他目录下的资源了。

上面的User-agent描述了爬虫的名字,这里将其设置为*,则表示对所有的爬虫有效,我们还可以特指某些爬虫,如下面的设置明确指定百度爬虫。

代码语言:javascript复制
User-agent:BaiduSpider

robots.txt文件中有2个重要的授权指令:Disallow和Allow,前者表示禁止抓取,后者表示运行抓取。也就是说,Disallow是黑名单,Allow是白名单。 例如,下面是一些Robots协议的例子。

1. 禁止所有爬虫抓取网站所有的资源

代码语言:javascript复制
User-agent:*Disallow:/

2. 禁止所有爬虫抓取网站/private和/person目录中的资源

代码语言:javascript复制
User-agent: *Disallow: /private/Disallow:/person/

3. 只禁止百度爬虫抓取网站资源

代码语言:javascript复制
User-agent:BaiduSpiderDisallow:/

很多搜索引擎的爬虫都有特定的名称,表1列出了一些常用的爬虫名称。

表1 常用的爬虫名称

爬虫名称

搜索引擎

网站

Googlebot

谷歌

www.google.com

BaiduSpider

百度

www.baidu.com

360Spider

360搜索

www.so.com

Bingbot

必应

www.bing.com

2. 分析Robots协议

Robots协议并不需要我们自己去分析,urllib库的robotparser模块提供了相应的API来解析robots.txt文件,这就是RobotFileParser类。可以用多种方式使用RobotFileParser类。例如,可以通过set_url方法设置robots.txt文件的URL,然后进行分析,代码如下:

代码语言:javascript复制
form urllib.robotparser import RobotFileParserrobot = 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方法判断是否可以抓取某一个页面。

代码语言:javascript复制
robot = RobotFileParser('https://www.jd.com/robots.txt')print(robot.can_fetch('*','https://www.jd.com/test.js'))

下面的案例使用了parse方法指定robots.txt文件的数据,并输出不同的URL是否允许抓取,这是另外一种使用RobotFileParser类的方式。

代码语言:javascript复制
from urllib.robotparser import RobotFileParserfrom urllib import requestrobot = 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'))# 输出Trueprint(robot.can_fetch('*','https://www.jd.com'))# 输出Trueprint(robot.can_fetch('*','https://www.jianshu.com/p/92f6ac2c350f'))# 输出Falseprint(robot.can_fetch('*','https://www.jianshu.com/search?q=Python&page=1&type=note'))

运行结果如下:

代码语言:javascript复制
TrueTrueFalse

- EOF -

推荐阅读 点击标题可跳转

就凭这3点,可以完全理解Python的类方法与静态方法

卧槽,好强大的魔法,竟能让Python支持方法重载

Python装饰器(decorator)不过如此,是我想多了

这样合并Python字典,可以让程序的运行效率提高4倍

Python字典不是不可以排序,是你方法没用对!

文件侠告诉你,Python复制文件的N种姿势!

Python代码可以加密吗?Python字节码告诉你!

使出Python的六脉神剑,让Python拥有无限扩展性

看我用元类(metaclass)花式创建Python类

你不知道__name__变量是什么意思吗?

Python生成器(Generator)最完美解释

0 人点赞