1. 程式人生 > >通過Python利用ADSL伺服器和tinyproxy構建資料自己的動態代理IP池,用django+redis做web服務 (優化版)

通過Python利用ADSL伺服器和tinyproxy構建資料自己的動態代理IP池,用django+redis做web服務 (優化版)

代理池初始版:https://blog.csdn.net/MeteorCountry/article/details/82085238

上一篇文章中所搭建的代理池在使用過程中出現了點小問題,代理池中莫名的多出了一些無效代理,檢查日誌後返現是在更新代理

池時舊的代理IP沒有刪除成功,就添加了新的代理IP。究其原因是因為在請求刪除介面時網路已斷開導致多次請求失敗,跳過了

刪除這一步驟,進行了重撥、更新,於是對 ADSL 伺服器端的程式碼進行了修改,又增加了日誌功能,程式碼如下:

#!/usr/bin/python3
import re,time,os,requests,json,datetime,random

only = 'only1'
log_list = []

#獲取時間
def getTime():
    numtime = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S---')
    return numtime

#寫入日誌
def write_log():
    with open('proxy.log','a') as f:
        for i in log_list:
            f.write(i+'\n')
        f.write('\n')
        f.close()

#切換IP,重啟代理服務
def changeIP():
    os.system('pppoe-stop')
    time.sleep(4)
    os.popen('service tinyproxy stop')
    os.popen('pppoe-start')
    time.sleep(7)
    os.popen('service tinyproxy start')

#取出當前IP
def extractIP():
    infor = os.popen('pppoe-status').read()
    try:
        ip = re.search('(\d+\.\d+\.\d+\.\d+)',infor).group(1)
        return ip
    except Exception as e:
        log_list.append(getTime()+'提取IP錯誤:'+str(e))
        return False

def updateDel():
    url = 'http://*.*.*.*:8000/proxy/updateDel?&only={0}'.format(only)
    #是否刪除成功
    state = False
    for i in range(2):
        try:
            res = requests.get(url,timeout=3)
            infor = json.loads(res.text)
            if infor['state']:
                log_list.append(getTime() + '刪除舊IP成功')
                state = True
                break
            else:
                log_list.append(getTime() + '刪除IP失敗')
        except Exception as e:
            log_list.append(getTime() + '刪除IP失敗:'+str(e))
            continue
    return state

def updatePut(ip):
    ip = ip+':'+'8888'
    url = 'http://*.*.*.*:8000/proxy/updatePut?ip={0}&only={1}'.format(ip,only)
    for i in range(3):
        try:
            res = requests.get(url,timeout=3)
            infor = json.loads(res.text)
            if infor['state']:
                break
            else:
                log_list.append(getTime() + '更新IP失敗')
        except Exception as e:
            log_list.append(getTime() + '更新IP失敗'+str(e))
            continue

if __name__ == '__main__':
    a = 1
    while True:
        if a==2:
            time.sleep(random.randrange(45,70))
        a=2
        state = updateDel()
        time.sleep(2)
        while True:
            #重新連線
            changeIP()
            #取出當前IP
            ip = extractIP()
            if ip:
                break
        #請求代理池中舊IP失敗,此處重新請求刪除介面
        if not state:
            log_list.append(getTime() + '第二次執行刪除舊IP方法')
            updateDel()
        updatePut(ip)
        log_list.append(getTime()+'已經更新IP:{0}'.format(ip))
        write_log()
        log_list = []

 

截止到現在,新的代理池用了三臺 ADSL 伺服器(每臺伺服器每分鐘提供一個代理IP,每個IP可以支援20個併發對請求速度無影響),已使用一星期,再無異常。

 

本文原創,如需轉載請註明來源。

注 : 網路爬蟲要儘量減小對被爬取網站影響, 如在被爬取網站每天訪問量較小的時間段去爬取,一切為了和平發展。