1. 程式人生 > >python爬蟲(5)——正則表達式(二)

python爬蟲(5)——正則表達式(二)

org handle uil urlopen 意思 esp 下載 header 因此

    前一篇文章,我們使用re模塊來匹配了一個長的字符串其中的部分內容。下面我們接著來作匹配“[email protected] advantage 314159265358 1892673 3.14 little Girl try_your_best 56 [email protected] python3”

    我們的目標是匹配‘56’,其中\d表示匹配數字,{2}表示匹配次數為兩次,{M,N},M,N均為非負整數,M<=N,表示匹配M-N次。在匹配規則前面加個r的意思是表示原生字符串。

技術分享圖片

    實際上我們在使用正則表達式的時候,通常先將其編譯成pattern對象,使用re.compile()方法來進行編譯。下面我們來匹配IP地址如:192.168.1.1。

   

1 import re
2 
3 str=192.168.1.1
4 
5 re.search(r(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5]),str)

 技術分享圖片

    可以看出來,正則使用起來並不簡單。在上面的規則中,我們是用了三個子組,如果我們在網頁上用findall匹配所有IP,它會把結果給分類了,變成(‘192’,‘168’,‘1’,‘1’)。顯然這不是我們想要的。這時候,我們需要用(?:...)來表示非捕獲組,即該子組匹配的字符串無法從後面獲取。

    有了之前的基礎,我嘗試著寫下了如下的代碼,從西刺代理網站上爬取IP地址,並用代理訪問網站驗證其是否可用。當中用到了python的異常處理機制。雖然代碼不成熟,但還是分享出來,慢慢改進。

 1 import urllib.request
 2 import re
 3 
 4 
 5 url="http://www.xicidaili.com/"
 6 useful_ip=[]
 7 def loadPage(url):
 8     headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36"}
 9     response=urllib.request.Request(url,headers=headers)
10 html=urllib.request.urlopen(response).read().decode("utf-8") 11 return html 12 13 def getProxy(): 14 html=loadPage(url) 15 pattern=re.compile(r(<td>\d+</td>)) 16 duankou=pattern.findall(html) 17 pattern=re.compile(r(?:(?:[01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}(?:[01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])) 18 content_list=pattern.findall(html) 19 list_num=[] 20 for num in duankou: 21 list_num.append(num[4:-5]) 22 for i in range(len(list_num)): 23 ip=content_list[i]+ ":"+list_num[i] 24 while True: 25 proxy_support=urllib.request.ProxyHandler({http:ip}) 26 opener=urllib.request.build_opener(proxy_support) 27 opener.add_handler=[("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36")] 28 urllib.request.install_opener(opener) 29 try: 30 print("正在嘗試使用 %s 訪問..." % ip) 31 ip_filter="http://www.whatsmyip.org/" 32 ip_response=urllib.request.urlopen(ip_filter) 33 except urllib.error.URLError: 34 print("訪問出錯,這個IP不能用啦") 35 break 36 else: 37 print("訪問成功!") 38 print("可用IP為: %s " % ip) 39 useful_ip.append(ip) 40 if input("繼續爬取?")=="N": 41 print("有效IP如下:") 42 for key in useful_ip: 43 print(key) 44 exit() 45 else: 46 break 47 48 if __name__=="__main__": 49 getProxy()

    在處理IP地址對應的端口號時,我用的一個非常笨的方法。實際上有更好的辦法解決,大家也可以想一想。在上面這段代碼中,使用urllib訪問網站、Handler處理器自定義opener、python異常處理、正則匹配ip等一系列的知識點。任何知識,用多了才會熟練。

技術分享圖片

    可以看到它運行成功,並且找到一個可用IP後會問你是否繼續爬取。當然,我們可以手動構建一個IPPOOL即IP池,自定義一個函數,把可以用的IP寫入一個文件保存起來,這裏就不作贅述了。在github上有成熟的ip池代碼,大家可以下載下來閱讀,這裏只是把前面講的一些用法做一個簡單的試驗,因此並沒有把這段代碼完善。

python爬蟲(5)——正則表達式(二)