編寫爬蟲竟然成了“面向監獄編程”,就是因為不懂Robots協議
編寫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
本文轉載自微信公眾號「極客起源」,可以通過以下二維碼關注。轉載本文請聯系極客起源公眾號。