当使用Python 2.7 urllib2
从API检索数据时,我收到错误[Errno 104] Connection reset by peer
.什么导致错误,以及如何处理错误,以便脚本不会崩溃?
ticker.py
def urlopen(url): response = None request = urllib2.Request(url=url) try: response = urllib2.urlopen(request).read() except urllib2.HTTPError as err: print "HTTPError: {} ({})".format(url, err.code) except urllib2.URLError as err: print "URLError: {} ({})".format(url, err.reason) except httplib.BadStatusLine as err: print "BadStatusLine: {}".format(url) return response def get_rate(from_currency="EUR", to_currency="USD"): url = "https://finance.yahoo.com/d/quotes.csv?f=sl1&s=%s%s=X" % ( from_currency, to_currency) data = urlopen(url) if "%s%s" % (from_currency, to_currency) in data: return float(data.strip().split(",")[1]) return None counter = 0 while True: counter = counter + 1 if counter==0 or counter%10: rateEurUsd = float(get_rate('EUR', 'USD')) # does more stuff here
追溯
Traceback (most recent call last): File "/var/www/testApp/python/ticker.py", line 71, inrateEurUsd = float(get_rate('EUR', 'USD')) File "/var/www/testApp/python/ticker.py", line 29, in get_exchange_rate data = urlopen(url) File "/var/www/testApp/python/ticker.py", line 16, in urlopen response = urllib2.urlopen(request).read() File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen return _opener.open(url, data, timeout) File "/usr/lib/python2.7/urllib2.py", line 406, in open response = meth(req, response) File "/usr/lib/python2.7/urllib2.py", line 519, in http_response 'http', request, response, code, msg, hdrs) File "/usr/lib/python2.7/urllib2.py", line 438, in error result = self._call_chain(*args) File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain result = func(*args) File "/usr/lib/python2.7/urllib2.py", line 625, in http_error_302 return self.parent.open(new, timeout=req.timeout) File "/usr/lib/python2.7/urllib2.py", line 406, in open response = meth(req, response) File "/usr/lib/python2.7/urllib2.py", line 519, in http_response 'http', request, response, code, msg, hdrs) File "/usr/lib/python2.7/urllib2.py", line 438, in error result = self._call_chain(*args) File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain result = func(*args) File "/usr/lib/python2.7/urllib2.py", line 625, in http_error_302 return self.parent.open(new, timeout=req.timeout) File "/usr/lib/python2.7/urllib2.py", line 400, in open response = self._open(req, data) File "/usr/lib/python2.7/urllib2.py", line 418, in _open '_open', req) File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain result = func(*args) File "/usr/lib/python2.7/urllib2.py", line 1207, in http_open return self.do_open(httplib.HTTPConnection, req) File "/usr/lib/python2.7/urllib2.py", line 1180, in do_open r = h.getresponse(buffering=True) File "/usr/lib/python2.7/httplib.py", line 1030, in getresponse response.begin() File "/usr/lib/python2.7/httplib.py", line 407, in begin version, status, reason = self._read_status() File "/usr/lib/python2.7/httplib.py", line 365, in _read_status line = self.fp.readline() File "/usr/lib/python2.7/socket.py", line 447, in readline data = self._sock.recv(self._rbufsize) socket.error: [Errno 104] Connection reset by peer error: Forever detected script exited with code: 1
Bunyk.. 115
"通过对等方重置连接"是TCP/IP等同于将手机重新关闭.它更礼貌而不仅仅是不回复,留下一个悬挂.但这并不是真正礼貌的TCP/IP逆转所期望的FIN-ACK.(来自其他SO回答)
所以你无法做任何事情,这是服务器的问题.
但您可以使用try .. except
block来处理该异常:
from socket import error as SocketError import errno try: response = urllib2.urlopen(request).read() except SocketError as e: if e.errno != errno.ECONNRESET: raise # Not error we are looking for pass # Handle error here.
服务器管理员通常使用这种方法来阻止客户端潜在的抓取请求,还是更可能只是一个无意的错误?现在我想知道我是否被故意阻止... (2认同)
小智.. 10
您可以尝试向time.sleep
代码添加一些调用.
似乎服务器端将每个时间单位(小时,天,秒)的请求数量限制为安全问题.您需要猜测多少(可能使用另一个带有计数器的脚本?)并调整您的脚本以不超过此限制.
为了避免代码崩溃,请尝试try .. except
在urllib2调用周围捕获此错误.