Python爬蟲技巧一之設置ADSL撥號伺服器代理
那夜
那是一個寂靜的深夜,科比還沒起床練球,雖然他真的可能不練了。
我廢了好大勁,爬蟲終於寫好了!BUG也全部調通了!心想,終於可以坐享其成了!
泡杯茶,安靜地坐在椅子上看著屏幕上一行行文字在控制台跳出,一條條數據嗖嗖進入我的資料庫,一張張圖片悄悄存入我的硬碟。人生沒有幾個比這更愜意的事情了。
我端起茶杯,抿了一口,靜靜地回味著茶香。
這時,什麼情況!屏幕爆紅了!爆紅了!一口茶的功夫啊喂!
怎麼回事!咋爬不動了,不動了!我用瀏覽器點開那一個個報錯的鏈接,瀏覽器顯示
您的請求過於頻繁,IP已經被暫時封禁,請稍後再試!
沃日,我IP被封了?此時此刻,空氣凝固了,茶也不再香了,請給我一個愛的抱抱啊。
時候不早了,還是洗洗睡吧。
次日
那一晚,輾轉反側難以入睡。
怎麼辦?怎麼辦?如果是你你該怎麼辦?
手動換個IP?得了吧,一會又要封了,還能不能安心睡覺啊?
找免費代理?可行,不過我之前測過不少免費代理IP,一大半都不好用,而且慢。不過可以一直維護一個代理池,定時更新。
買代理?可以可以,不過優質的代理服務商價格可是不菲的,我買過一些廉價的,比如幾塊錢套餐一次提取幾百IP的,算了還是不說了都是淚。
然而最行之有效的方法是什麼?那當然是ADSL撥號!
這是個啥?且聽我慢慢道來。
什麼是ADSL
ADSL (Asymmetric Digital Subscriber Line ,非對稱數字用戶環路)是一種新的數據傳輸方式。它因為上行和下行帶寬不對稱,因此稱為非對稱數字用戶線環路。它採用頻分復用技術把普通的電話線分成了電話、上行和下行三個相對獨立的信道,從而避免了相互之間的干擾。
他有個獨有的特點,每撥一次號,就獲取一個新的IP。也就是它的IP是不固定的,不過既然是撥號上網嘛,速度也是有保障的,用它搭建一個代理,那既能保證可用,又能自由控制撥號切換。
如果你是用的ADSL上網方式,那就不用過多設置了,直接自己電腦調用一個撥號命令就好了,自動換IP,分分鐘解決封IP的事。
然而,你可能說?我家寬頻啊,我連得公司無線啊,我蹭的網上的啊!那咋辦?
這時,你就需要一台VPS撥號主機。
購買伺服器
某度廣告做的那麼好是吧?一搜一片,這點谷歌可是遠遠比不上啊。
於是乎,我就搜了搜,鍵入:撥號伺服器,有什麼騎士互聯啊、無極網路啊、掛機寶啊等等的。我選了個價錢還湊合的,選了個無極網路(這裡不是在打廣告),80一個月的配置,一天兩塊錢多點。
2核、512M內存,10M帶寬。
下面是鏈接:
無極網路撥號VPS
大家覺得有更便宜的更好用請告訴我呀!
接下來開始裝操作系統,進入後台,有一個自助裝系統的頁面。
我裝的CentOS的,在後面設置代理啊,定時任務啊,遠程SSH管理啊之類的比較方便。如果你想用Windows,能配置好代理那也沒問題。
有的小夥伴可能會問了,既然它的IP是撥號變化的,你咋用SSH連?其實服務商提供了一個域名,做了動態解析和埠映射,映射到這台主機的22埠就好了,所以不用擔心IP變化導致SSH斷開的問題。
好了裝好了伺服器之後,服務商提供了一個ADSL的撥號操作過程,用pppoe命令都可以完成,如果你的是Linux的主機一般都是用這個。然後服務商還會給給你一個撥號賬號和密碼。
那麼接下來就是試下撥號了。
服務商會提供詳細的撥號流程說明。
比如無極的是這樣的:
撥號流程
設置好了之後,就有幾個關鍵命令:
pppoe-start 撥號npppoe-stop 斷開撥號npppoe-status 撥號連接狀態n
如果想重新撥號,那就執行stop、start就可以了。
反覆執行,然後查看下ip地址,你會發現撥號一次換一個IP,是不是爽翻了!
好,那接下來就設置代理吧。
設置代理伺服器
之前總是用別人的代理,沒自己設置過吧?那麼接下來我們就來親自搭建HTTP代理。
Linux下搭建HTTP代理,推薦Squid和TinyProxy。都非常好配置,你想用哪個都行,且聽我慢慢道來。
我的系統是CentOS,以它為例進行說明。
Squid
首先利用yum安裝squid
yum -y install squidn
設置開機啟動
chkconfig --level 35 squid onn
修改配置文件
vi /etc/squid/squid.confn
修改如下幾個部分:
http_access allow !Safe_ports #deny改成allownhttp_access allow CONNECT !SSL_ports #deny改成allownhttp_access allow all #deny改成allown
其他的不需要過多配置。
啟動squid
sudo service squid startn
如此一來配置就完成了。
代理使用的埠是3128
TinyProxy
首先添加一下鏡像源,然後安裝
rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpmnyum updatenyum install tinyproxyn
修改配置
vi /etc/tinyproxy/tinyproxy.confn
可以修改埠和允許的IP,如果想任意主機都連接那就把Allow這一行注釋掉。
Port 8888 #預設是8888 Port,你可以更改nAllow 127.0.0.1 #將127.0.0.1改成你自己的IPn#例如你的IP 是1.2.3.4,你改成Allow 1.2.3.4,那只有你才可以連上這個Proxyn#若你想任何IP都可以臉到Proxy在Allow前面打#注釋n
啟動TinyProxy
service tinyproxy startn
好了,兩個代理都配置好了。
你想用那個都可以!
不過你以為這樣就完了嗎?太天真了,我被困擾了好幾天,怎麼都連不上,我還在懷疑是不是我哪裡設置得不對?各種搜,一直以為是哪裡配置有遺漏,後來發現是iptables的鍋,萬惡的防火牆。踩過的的坑,那就不要讓大家踩了,用下面的命令設置下iptables,放行3128和8888埠就好了。
service iptables savensystemctl stop firewalldnsystemctl disable firewalldnsystemctl start iptablesnsystemctl status iptablesnsystemctl enable iptablesn
修改iptables配置
vi /etc/sysconfig/iptablesn
在
-A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPTn
的下面添加兩條規則
-A IN_public_allow -p tcp -m tcp --dport 3128 -m conntrack --ctstate NEW -j ACCEPTn-A IN_public_allow -p tcp -m tcp --dport 8888 -m conntrack --ctstate NEW -j ACCEPTn
如圖所示
保存,然後重啟iptables
sudo service iptabels restartn
輸入
ifconfig得到IP地址,在其他的主機上輸入
curl -x IP:8888 www.baidu.comn
測試一下,如果能出現結果,那就說明沒問題。
如果怎麼配都連不上,那乾脆關了你的防火牆吧。雖然不推薦。
連接代理
接下來才是重頭戲,你咋知道你的伺服器IP現在到底是多少啊?撥一次號IP就換一次,那這還了得?
如果服務商提供了埠映射!那一切都解決了!直接用埠映射過去就好了。然而,我的並沒有。
自力更生,艱苦創業!
首先我研究了一下DDNS服務,也就是動態域名解析。即使你的IP在變化,那也可以通過一個域名來映射過來。
原理簡單而統一:當前撥號主機定時向一個固定的伺服器發請求,伺服器獲取remote_addr就好了,可以做到定時更新和解析。
那麼我找了一下,國內做的比較好的就是花生殼了,然後又找到了DNSPOD的介面解析。
下面簡單說下我的折騰過程,大家可以先不用試,後面有更有效的方法。
花生殼
現在花生殼出到3.0版本了,有免費版和付費版之分,我就試用了一下免費版的。這裡是花生殼的一些配置和下載:
花生殼配置
下載花生殼客戶端之後,會生成SN碼,用這個在花生殼的官網登錄後,會分配給你一個免費的域名。
接下來這個域名就能解析到你的主機了。
DNSPOD
DNSPOD原理也是一樣,不過好處是你可以配置自己的域名。
在GitHub上有腳本可以使用。
腳本鏈接
具體的細節我就不說了,實際上就是定時請求,利用remote_addr更新DNSPOD記錄,做到動態解析。
解析介面
不過!這兩個有個通病!慢!
什麼慢?解析慢!但這不是他們的鍋,因為DNS修改後完全生效就是需要一定的時間,這一秒你撥號了,然後更新了IP,但是域名可能還是解析著原來的IP,需要過幾分鐘才能變過來。這能忍嗎?
我可是在跑爬蟲啊,這還能忍?
自力更生
嗯,V2EX果然是個好地方,逛了一下,收穫不小。
鏈接在此
參考了 abelyao 的思路,自己寫了腳本來獲取IP,保證秒級更新!
此時,你還需要另一台固定IP的主機或者某個雲伺服器,只要是地址固定的就好。在這裡我用了另一台有固定IP的阿里雲主機,當然你如果有什麼新浪雲啊之類的也可以。
那麼現在的思路就是,撥號VPS定時撥號換IP,然後請求阿里雲主機,阿里雲主機獲取VPS的IP地址即可。
撥號VPS做的事情:
定時撥號,定時請求伺服器。使用bash腳本,然後crontab定時執行。
遠程伺服器:
接收請求,獲取remote_addr,保存起來。使用Flask搭建伺服器,接收請求。
廢話少說,上代碼
AutoProxy
功能
由於DDNS生效時間過長,對於爬蟲等一些時間要求比較緊迫的項目就不太適用,為此本項目根據DDNS基本原理來實現實時獲取ADSL撥號主機IP。
基本原理
client文件夾由ADSL撥號客戶機運行。它會定時執行撥號操作,然後請求某個固定地址的伺服器,以便讓伺服器獲取ADSL撥號客戶機的IP,主要是定時bash腳本運行。
server文件夾是伺服器端運行,利用Python的Flask搭建伺服器,然後接收ADSL撥號客戶機的請求,得到remote_addr,獲取客戶機撥號後的IP。
項目結構
server
- config.py 配置文件。
- ip 客戶端請求後獲取的客戶端IP,文本保存。
- main.py Flask主程序,提供兩個介面,一個是接收客戶端請求,然後將IP保存,另外一個是獲取當前保存的IP。
client
- crontab 定時任務命令示例。
- pppoe.sh 撥號腳本,主要是實現重新撥號的幾個命令。
- request.sh 請求伺服器的腳本,主要是實現撥號後請求伺服器的操作。
- reqeust.conf 配置文件。
使用
伺服器
伺服器提供兩個功能,record方法是客戶機定時請求,然後獲取客戶機IP並保存。proxy方法是供我們自己用,返回保存的客戶機IP,提取代理。
克隆項目
git clone https://github.com/Germey/AutoProxy.gitn
修改配置
修改config.py文件
- KEY 是客戶端請求伺服器時的憑證,在client的reqeust.conf也有相同的配置,二者保持一致即可。
- NEED_AUTH 在獲取當前保存的IP(即代理的IP)的時候,為防止自己的主機代理被濫用,在獲取IP的時候,需要加許可權驗證。
- AUTH_USER和AUTH_PASSWORD分別是認證用戶名密碼。
- PORT默認埠,返回保存的結果中會自動添加這個埠,組成一個IP:PORT的代理形式。
運行
cd servernnohup python main.pyn
ADSL客戶機
克隆項目
git clone https://github.com/Germey/AutoProxy.gitn
修改配置
修改reqeust.conf文件
- KEY 是客戶端請求伺服器時的憑證,在server的config.py也有相同的配置,二者保持一致即可。
- SERVER是伺服器項目運行後的地址,一般為http://<伺服器IP>/record。如`http://120.27.14.24/record`。
修改pppoe.sh文件
這裡面寫上重新撥號的幾條命令,記得在前兩行配置一下環境變數,配置上撥號命令所在的目錄,以防出現腳本無法運行的問題。
運行
設置定時任務
crontab -en
輸入crontab的實例命令
*/5 * * * * /var/py/AutoProxy/client/request.sh /var/py/AutoProxy/client/request.conf >> /var/py/AutoProxy/client/request.logn
注意修改路徑,你的項目在哪裡,都統一修改成自己項目的路徑。
最前面的*/5是5分鐘執行一次。
好了,保存之後,定時任務就會開啟。
驗證結果
這樣一來,訪問伺服器地址,就可以得到ADSL撥號客戶機的IP了。
import requestsnnurl = http://120.27.14.24:5000nproxy = requests.get(url, auth=(admin, 123)).textnprint(proxy)n
實例結果:
116.208.97.22:8888n
擴展
如果你有域名,可以自己解析一個域名,這樣就可以直接請求自己的域名,拿到實時好用的代理了,而且定時更新。
代理設置
urllib2
import urllib2nproxy_handler = urllib2.ProxyHandler({"http": http:// + proxy})nopener = urllib2.build_opener(proxy_handler)nurllib2.install_opener(opener)nresponse = urllib2.urlopen(http://httpbin.org/get)nprint response.read()n
requests
import requestsnproxies = {nhttp: http:// + proxy,n}nr = requests.get(http://httpbin.org/get, proxies=proxies)nprint(r.text)n
以上便秒級解決了動態IP解析,自己實現了一遍DDNS,爽!
那這樣以來,以後就可以直接請求你的主機獲取一個最新可用的代理IP了,穩定可用,定時變化!
以上便是ADSL撥號伺服器配置的全過程,希望對大家有幫助!
作者:崔慶才
出處:崔慶才的個人博客
最近很多人私信問我問題,平常知乎評論看到不多,如果沒有及時回復,大家也可以加小編微信:tszhihu,進知乎大數據分析挖掘交流群,可以跟各位老師互相交流。謝謝。
推薦閱讀:
※從零開始寫Python爬蟲 --- 3.2 爬蟲實踐:獲取快代理
※python 高度魯棒性爬蟲的異常和超時問題
※基於微博數據用 Python 打造一顆「心」
※第100篇文章紀念(? ?_?)?
※4行Python代碼獲取所在城市天氣預報