上一節,大概講述了Python 爬蟲的編寫流程, 從這節開始主要解決如何突破在爬取的過程中限制。比如,IP、JS、驗證碼等。這節主要講利用IP代理突破。
1.關於代理
簡單的說,代理就是換個身份。網絡中的身份之一就是IP。比如,我們身在牆內,想要訪問google、u2b、fb等,直接訪問是404,所以要換個不會被牆的IP,比如國外的IP等。這個就是簡單的代理。
在爬蟲中,有些網站可能為了防止爬蟲或者DDOS等,會記錄每個IP的訪問次數,比如,有些網站允許一個IP在1s(或者別的)只能訪問10次等,那么我們就需要訪問一次換一個IP(具體什么策略,自己決定)。
那么問題來了,這些代理從哪得到?對於公司來講,買代理IP。但是對於個人的話,可能會有浪費。那么怎么辦呢?網上有很多免費的代理IP網站,但是手動更改的話,很浪費時間,並且免費的IP有很多不可用。所以,我們可以用爬蟲爬那么IP。用上一節的代碼,完全可以做到。這里我們用http://www.xicidaili.com/nn/1測試,聲明:僅學習交流,切勿用作商業用途等
2.獲取代理IP,代碼如下:
#encoding=utf8 import urllib2 import BeautifulSoup User_Agent = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0' header = {} header['User-Agent'] = User_Agent url = 'http://www.xicidaili.com/nn/1' req = urllib2.Request(url,headers=header) res = urllib2.urlopen(req).read() soup = BeautifulSoup.BeautifulSoup(res) ips = soup.findAll('tr') f = open("../src/proxy","w") for x in range(1,len(ips)): ip = ips[x] tds = ip.findAll("td") ip_temp = tds[2].contents[0]+"\t"+tds[3].contents[0]+"\n" # print tds[2].contents[0]+"\t"+tds[3].contents[0] f.write(ip_temp)
代碼說明:
a).這里我們使用的urllib2模塊,因為,這個請求有點特殊,服務器會驗證請求中的header(如有疑問,可參考http的相關資料)
b).urllib2與urllib的區別在於,urllib2發送請求的時候可攜帶參數(我現在只用到這點區別)
c).open()用於打開文件,第一個參數是文件的路徑可以填絕對路徑,例如E:\\proxy("\"在編程中是特殊字符,要用"\\"代表實際的"\")。也可以是相對路徑,比 如"../src/proxy",就是文件相對於代碼的位置。第二個參數"w",代表打開文件的權限,w代表寫權限,r代表讀權限。這個在很多系統中都通用。比如,linux等
d).for循環,如果之前學過java或者其他高級語言,可能不太習慣,因為他們用的是for(;;)這樣的。python中的for循環,in 表示X的取值,按順序取到in后面的參數
特別注意:別忘了for語句后面的冒號(":")
c).range函數,代表生成一系列數,如果range(0,6,1),意思就是從0開始,到6結束(不包括6),每次增加1(也就是步長為1),生成一個數組,結果就是[0, 1, 2, 3, 4, 5]
e).f.write()就是往文件里面寫數據,如果打開文件的時候,沒有"w"權限,則無法寫入。
頁面截圖:

運行結果:

3.並不是所有的代理都能用,原因有很多,可能是我們所處的網絡連不到這個代理,也有可能是這個代理,連不到我們的目標網址,所以,我們要驗證一下。以http://ip.chinaz.com/getip.aspx作為目標網址為例(這個是測試ip地址的網址)代碼如下:
#encoding=utf8 import urllib import socket socket.setdefaulttimeout(3) f = open("../src/proxy") lines = f.readlines() proxys = [] for i in range(0,len(lines)): ip = lines[i].strip("\n").split("\t") proxy_host = "http://"+ip[0]+":"+ip[1] proxy_temp = {"http":proxy_host} proxys.append(proxy_temp) url = "http://ip.chinaz.com/getip.aspx" for proxy in proxys: try: res = urllib.urlopen(url,proxies=proxy).read() print res except Exception,e: print proxy print e continue
代碼說明:
a).ip = lines[i].strip("\n").split("\t") 這個是去掉每行末尾的換行符(也就是"\n"),然后以制表符(也就是"\t")分割字符串為字符串數組
b).proxy_temp = {"http":proxy_host}其中http代表代理的類型,除了http之外還有https,socket等這里就以http為例
c).urllib.urlopen(url,proxies=proxy) 其中proxies就是代理。以代理模式訪問目標網址
d).socket.setdefaulttimeout(3)設置全局超時時間為3s,也就是說,如果一個請求3s內還沒有響應,就結束訪問,並返回timeout(超時)
運行結果如圖:

從結果看可用的並不是很多。但是也夠個人用了。
至此,IP代理的使用就結束了。
備注:
1.代碼僅供學習交流,切勿用作商業用途
2.代碼如有問題,多多指教
3.轉載請注明出處
