05-訪問逾時設定
鄭昀 201005 隸屬於《01.資料抓取》小節
設定 HTTP 或 Socket 訪問逾時,來防止爬蟲抓取某個頁面時間過長。
pycurl 庫的調用中,可以設定逾時時間:
c.setopt(pycurl.CONNECTTIMEOUT, 60)
在 Python 2.6 版本下,httplib 庫由於有如下建構函式:
class HTTPConnection:
def __init__(self, host, port=None, strict=None,
timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
self.timeout = timeout
所以可以設定:
>>> h3 = httplib.HTTPConnection('www.cwi.nl', 80, timeout=10)
參見文檔 #2452: timeout is used for all blocking operations :
如果通過 HTTPConnection 或 HTTPSConnection 的建構函式給定逾時時間,那麼阻塞操作(如試圖建立串連)將會逾時。如果沒有給或者賦值 None ,那麼它將使用全域的逾時時間設定。
Python 2.5 下,因為 HTTPConnection 類的 __init__ 函數沒有 timeout 參數,所以通過一個隱藏很深的函數:
httplib.socket.setdefaulttimeout(3)#輸入參數單位貌似是分鐘
來設定逾時。
設定全域逾時最後,抓取時如果實在找不到什麼函數能設定逾時時間,那麼可以設定全域的 socket 逾時,雖然這樣做不大合適:
>>> import socket
>>> socket.setdefaulttimeout(90)
setdefaulttimeout() was a hack to allow to set the timeout when nothing else is available.
如何捕獲逾時異常?舉例:
from urllib2 import urlopen
import socket
slowurl =”http://www.wenxuecity.com/”
socket.setdefaulttimeout(1)
try:
data = urlopen(slowurl)
data.read()
except socket.error:
errno, errstr = sys.exc_info()[:2]
if errno == socket.timeout:
print "There was a timeout"
else:
print "There was some other socket error"
參考資源:
1、 No way to disable socket timeouts in httplib, etc.
2、How to catch socket timeout?