Python处理socket.error:由对等方重置连接

当使用Python 2.7和urllib2从API中检索数据时,我得到[Errno 104] Connection reset by peer的错误[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, in <module> rateEurUsd = 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 

“通过对等方重置连接”是将电话重新挂机的TCP / IP等价物。 比单纯的不回答更有礼貌,只留下一个。 但是,这不是真正有礼貌的TCP / IP交换机所期望的FIN-ACK。 ( 从其他SO回答 )

所以你不能做任何事情,这是服务器的问题。

但是你可以使用try .. except块来处理这个exception:

 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. 

您可以尝试将一些time.sleep调用添加到您的代码。

似乎服务器端限制每个时间单元(小时,天,秒)的请求量作为安全问题。 你需要猜测有多less(也许使用另一个脚本与计数器?),并调整您的脚本不超过这个限制。

为了避免你的代码崩溃,尝试用try .. except来捕获这个错误, try .. except在urllib2调用之外。