轉載:使用Tornado+Redis維護ADSL撥號服務器代理池

咱們嘗試維護過一個免費的代理池,可是代理池效果用過就知道了,畢竟裏面有大量免費代理,雖然這些代理是可用的,可是既然咱們能刷到這個免費代理,別人也能呀,因此就致使這個代理同時被不少人使用來抓取網站,因此當咱們興致勃勃地拿他來抓取某個網站的時候,會發現它仍是被網站封禁的狀態,因此在某些狀況下免費代理池的成功率仍是比較低的。html

固然咱們也能夠去購買一些代理,好比幾塊錢提取幾百幾千個的代理,然而通過測試後質量也是很通常,也能夠去購買專線代理,不過價格也是不菲的。那麼目前最穩定並且又保證可用的代理方法就是設置ADSL撥號代理了。git

本篇來說解一下ADSL撥號代理服務器的相關設置。github

什麼是ADSL

你們可能對ADSL比較陌生,ADSL全稱叫作Asymmetric Digital Subscriber Line,非對稱數字用戶環路,由於它的上行和下行帶寬不對稱。它採用頻分複用技術把普通的電話線分紅了電話、上行和下行三個相對獨立的信道,從而避免了相互之間的干擾。web

有種主機叫作動態撥號VPS主機,這種主機在鏈接上網的時候是須要撥號的,只有撥號成功後才能夠上網,每撥一次號,主機就會獲取一個新的IP,也就是它的IP並非固定的,並且IP量特別大,幾乎不會撥到相同的IP,若是咱們用它來搭建代理,既能保證高度可用,又能夠自由控制撥號切換。redis

經測試發現這也是最穩定最有效的代理方式,本節詳細介紹一下ADSL撥號代理服務器的搭建方法。數據庫

購買動態撥號VPS主機

因此在開始以前,咱們須要先購買一臺動態撥號VPS主機,這樣的主機在百度搜索一下,服務商仍是至關多的,在這裏推薦一家雲立方,感受仍是比較良心的,非廣告。api

配置的話能夠自行選擇,看下帶寬是否能夠知足需求就行了。安全

購買完成以後,就須要安裝操做系統了,進入撥號主機的後臺,首先預裝一個操做系統。服務器

在這裏推薦安裝CentOS7系統。網絡

而後找到遠程管理面板找到遠程鏈接的用戶名和密碼,也就是SSH遠程鏈接服務器的信息。

好比我這邊的IP端口分別是 153.36.65.214:20063,用戶名是root。

命令行下輸入:

 

 

 

而後輸入管理密碼,就能夠鏈接上遠程服務器了。

進入以後,能夠發現有一個可用的腳本文件,叫作ppp.sh,這是撥號初始化的腳本,運行它會讓咱們輸入撥號的用戶名和密碼,而後它就會開始各類撥號配置,一次配置成功,後面的撥號就不須要重複輸入用戶名和密碼了。

運行ppp.sh腳本,輸入用戶名密碼等待它的配置完成。

都提示成功以後就能夠進行撥號了。

在撥號以前若是咱們測試ping任何網站都是不通的,由於當前網絡還沒聯通,輸入撥號命令:

 

 

能夠發現撥號命令成功運行,沒有任何報錯信息,這就證實撥號成功完成了,耗時約幾秒鐘。接下來若是再去ping外網就能夠通了。

若是要中止撥號能夠輸入:

 

 

中止以後,能夠發現又連不通網絡了。

因此只有撥號以後才能夠創建網絡鏈接。

因此斷線重播的命令就是兩者組合起來,先執行adsl-stop再執行adsl-start,每撥一次號,ifocnfig命令觀察一下主機的IP,發現主機的IP一直是在變化的,網卡名稱叫作ppp0。

因此,到這裏咱們就能夠知道它做爲代理服務器的巨大優點了,若是將這臺主機做爲代理服務器,若是咱們一直撥號換IP,就不怕遇到IP被封的狀況了,即便某個IP被封了,從新撥一次號就行了。

因此接下來咱們要作的就有兩件事,一是怎樣將主機設置爲代理服務器,二是怎樣實時獲取撥號主機的IP。

設置代理服務器

以前咱們常常據說代理服務器,也設置過很多代理了,可是可能沒有本身設置吧,本身有一臺主機怎樣設置爲代理服務器呢?接下來咱們就親自試驗下怎樣搭建HTTP代理服務器。

在Linux下搭建HTTP代理服務器,推薦TinyProxy和Squid,配置都很是簡單,在這裏咱們以TinyProxy爲例來說解一下怎樣搭建代理服務器。

安裝TinyProxy

固然第一步就是安裝TinyProxy這個軟件了,在這裏我使用的系統是CentOS,因此使用yum來安裝,若是是其餘系統如Ubuntu能夠選擇apt-get等命令安裝,都是相似的。

命令行執行yum安裝指令:

 

 

運行完成以後就能夠完成tinyproxy的安裝了。

配置TinyProxy

安裝完成以後還須要配置一下TinyProxy才能夠用做代理服務器,須要編輯配置文件,它通常的路徑是/etc/tinyproxy/tinyproxy.conf

能夠看到有一行

 

 

在這裏能夠設置代理的端口,默認是8888。

而後繼續向下找,有這麼一行

 

 

這是被容許鏈接的主機的IP,若是想任何主機均可以鏈接,那就直接將它註釋便可,因此在這裏咱們選擇直接註釋,也就是任何主機均可以使用這臺主機做爲代理服務器了。

修改成

 

 

設置完成以後重啓TinyProxy便可。

 

 

驗證TinyProxy

好了,這樣咱們就成功搭建好代理服務器了,首先ifconfig查看下當前主機的IP,好比當前個人主機撥號IP爲112.84.118.216,在其餘的主機運行測試一下。

好比用curl命令設置代理請求一下httpbin,檢測下代理是否生效。

 

 

若是有正常的結果輸出而且origin的值爲代理IP的地址,就證實TinyProxy配置成功了。

好,那到如今,咱們接下來要作的就是須要動態實時獲取主機的IP了。

動態獲取IP

真正的好戲纔開始呢,咱們怎樣動態獲取主機的IP呢?可能你首先想到的是DDNS也就是動態域名解析服務,咱們須要使用一個域名來解析,也就是雖然IP是變的,但域名解析的地址能夠隨着IP的變化而變化。

它的原理實際上是撥號主機向固定的服務器發出請求,服務器獲取客戶端的IP,而後再將域名解析到這個IP上就能夠了。

國內比較有名的服務就是花生殼了,也提供了免費版的動態域名解析,另外DNSPOD也提供瞭解析接口來動態修改域名解析設置,DNSPOD,可是這樣的方式都有一個通病,那就是慢!

緣由在於DNS修改後到徹底生效是須要必定時間的,因此若是在前一秒撥號了,這一秒的域名解析的可能仍是原來的IP,時間長的話可能須要幾分鐘,也就是說這段時間內,服務器IP已經變了,可是域名仍是上一次撥號的IP,因此代理是不能用的,對於爬蟲這種秒級響應的需求,是徹底不能接受的。

因此根據花生殼的原理,能夠徹底本身實現一下動態獲取IP的方法。

因此本節重點介紹的就是怎樣來實現實時獲取撥號主機IP的方法。

要實現這個須要兩臺主機,一臺主機就是這臺動態撥號VPS主機,另外一臺是具備固定公網IP的主機。動態VPS主機撥號成功以後就請求遠程的固定主機,遠程主機獲取動態VPS主機的IP,就能夠獲得這個代理,將代理保存下來,這樣撥號主機每撥號一次,遠程主機就會及時獲得撥號主機的IP,若是有多臺撥號VPS,也統一發送到遠程主機,這樣咱們只須要從遠程主機取下代理就行了,保準是實時可用,穩定高效的。

總體思路大致是這樣子,固然爲了更完善一下,咱們要作到以下功能:

遠程主機:

  • 監聽主機請求,獲取動態VPS主機IP
  • 將VPS主機IP記錄下來存入數據庫,支持多個客戶端
  • 檢測當前接收到的IP可用狀況,若是不可用則刪除
  • 提供API接口,經過API接口可獲取當前可用代理IP

撥號VPS:

  • 定時執行撥號腳本換IP
  • 換IP後當即請求遠程主機
  • 撥號後檢測是否撥號成功,若是失敗當即從新撥號

遠程主機實現

說了這麼多,那麼咱們就梳理一下具體的實現吧,整個項目咱們用Python3實現。

數據庫

遠程主機做爲一臺服務器,動態撥號VPS會定時請求遠程主機,遠程主機接收到請求後將IP記錄下來存入數據庫。
由於IP是一直在變化的,IP更新了以後,原來的IP就不能用了,因此對於一個主機來講咱們可能須要屢次更新一條數據。另外咱們不能僅限於維護一臺撥號VPS主機,固然是須要支持多臺維護的。在這裏咱們直接選用Key-Value形式的非關係型數據庫存儲更加方便,因此在此選用Redis數據庫。

既然是Key-Value,Key是什麼?Value是什麼?首先咱們能肯定Value就是代理的值,好比112.84.119.67:8888,那麼Key是什麼?咱們知道,這個IP是針對一臺動態撥號VPS的,並且這個值會不斷地變,因此咱們須要有一個不變量Key來惟一標識這臺主機,因此在這裏咱們能夠把Key當作主機名稱。名稱怎麼來?本身取就行了,只要每臺主機的名字不重複,咱們就能夠區分出是哪臺主機了,這個名字能夠在撥號主機那邊指定,而後傳給遠程主機就行了。

因此,在這裏數據庫咱們選用Redis,Key就是撥號主機的名稱,能夠本身指定,Value就是代理的值。

因此能夠寫一個操做Redis數據庫的類,參考以下:

 

 

首先初始化Redis鏈接,咱們能夠將Key設計成adsl:vm1這種形式,冒號前面是總的key,冒號後面是主機名稱name,這樣顯得結構更加清晰。

而後指定set()和get()方法,用來存儲代理和獲取代理。

請求處理

撥號主機會一直向遠程主機發送請求,遠程主機固然能夠獲取撥號主機的IP,可是代理端口是沒法得到的,咱們在撥號主機上設置了TinyProxy或者Squid,可是服務器不知道是在哪一個端口開的,因此端口也是須要客戶端傳給遠程主機的。遠程主機接收到請求後,將解析獲得的IP和端口合併就能夠做爲完整的代理保存了。

因此如今咱們知道撥號主機須要傳送給遠程主機的信息已經有兩個了,一是撥號主機自己的名稱,二是代理的端口。

通訊祕鑰

爲了保證遠程主機不被惡意的請求干擾,能夠設置一個傳輸祕鑰,最簡單的方式能夠兩者共同規定一個祕鑰字符串,撥號主機在傳送這個字符串,遠程主機匹配一下,若是能正確匹配,那就進行下一步的處理,若是不能匹配,那麼多是惡意請求,就忽略這個請求。

固然確定有更好的加密傳輸方式,但爲了方便起見能夠用如上來作。

因此客戶機還須要傳送一個數據,那就是通訊祕鑰,一共須要傳送三個數據。

因此咱們須要架設一個服務器,一直監聽客戶端的請求,在這裏咱們用tornado實現。

tornado的安裝也很是簡單,利用pip安裝便可:

 

 

定義一個處理撥號主機請求的方法,在這裏咱們使用post請求,參考以下。

 

 

遠程主機獲取請求的token,也就是上面咱們所說的通訊密鑰,保證安全。port是撥號機的代理端口,name是撥號主機的名稱。而後咱們再獲取請求的remote_ip,也就是撥號主機的IP。而後將IP和端口拼合就能夠獲得撥號主機的完整代理信息了,將其存入數據庫便可。

代理檢測

在遠程主機端咱們須要作一下代理檢測,若是某個代理不可用了,會及時將其去除,以避免出現獲取到代理後不可用的狀況。

注意:在這裏在撥號主機端驗證是不夠的,由於可能忽然遇到某個撥號主機宕機的狀況,這樣撥號主機就不會再向遠程主機發送請求,而最後一次獲得的代理還會存在於數據庫中,因此在遠程主機端統一驗證比較科學。

驗證方式能夠定時檢測,也能夠每收到一次請求檢測一次,用獲取到的代理來請求某個網站,檢測一下是否能訪問便可。若是不能,將其從數據庫中刪除。

API

遠程主機已經將撥號主機的IP和端口保存下來了,那也就是說,全部的可用的代理已經在遠程主機保存了,咱們須要提供一個接口來將代理獲取下來。

好比咱們能夠提供這麼幾個方法,獲取全部代理,獲取最新代理,獲取隨機代理等等。

 

 

而後用tornado搭建API服務,若是能夠的話還能夠綁定一個域名,更加便捷,舉例以下:

獲取隨機代理:

獲取最新代理:

獲取全部代理:

請求接口獲取可用代理便可,好比獲取一個隨機代理:

 

 

這樣咱們拿到的IP都是穩定可用的,並且過段時間從新請求取到的IP就會變化,是一直動態變化的高可用代理。

撥號VPS實現

定時撥號

撥號VPS須要每隔一段時間就撥號一次,咱們能夠直接執行命令行來撥號,那在Python裏咱們只須要調用一下這個撥號命令就行了。利用subprocess模塊調用腳本便可,在這裏定義一個變量ADSL_BASH爲adsl-stop;adsl-start,這就是撥號的腳本。

 

 

經過getstatusoutput方法能夠獲取腳本的執行狀態和輸出結果,若是status爲0,則證實撥號成功,而後檢測一下撥號接口是否獲取了IP地址。

執行ifconfig命令能夠獲取當前的IP,我這臺主機接口名稱叫作ppp0,固然網卡名稱能夠本身指定,因此將ppp0接口的IP提取出來便可。

 

 

若是方法正常返回IP,則證實IP存在,撥號成功,接下來向遠程主機發送請求便可,而後sleep一段時間從新再次撥號。

若是方法返回的值爲空,那證實IP不存在,咱們須要從新撥號。

請求遠程主機

發送的時候須要攜帶這麼幾個信息,一個是通訊祕鑰,一個是代理端口,另外一個是主機的標識符,用requests發送便可。

 

 

因此總體的思路實現能夠寫成這樣子:

 

 

這樣咱們就能夠作到定時撥號並向遠程主機發送請求了。

代碼

Talk is cheap, show me the code! 在這裏提供一份完整代碼實現,其中client模塊是在動態VPS主機運行,server模塊在遠程主機運行,具體的操做使用能夠參考README。

ADSLProxyPool

轉載請註明:靜覓 » 使用Tornado+Redis維護ADSL撥號服務器代理池

相關文章
相關標籤/搜索