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。如`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代碼獲取所在城市天氣預報

TAG:Python | 爬虫 | Python入门 |