Linux IP代理篩選系統(shell+proxy)

來源:互聯網
上載者:User

上一篇部落格,介紹了Linux 抓取網頁的執行個體,其中在抓取google play國外網頁時,需要用到Proxy 伺服器

代理的用途

其實,除了抓取國外網頁需要用到IP代理外,還有很多情境會用到代理:

  • 通過代理訪問一些國外網站,繞過被某國防火牆過濾掉的網站
  • 使用教育網的Proxy 伺服器,可以訪問到大學或科研院所的內部網站資源
  • 利用設定代理,把請求通過Proxy 伺服器下載快取後,再傳回本地,提高訪問速度
  • 駭客發動攻擊時,可以通過使用多重代理來隱藏原生IP地址,避免被跟蹤(當然,魔高一尺,道高一丈,終究會被traced)

代理的原理

代理服務的原理是本地瀏覽器(Browser)發送請求的資料,不是直接發送給網站伺服器(Web Server)

而是通過中間的Proxy 伺服器(Proxy)來代替完成,如:

IP代理篩選系統

問題分析

  • 因為不可能每天都遍曆測試全球2^32數量級的IP地址,來看哪個IP可用,因此首要工作就是尋找待選的代理IP源?
  • 初步確定了待選代理IP源,如何確定這裡面的每一個IP是真的可用?
  • 尋找到的待選代理IP源,是以什麼格式儲存的?需要進行文本預先處理嗎?
  • 選擇並確定了某個代理IP可用,但在下載網頁過程中可能會又突然失效了,如何繼續抓取剩下的網頁?
  • 如果重新選擇了一個可用的代理IP完成了剩下的網頁抓取,為了方便下次使用,需要將它更新到12國抓取指令碼中,該如何?呢?
  • 上篇部落格中提到過,在抓取遊戲排名網頁和遊戲網頁的過程中,都需要使用代理IP來下載網頁,如果遇到上面的代理IP突然失效,該如何解決?
  • 如果一個代理IP並沒有失效,但是它抓取網頁的速度很慢或極慢,24小時內無法完成對應國家的網頁抓取任務,該怎麼辦?需要重新篩選一個更快的嗎?
  • 如果把所有代理IP源篩選一遍後,仍然沒有一個可用的代理IP,該怎麼辦?是繼續迴圈再篩選一次或多次,還是尋找新的代理IP源?

分析解決一個實際問題時,將會遇到各種問題,有些問題甚至是方案設計之初都難以想到的(如代理IP抓取網頁速度過慢),我的體會是:動手實踐比純理論更重要!

方案設計

總體思路:尋找並縮小篩選的IP代理源——》檢測代理IP是否可用——》IP可用則記錄下來抓取網頁——》代理IP故障則重新篩選——》繼續抓取網頁——》完成

1、IP代理源

選擇有兩個原則:可用和免費,經過深入調研和搜尋,最後確定兩個網站的IP代理比較靠譜:freeproxylists.net 和 xroxy.com

從國家數、IP代理數量、IP代理可用率、IP代理文字格式設定等多方面綜合考量,IP代理源主要選自前者,後者作為補充,在後來的實踐測試表明這種初選方案基本滿足需求

2、文本預先處理

從freeproxylists.net擷取的代理IP,有IP地址、連接埠、類型、匿名性、國家...等等參數,而我們需要的僅僅是IP+Port,因此需要對初選的IP代理源做文本預先處理

文本空格處理命令:

        sed -e "s/\s\{2,\}/:/g" $file_input > $file_split
        sed -i "s/ /:/g" $file_split

合并代理IP(ip:port)命令:

        proxy_ip=$(echo $line | cut -f 1 -d ":")
        proxy_port=$(echo $line | cut -f 2 -d ":")
        proxy=$proxy_ip":"$proxy_port

3、檢測IP代理

文本預先處理代理IP為標準格式(ip:port)後,需要進行代理IP篩選測試,看哪些可用哪些不可用(由於擷取的IP代理源有一些不能使用或下載過慢,需要過濾掉)

curl抓取網頁檢測IP代理是否可用命令:

cmd="curl -y 60 -Y 1 -m 300 -x $proxy -o $file_html$index $url_html"

$cmd

4、儲存IP代理

檢測一個代理IP是否可用,如果可用,則儲存下來。

判斷一個代理IP是否可用的標準,是通過判斷步驟3中下載的網頁($file_html$index)是否有內容,具體命令如下:

        if [ -e ./$file_html$index ]; then
            echo $proxy >> $2
            break;
        fi

5、IP代理抓取網頁

利用步驟4儲存的代理IP抓取網頁,通過代理IP抓取12國排名網頁和遊戲網頁,具體命令如下:

    proxy_cmd="curl -y 60 -Y 1 -m 300 -x $proxy -o $proxy_html $proxy_http"
    $proxy_cmd

6、IP代理故障

IP代理故障有多種情況,在上面的問題分析中已經列出了幾條,下面將詳細分析如下:

a、代理IP在抓取的網頁過程中,突然失效,無法繼續完成網頁抓取

b、代理IP沒有失效,但是抓取網頁很慢,無法在一天24小時內完成網頁抓取,導致無法產生遊戲排名每日報表

c、代理IP全部失效,無論是輪詢檢測一遍或多遍後,都無法完成當天的網頁抓取任務

d、由於整個網路路由擁塞,導致代理IP抓取網頁很慢或無法抓取,誤判為代理IP全部失效,如何恢複和糾正

7、重新檢測IP代理

在網頁抓取過程中,面對步驟6的IP代理故障,設計一套合理、高效的代理IP抓取恢複機制,是整個IP代理篩選系統的核心和關鍵

其故障恢複的輪詢篩選流程如下:

流程中,需要注意幾點:

a、首先檢測上次IP代理,這是因為上次(昨天)的IP代理完成了所有網頁抓取任務,其可用機率相對比較高,所以優先考慮其今天是否也可用。如果不可用,則另選其它

b、如果上次代理IP今天不可用,則重新遍曆檢測代理IP源,一旦檢測到有可用,則不再迴圈下去,更新可用IP代理並儲存其在IP源的位置,方便下次從此處開始遍曆

c、如果流程b新選的代理IP突然失效或網速過慢,則在b記錄的IP源位置繼續篩選後面的代理IP是否可用。如可用,則繼續抓取網頁;如不可用,則再次遍曆整個IP源

d、如果再次遍曆了整個代理IP源,仍然沒有代理IP可用,則反覆輪詢遍曆整個代理IP源,直到有代理IP可用或今天24時過去(即今日整天都找不到可用代理IP)

e、對流程d中全部代理IP失效且整日找不到可用代理IP,無法完成當日網頁抓取這一特殊情況,在次日淩晨重新啟動網頁抓取總控指令碼前,需要先殺死流程d在背景迴圈進程,防止今日和次日的兩個後台網頁抓取程式同時運行(相當於兩個非同步後台抓取進程),造成抓取網頁排名資料陳舊或錯誤、佔用網速頻寬等。其實現殺死當日僵死的後台抓取進程,請見上一篇部落格 Linux 抓取網頁執行個體 ——》 自動化總控指令碼 ——》kill_curl.sh指令碼,其原理是kill -9 進程號,關鍵指令碼代碼如下:

while [ ! -z $(ps -ef | grep curl | grep -v grep | cut -c 9-15) ]
do
    ps -ef | grep curl | grep -v grep | cut -c 15-20 | xargs kill -9
    ps -ef | grep curl | grep -v grep | cut -c 9-15 | xargs kill -9
done

8、完成網頁抓取

通過上述的IP代理篩選系統,篩選出12國可用的免費代理IP,完成每日12國網頁排名和遊戲網頁的抓取任務

之後,就是對網頁中遊戲屬性資訊的進行提取、處理,產生每日報表、郵件定時發送和趨勢圖查詢等,詳見我的上一篇部落格:Linux 抓取網頁執行個體

指令碼功能實現

IP代理篩選的基本過程比較簡單,其資料格式和實現步驟如下:

首先,到 freeproxylists.net 網站,收集可用的代理IP源(以美國為例),其格式如下:

接著,清除中的空格,具體實現命令請見上面【方案設計】——》【2、文本預先處理】,文本預先處理後的格式如下:

然後,測試文本預先處理後的代理IP是否可用具體命令請見上面【方案設計】——》【3、檢測IP代理】,檢測代理IP後的格式如下:

下面介紹shell指令碼實現文本預先處理和網頁篩選的詳細步驟

1、文本預先處理

# file processlog='Top800proxy.log'dtime=$(date +%Y-%m-%d__%H:%M:%S)function select_proxy(){    if [ ! -d $dir_split ]; then        mkdir $dir_split    fi    if [ ! -d $dir_output ]; then        mkdir $dir_output    fi    if [ ! -e $log ]; then        touch $log    fi    echo "================== Top800proxy $dtime ==================" >> $log     for file in `ls $dir_input`; do        echo $file >> $log        file_input=$dir_input$file        echo $file_input >> $log        file_split=$dir_split$file"_split"        echo $file_split >> $log        rm -rf $file_split        touch $file_split        sed -e "s/\s\{2,\}/:/g" $file_input > $file_split        sed -i "s/ /:/g" $file_split        file_output=$dir_output$file"_out"        echo $file_output >> $log        proxy_output "$file_split" "$file_output"        echo '' >> $log    done    echo '' >> $log}

指令碼功能說明:

if語句,判斷並建立用於儲存處理IP源中間結果的檔案夾$dir_split 和 $dir_output ,前者儲存【指令碼功能實現】中文本預先處理後的文字格式設定,後者儲存檢測後可用的代理IP

sed -e語句,把輸入文本(指令碼功能實現的圖1)中的多個空格,修改為一個字元“:”

sed -i語句,進一步把文本中的多餘空格,轉換為一個字元":"

轉換的中間結果,都儲存到檔案夾 $dir_split 

後面的file_output三行,以檔案參數的形式"$file_split",傳給代理IP檢測函數(proxy_output),篩選出可用的代理IP

2、代理IP篩選

index=1file_html=$dir_output"html_"cmd=''function proxy_output(){    rm -rf $2    touch $2    rm -rf $file_html*    index=1    while read line    do        proxy_ip=$(echo $line | cut -f 1 -d ":")        proxy_port=$(echo $line | cut -f 2 -d ":")        proxy=$proxy_ip":"$proxy_port        echo $proxy >> $log        cmd="curl -y 60 -Y 1 -m 300 -x $proxy -o $file_html$index $url_html"        echo $cmd >> $log        $cmd        if [ -e ./$file_html$index ]; then            echo $proxy >> $2            break;        fi        index=`expr $index + 1`    done < $1    rm -rf $file_html*}

指令碼功能說明:

代理IP篩選函數proxy_output頭三行,清除先前篩選的結果,作用是初始化

while迴圈,主要是遍曆以參數形式傳入的文本預先處理後的"$file_split",檢測代理IP是否可用,其步驟如下:

a、首先拼接出代理IP的(ip:port)格式,其實現是通過cut分割文本行,然後提取出第一個欄位(ip)和第二個欄位(port),拼接成(ip:port)

b、通過curl構造出抓取網頁的命令cmd,執行網頁下載命令$cmd

c、通過檢測網頁下載命令執行後,是否產生了網頁下載檔案,來判斷拼接出的代理IP($proxy)是否有效。若有效,則儲存此代理IP到"$file_output"中並退出遍曆(break)

d、如果當前代理IP無效,則讀取下一行代理IP,繼續檢測

代理IP抓取網頁執行個體:

利用上面的代理IP系統,篩選出來免費代理IP,抓取遊戲排名網頁的執行個體如下(指令碼片段):

index=0    while [ $index -le $TOP_NUM ]    do        url=$url_start$index$url_end        url_cmd='curl -y 60 -Y 1 -m 300 -x '$proxy' -o '$url_output$index' '$url        echo $url_cmd        date=$(date "+%Y-%m-%d___%H-%M-%S")        echo $index >> $log        echo $url"___________________$date" >> $log        $url_cmd        # done timeout file        seconds=0        while [ ! -f $url_output$index ]        do            sleep 1            echo $url_output$index"________________no exist" >> $log            $url_cmd            seconds=`expr $seconds + 1`            echo "seconds____________"$seconds >> $log            if [ $seconds -ge 5 ]; then                select_proxy                url_cmd='curl -y 60 -Y 1 -m 300 -x '$proxy' -o '$url_output$index' '$url                seconds=0            fi        done        index=`expr $index + 24`    done

指令碼功能說明:

上面shell指令碼程式碼片段,是用來抓取網頁的,其中最核心的一行是 select_proxy 

其作用是上述介紹過的,當代理IP突然失效、抓取網頁過慢、全部代理IP都無效、或無法完成當天的網頁抓取工作,用來重新篩選代理IP,恢複網頁抓取的一段核心代碼

其設計實現流程,如上述的【方案設計】——》【7、重新檢測IP代理】,其實現原理可參照上述的【代理IP篩選】的指令碼,在此不再貼出其源指令碼代碼

相關文章

Alibaba Cloud 10 Year Anniversary

With You, We are Shaping a Digital World, 2009-2019

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。