若是使用spider抓取同一網站的多個頁面可能會致使IP被封(或者觸發相似的機制),可使用代理proxy解決這一問題。在使用代理以前咱們須要瞭解opener和handler。html
urllib.request使用opener打開url,而opener實際是使用handler進行處理。因此咱們通常先建立一個handler,在使用build_opener一個opener,以後就可使用這個opener打開url,或者使用install_opener安裝opener。cookie
下面就是一個簡單的例子:app
1 import re 2 import urllib.request 3 4 5 def Spider(url): 6 proxy = urllib.request.ProxyHandler({'http':'IP:PORT'}) 7 opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler) 8 urllib.request.install_opener(opener) 9 req = urllib.request.Request(url, headers = { 10 "Connection": "Keep-Alive", 11 "Accept": "text/html, application/xhtml+xml, */*", 12 "Accept-Language": "en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3", 13 "User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko"}) 14 page=urllib.request.urlopen(req).read().decode("UTF-8") 15 pat='(http://pan\.baidu\.com/s/[\da-zA-Z]{6,8})' 16 s=re.findall(pat,page) 17 pat_='(密碼(.?)(\s)?([\da-zA-Z]{4}))' 18 s_=re.findall(pat_,page) 19 if s: 20 if s_: 21 print(s[0]) 22 print(s_[0][0]) 23 else: 24 print("提取碼沒有抓到") 25 else: 26 print("提取網址沒有抓到") 27 28 if __name__ =="__main__": 29 url="網址" 30 Spider(url)
除了使用代理proxy,咱們還能夠經過cookie handler模擬登錄。ide
一般咱們須要分析目標網站的登錄流程,不一樣的網站可能流程不同。post
如下是知乎的登錄流程:網站
使用HTTPfox檢測一次登錄流程,咱們能夠發現上面有一條post指令,在看看發送的內容:ui
咱們須要得到一串_xsrf字符串,而這個能夠從知乎首頁中獲取。下面就開始演示如何使用cookie登錄知乎了。url
1 import urllib.request 2 import http.cookiejar 3 import gzip 4 import re 5 6 def Get_xsrf(html): 7 pat='name="_xsrf"\svalue="(.*?)"/>' 8 s=re.findall(pat,html) 9 return s[0] 10 11 12 def Degzip(page): 13 try: 14 print("正在解壓.....") 15 html= gzip.decompress(page) 16 print("解壓完畢!") 17 except: 18 print("無需解壓") 19 return html 20 21 def Getopener(): 22 cj=http.cookiejar.CookieJar() 23 cookie=urllib.request.HTTPCookieProcessor(cj) 24 opener=urllib.request.build_opener(cookie) 25 header=[] 26 head= { 27 'Connection': 'Keep-Alive', 28 'Accept': 'text/html, application/xhtml+xml, */*', 29 'Accept-Language': 'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3', 30 'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko', 31 'Accept-Encoding': 'gzip, deflate', 32 'Host': 'www.zhihu.com', 33 'DNT': '1'} 34 for key, value in head.items(): 35 elem = (key, value) 36 header.append(elem) 37 opener.addheaders = header 38 return opener 39 40 41 def Spider(url): 42 opener=Getopener() 43 data=opener.open(url).read() 44 html=Degzip(data).decode("UTF-8") 45 xsrf=Get_xsrf(html) 46 47 url+="login" 48 ID="帳號" 49 PASSWORD="密碼" 50 postDict = { 51 '_xsrf':xsrf, 52 'email': ID, 53 'password': PASSWORD, 54 'rememberme': 'y'} 55 postData=urllib.parse.urlencode(postDict).encode("UTF-8") 56 data=opener.open(url,postData).read() 57 html=Degzip(data).decode("UTF-8") 58 59 pat='<span class="name">(.*?)</span>' 60 s=re.findall(pat,html) 61 print(s[0]) 62 63 64 if __name__=="__main__": 65 url = 'http://www.zhihu.com/' 66 Spider(url)
最後spider會抓取知乎的登錄用戶名並輸出。spa