今天咱寫一個挺實(shí)用的工具,就是掃描并獲取可用的proxy
首先呢,我先百度找了一個網(wǎng)站:http://www.xicidaili.com 作為例子
這個網(wǎng)站里公布了許多的國內(nèi)外可用的代理的ip和端口
我們還是按照老樣子進(jìn)行分析,就先把所有國內(nèi)的proxy掃一遍吧
點(diǎn)開國內(nèi)部分進(jìn)行審查發(fā)現(xiàn),國內(nèi)proxy和目錄為以下url:
http://www.xicidaili.com/nn/x
這個x差不多兩千多頁,那么看來又要線程處理了。。。
老樣子,我們嘗試是否能直接以最簡單的requests.get()獲取內(nèi)容
返回503,那么我們加一個簡單的headers
返回200,成咯
好了我們先進(jìn)行網(wǎng)頁內(nèi)容分析并獲取想要的內(nèi)容
我們發(fā)現(xiàn),包含ip信息的內(nèi)容在<tr>標(biāo)簽內(nèi),于是我們就能很方便的用bs進(jìn)行獲取標(biāo)簽內(nèi)容
但是我們隨之又發(fā)現(xiàn),ip、端口、協(xié)議的內(nèi)容分別在提取的<tr>標(biāo)簽的第2,3,6三個<td>標(biāo)簽內(nèi)
于是我們開始嘗試編寫,一下為編寫思路:
處理頁面的時候,是先提取tr標(biāo)簽,再將tr標(biāo)簽中的td標(biāo)簽提取
所以運(yùn)用了兩次bs操作,并且第二次使用bs操作時需要進(jìn)行str處理
因為我們獲得tr之后,我們需要其中的2,3,6號的東西,
但是當(dāng)我們用一個for循環(huán)輸出的i并不能進(jìn)行組的操作
所以我們干脆分別對每一個td的soup進(jìn)行第二次操作之后直接提取2,3,6
提取之后,直接加上.string提取內(nèi)容即可
r = requests.get(url = url,headers = headers) soup = bs(r.content,"html.parser") data = soup.find_all(name = 'tr',attrs = {'class':re.compile('|[^odd]')}) for i in data: soup = bs(str(i),'html.parser') data2 = soup.find_all(name = 'td') ip = str(data2[1].string) port = str(data2[2].string) types = str(data2[5].string).lower() proxy = {} proxy[types] = '%s:%s'%(ip,port)這樣,我們每次循環(huán)都能生成對應(yīng)的proxy字典,以便我們接下來驗證ip可用性所使用
字典這兒有個注意點(diǎn),我們有一個將types變?yōu)樾懙牟僮鳎驗樵趃et方法中的proxies中寫入的協(xié)議名稱應(yīng)為小寫,而網(wǎng)頁抓取的是大寫的內(nèi)容,所以進(jìn)行了一個大小寫轉(zhuǎn)換
那么驗證ip可用性的思路呢
很簡單,我們使用get,加上我們的代理,請求網(wǎng)站:
http://1212.ip138.com/ic.asp
這是一個神奇的網(wǎng)站,能返回你的外網(wǎng)ip是什么
url = 'http://1212.ip138.com/ic.asp'r = requests.get(url = url,proxies = proxy,timeout = 6)
這里我們需要加上timeout去除掉那些等待時間過長的代理,我設(shè)置為6秒
我們以一個ip進(jìn)行嘗試,并且分析返回的頁面
返回的內(nèi)容如下:
<html><head><meta xxxxxxxxxxxxxxxxxx><title> 您的IP地址 </title></head><body style="margin:0px"><center>您的IP是:[xxx.xxx.xxx.xxx] 來自:xxxxxxxx</center></body></html>
新聞熱點(diǎn)
疑難解答
圖片精選