上一節,大概講述了Python 爬蟲的編寫流程, 從這節開始主要解決如何突破在爬取的過程當中限制。好比,IP、JS、驗證碼等。這節主要講利用IP代理突破。java
1.關於代理python
簡單的說,代理就是換個身份。網絡中的身份之一就是IP。好比,咱們身在牆內,想要訪問google、u2b、fb等,直接訪問是404,因此要換個不會被牆的IP,好比國外的IP等。這個就是簡單的代理。linux
在爬蟲中,有些網站可能爲了防止爬蟲或者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的相關資料)app
b).urllib2與urllib的區別在於,urllib2發送請求的時候可攜帶參數(我如今只用到這點區別)socket
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.轉載請註明出處