python掃描proxy並獲取可用代理ip

今天咱寫一個挺實用的工具,就是掃描並獲取可用的proxyhtml

 

首先呢,我先百度找了一個網站:http://www.xicidaili.com 做爲例子app

這個網站裏公佈了許多的國內外可用的代理的ip和端口ide

咱們仍是按照老樣子進行分析,就先把全部國內的proxy掃一遍吧工具

點開國內部分進行審查發現,國內proxy和目錄爲如下url:網站

http://www.xicidaili.com/nn/xurl

這個x差很少兩千多頁,那麼看來又要線程處理了。。。spa

老樣子,咱們嘗試是否能直接以最簡單的requests.get()獲取內容線程

返回503,那麼咱們加一個簡單的headers代理

返回200,成咯code

 

好了咱們先進行網頁內容分析並獲取想要的內容

咱們發現,包含ip信息的內容在<tr>標籤內,因而咱們就能很方便的用bs進行獲取標籤內容

可是咱們隨之又發現,ip、端口、協議的內容分別在提取的<tr>標籤的第2,3,6三個<td>標籤內

因而咱們開始嘗試編寫,一下爲編寫思路:

  處理頁面的時候,是先提取tr標籤,再將tr標籤中的td標籤提取

  因此運用了兩次bs操做,而且第二次使用bs操做時須要進行str處理

  由於咱們得到tr以後,咱們須要其中的2,3,6號的東西,

  可是當咱們用一個for循環輸出的i並不能進行組的操做

  因此咱們乾脆分別對每個td的soup進行第二次操做以後直接提取2,3,6

  提取以後,直接加上.string提取內容便可

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)

這樣,咱們每次循環都能生成對應的proxy字典,以便咱們接下來驗證ip可用性所使用

字典這兒有個注意點,咱們有一個將types變爲小寫的操做,由於在get方法中的proxies中寫入的協議名稱應爲小寫,而網頁抓取的是大寫的內容,因此進行了一個大小寫轉換

 

那麼驗證ip可用性的思路呢

很簡單,咱們使用get,加上咱們的代理,請求網站:

http://1212.ip138.com/ic.asp

這是一個神奇的網站,能返回你的外網ip是什麼

url = 'http://1212.ip138.com/ic.asp'
r = requests.get(url = url,proxies = proxy,timeout = 6)

這裏咱們須要加上timeout去除掉那些等待時間過長的代理,我設置爲6秒

咱們以一個ip進行嘗試,而且分析返回的頁面

返回的內容以下:

<html>

<head>

<meta xxxxxxxxxxxxxxxxxx>

<title> 您的IP地址 </title>

</head>

<body style="margin:0px"><center>您的IP是:[xxx.xxx.xxx.xxx] 來自:xxxxxxxx</center></body></html>

那麼咱們只須要提取出網頁內[]的內容便可

若是咱們的代理可用,就會返回代理的ip

(這裏會出現返回的地址仍是咱們本機的外網ip的狀況,雖然我也不是很清楚,可是我把這種狀況排除,應該仍是代理不可用)

那麼咱們就能進行一個判斷,若是返回的ip和proxy字典中的ip相同,則認爲這個ip是可用的代理,並將其寫入文件

 

咱們的思路就是這樣,最後進行queue和threading線程的處理便可

上代碼:

#coding=utf-8

import requests
import re
from bs4 import BeautifulSoup as bs
import Queue
import threading 

class proxyPick(threading.Thread):
    def __init__(self,queue):
        threading.Thread.__init__(self)
        self._queue = queue

    def run(self):
        while not self._queue.empty():
            url = self._queue.get()

            proxy_spider(url)

def proxy_spider(url):
    headers = {
            .......
        }

    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)
        try:
            proxy_check(proxy,ip)
        except Exception,e:
            print e
            pass

def proxy_check(proxy,ip):
    url = 'http://1212.ip138.com/ic.asp'
    r = requests.get(url = url,proxies = proxy,timeout = 6)

    f = open('E:/url/ip_proxy.txt','a+')

    soup = bs(r.text,'html.parser')
    data = soup.find_all(name = 'center')
    for i in data:
        a = re.findall(r'\[(.*?)\]',i.string)
        if a[0] == ip:
            #print proxy
            f.write('%s'%proxy+'\n')
            print 'write down'
            
    f.close()

#proxy_spider()

def main():
    queue = Queue.Queue()
    for i in range(1,2288):
        queue.put('http://www.xicidaili.com/nn/'+str(i))

    threads = []
    thread_count = 10

    for i in range(thread_count):
        spider = proxyPick(queue)
        threads.append(spider)

    for i in threads:
        i.start()

    for i in threads:
        i.join()

    print "It's down,sir!"

if __name__ == '__main__':
    main()

這樣咱們就能把網站上所提供的能用的代理ip所有寫入文件ip_proxy.txt文件中了

 

但願你們喜歡

謝謝觀看!

相關文章
相關標籤/搜索