背景調(diào)研:
在爬取一個(gè)網(wǎng)站之前,首先需要對目標(biāo)站點(diǎn)的規(guī)模、結(jié)構(gòu)進(jìn)行了解。網(wǎng)站自身的rotbots.txt和Sitemap文件都可以為我們提供幫助
1.rotbots協(xié)議檢查
大多數(shù)網(wǎng)站都會定義rotbots.txt文件,這樣可以讓爬蟲爬取時(shí)了解網(wǎng)站存在那些限制,這些限制僅僅作為建議給出,但是作為良好的網(wǎng)絡(luò)公民應(yīng)該予以準(zhǔn)守。并且檢查rotbots協(xié)議可以防止爬蟲被封禁。
2.識別網(wǎng)站所用的技術(shù)
構(gòu)建網(wǎng)站的技術(shù),也會影響爬蟲的使用,python提供了builtwith模塊,該模塊將url作為參數(shù),下載后進(jìn)行分析,然后返回網(wǎng)站使用的技術(shù)。
pip install builtwith
例:
import builtwith
????html_1 = builtwith.parse('http://www.itdecent.cn/')
????print(html_1)
3.尋找網(wǎng)站作者
對于一些網(wǎng)站,你可能會想知道作者是誰,python提供了python-whois庫
pip install python-whois
import whois
print(whois.whois('http://www.itdecent.cn/'))
4.編寫第一個(gè)網(wǎng)絡(luò)爬蟲
為了抓取網(wǎng)站,我們首先需要下載包含信息的網(wǎng)頁,該過程稱為“爬?。╟rawling)”。
import urllib.request
def download_url(url):
????return urllib.request.urlopen(url).read()
當(dāng)url傳入時(shí),該函數(shù)會下載并返回HTML,但是該函數(shù)使用時(shí),可能會出現(xiàn)問題,比如請求的頁面不存在,這時(shí)程序退出拋出異常,安全起見,讓它變得更健壯。
健壯后
import urllib.request
from? urllibimport? error
def download_url(url):
????print('Download',url)
????try:
????????html =? urllib.request.urlopen(url).read()
????except urllib.error.URLErroras e:
????????print('download error',e.reason)
????????html =None
? ? ? ? return html
現(xiàn)在下載時(shí),出現(xiàn)問題,函數(shù)可以捕獲,然后返回None
5.重試下載
下載時(shí),遇到的錯(cuò)誤往往是臨時(shí)性的,比如服務(wù)器過載返回503,對于這樣的情況,需要重新請求下載,但是如果返回404找不到頁面,重新請求也是沒有用。所以我們確保5xx的情況下重新請求即可:
import urllib.request?
from urllib import errordef download(url,num_retries=2):
????print('download',url)
????try:
????????html = urllib.request.urlopen(url).read()
????except urllib.error.URLErroras e:
????????print('download error',e.reason)
????????html =None
? ? ? ? if num_retries >0:
????????????if hasattr(e,'code')and 500 <= e.code <=600:
????????????????return download(url,num_retries-1)
????return html
現(xiàn)在當(dāng)函數(shù)執(zhí)行遇到code為5xx時(shí),將會遞歸調(diào)用函數(shù)本身進(jìn)行重試,并且添加了重新下載的次數(shù),默認(rèn)值為2次。
6.設(shè)置用戶代理
為了讓下載更加可靠,可以控制代理設(shè)定,我們重新對download函數(shù)進(jìn)行修改,設(shè)定一個(gè)代理,這次使用默認(rèn)代“wswp”,即“web Scraping with Python”。
def download(url,user_agent='wswp',num_retries=2):
????print('download',url)
????headers = {'user_agent':user_agent}
????request = urllib.request.Request(url,headers=headers)
????try:
????????html = urllib.request.urlopen(request).read()
????except urllib.error.URLErroras e:
????????print('download error',e.reason)
????????html =None
? ? ? ? if num_retries >0:
????????????if hasattr(e,'code')and 500<=e.code <=600:
????????????????return download(url,user_agent,num_retries-1)
????return html
現(xiàn)在我們擁有了靈活下載的函數(shù),該函數(shù)可以捕獲異常、重新請求下載、設(shè)置用戶代理。