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

分享一下我老師大神的人工智能教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

上一篇博客,介紹了Linux 抓取網頁的實例,其中在抓取google play國外網頁時,需要用到代理服務器


代理的用途

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

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


代理的原理

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

而是通過中間的代理服務器(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篩選】的腳本,在此不再貼出其源腳本代碼



           

給我老師的人工智能教程打call!http://blog.csdn.net/jiangjunshow

這裏寫圖片描述