關于robots協議
Robots協議(也稱為爬蟲協議、機器人協議等)的全稱是“網絡爬蟲排除標準”(Robots Exclusion Protocol),網站通過Robots協議告訴搜索引擎哪些頁面可以抓取,哪些頁面不能抓取。
Robots協議是國際互聯網界通行的道德規范,基于以下原則建立:1、搜索技術應服務于人類,同時尊重信息提供者的意愿,并維護其隱私權;2、網站有義務保護其使用者的個人信息和隱私不被侵犯。
Robots協議用來告知搜索引擎哪些頁面能被抓取,哪些頁面不能被抓取;可以屏蔽一些網站中比較大的文件,如:圖片,音樂,視頻等,節省服務器帶寬;可以屏蔽站點的一些死鏈接。方便搜索引擎抓取網站內容;設置網站地圖連接,方便引導蜘蛛爬取頁面。
robots.txt文件應該放置在網站根目錄下。舉例來說,當spider訪問一個網站時,首先會檢查該網站中是否存在robots.txt這個文件,如果 Spider找到這個文件,它就會根據這個文件的內容,來確定它訪問權限的范圍。
如今,在中國國內互聯網行業,正規的大型企業也都將Robots協議當做一項行業標準,國內使用Robots協議最典型的案例,就是淘寶網拒絕百度搜索、京東拒絕一淘搜索。不過,絕大多數中小網站都需要依靠搜索引擎來增加流量,因此通常并不排斥搜索引擎,也很少使用Robots協議。
robots語法
語法 | 描述 |
---|---|
User-agent: * | 這里的代表的所有的搜索引擎種類,是一個通配符 |
Disallow: /admin/ | 這里定義是禁止爬尋admin目錄下面的目錄 |
Disallow: /require/ | 這里定義是禁止爬尋require目錄下面的目錄 |
Disallow: /ABC/ | 這里定義是禁止爬尋ABC目錄下面的目錄 |
Disallow: /cgi-bin/*.htm | 禁止訪問/cgi-bin/目錄下的所有以".htm"為后綴的URL(包含子目錄)。 |
Disallow: /? | 禁止訪問網站中所有包含問號 (?) 的網址 |
Disallow: /.jpg$ | 禁止抓取網頁所有的.jpg格式的圖片 |
Disallow:/ab/adc.html | 禁止爬取ab文件夾下面的adc.html文件。 |
Allow: /cgi-bin/ | 這里定義是允許爬尋cgi-bin目錄下面的目錄 |
Allow: /tmp | 這里定義是允許爬尋tmp的整個目錄 |
Allow: .htm$ | 僅允許訪問以".htm"為后綴的URL。 |
Allow: .gif$ | 允許抓取網頁和gif格式圖片Sitemap: 網站地圖 告訴爬蟲這個頁面是網站地圖 |
解析robot
用法:
1、rp = robotparser.RobotFileParser() 獲取一個解析器對象。
2、rp.set_url("robot file url") 設置robot文件的地址。
3、rp.read() 從網上下載robot文件。
4、rp.can_fetch(user_agent, url) 返回某個user_agent是否有url的訪問權限,若無權限,則不能爬取該url。
import urllib.request
import urllib.parse
import re
import urllib.robotparser
def download(url, headers={}, retryCount=5):
"""
下載頁面
:param url: 要下載的鏈接
:param headers: 偽造頭
:param retryCount: 如果是服務器錯誤,需要嘗試的次數
:return:
"""
# 請求頭對象
request = urllib.request.Request(url, headers=headers)
try:
# 返回數據
response = urllib.request.urlopen(request)
except urllib.error.URLError as e:
# 判斷是否為服務器錯誤
if hasattr(e, 'code') and 500 <= e.code < 600:
# 重試幾次
if retryCount > 0:
return download(url, headers, retryCount-1)
# 最終下載失敗
return None
return response.read()
def get_link(html):
"""
得到頁面中的鏈接
:param html: 頁面數據
:return: 返回鏈接列表
"""
webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']', re.IGNORECASE)
return webpage_regex.findall(html)
def link_spider(start_link, link_regex):
"""
鏈接爬蟲函數
:param start_link: 開始下載的鏈接
:param link_regex: 需要的部分鏈接
:return:
"""
# 等待下載的鏈接的列表
wait_download_link = [start_link]
# 解析鏈接,分析域名
urlObj = urllib.parse.urlparse(start_link)
# 判斷是否滿足robot協議,獲取一個解析器對象
rp = urllib.robotparser.RobotFileParser()
# 設置robot文件的地址
rp.set_url('http://127.0.0.1:8080/robots.txt')
# 從網上下載robot文件
rp.read()
# 定義一個集合,用來過濾掉重復的鏈接
crawled_link = set()
while wait_download_link:
# 從所有等待下載的連接列表中彈出一個鏈接
url = wait_download_link.pop()
# 返回某個user-agent是否有url的訪問權限,若沒有權限,則不能爬取
if rp.can_fetch('myspider', url):
# 下載url鏈接的頁面
html = download(url)
# 如果沒有頁面數據,則跳出本次循環重新開始
if html is None:
continue
# 將下載過的鏈接放入已經下載過的鏈接集合中
crawled_link.add(url)
# 利用正則表達式篩選出頁面所有的鏈接
all_link = get_link(html.decode('utf-8'))
# 遍歷鏈接
for link in all_link:
# 篩選出自己需要的鏈接
if re.match(link_regex, link):
# 得到完整的有用鏈接
realUrl = urlObj.scheme + '://' + urlObj.netloc + link
# 判斷鏈接是否已經下載過
if realUrl not in crawled_link:
wait_download_link.append(realUrl)
else:
print('不能爬取該網頁!!')
continue
link_spider('http://127.0.0.1:8080/places/default/index', '/places/default/view/|/places/default/index/')