在linux下python爬蟲進程發生異常時自動重啟直至正常結束的方法


之前在做爬蟲的時候遇到一種情況,當網絡情況不太好的時候,爬蟲爬到的鏈接在urlopen時會因為無法正常連接而報URLError或者timeout的錯誤導致陳序報錯而終止;但是這些錯誤在重新運行陳序后能夠解決,因此為了避免重復手動重啟程序的麻煩,就想寫腳本來自動重啟。

思路很簡單:
1.首先腳本檢測目標程序是否在運行。這里我們可以用pidof的返回值來判斷。
2.如果腳本檢測到程序尚未運行或程序運行出錯,重啟程序。這里需要用到linux的$?變量,該變量能返回上一次命令的運行狀態。其中0為運行正常,其他均為運行報錯。
3.如果程序正常運行結束,終止腳本

例如我們要自動運行名為web_crawler.py的腳本,那么可以寫如下shell腳本:

#! /bin/bash
pidof web_crawler.py # 檢測程序是否運行
while [ $? -ne 0 ]    # 判斷程序上次運行是否正常結束
do
    echo "Process exits with errors! Restarting!"
    python web_crawler.py    #重啟程序
done
echo "Process ends!"

PS1: 這只能處理網絡狀況不良引起連接出錯的情況,通過重新嘗試鏈接能夠解決的。如果是遇到了由於網站被牆導致的鏈接錯誤,那么這個做法就很有問題了,因為無論你重復幾次都無法打開鏈接。這種情況的解決方式要么是翻牆再運行爬蟲,那么就是跳過被牆的鏈接——具體操作可以是用re匹配鏈接排除,也可以是用try在連接超時執行跳出操作。例如:

try:
    res = urllib2.urlopen(rq, timeout=10) # use urllib2 package
except urllib2.URLError, e:
    print "Timed out to connect to this URL"
    return None
except socket.timeout: # use socket package
    print "Time out!"
    return None

PS2:這里我們實際爬的是stanford cs224d上的鏈接然后下載內容,由於有些鏈接(pdf文件或者html網頁)不包含文件后綴,保存的時候會比較麻煩。但是如果鏈接是網頁的話那么res.headers.getheader('Content-Type') # urllib2或者rq = requests.get(url);r.headers['content-type'] # requests返回內容包含'text/html',利用這一點我們就可以識別出網頁鏈接進行保存。

參考:

  1. http://stackoverflow.com/questions/18883086/check-if-the-page-is-html-page-in-python
  2. http://stackoverflow.com/questions/20162678/linux-script-to-check-if-process-is-running-act-on-the-result
  3. http://stackoverflow.com/questions/90418/exit-shell-script-based-on-process-exit-code
  4. http://stackoverflow.com/questions/16778435/python-check-if-website-exists


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM