2013-12-13 19 views
47

Quando si utilizza Python 2.7 con urllib2 per recuperare i dati da un'API, viene visualizzato l'errore [Errno 104] Connection reset by peer. Che cosa sta causando l'errore, e come dovrebbe essere gestito l'errore in modo che lo script non si arresti?Python che gestisce socket.error: [Errno 104] Connessione ripristinata dal 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

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 
+0

Su arch linux, get_rate funziona bene per me. Sei sicuro di non essere filtrato? Puoi caricare quell'URL in un browser? – korylprince

+0

@korylprince Funziona bene in un browser e lo script funziona bene per un po 'prima che l'errore inizi a comparire. Se non riesco a evitare l'errore, come deve essere gestito l'errore in modo che non si blocchi e probabilmente utilizza il valore più recente recuperato? –

risposta

87

"Connection reset by peer" is the TCP/IP equivalent of slamming the phone back on the hook. It's more polite than merely not replying, leaving one hanging. But it's not the FIN-ACK expected of the truly polite TCP/IP converseur. (From other SO answer)

Così non si può fare nulla al riguardo, è la questione del server.

Ma si potrebbe usare try .. except blocco per gestire tale eccezione:

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. 
+0

È vero che l'amministratore del server solitamente utilizza questo metodo per bloccare potenziali richieste di scraping da un client o è più probabile che si tratti solo di un bug non intenzionale? Ora mi chiedo se sono bloccato intenzionalmente o no ... – Blaszard

0

si può provare ad aggiungere alcuni time.sleep chiamate al codice.

Sembra che il lato server limiti la quantità di richieste per unità di tempo (ora, giorno, secondo) come un problema di sicurezza. Devi indovinare quanti (magari usando un altro script con un contatore?) E aggiustare il tuo script per non superare questo limite.

Al fine di evitare il blocco del codice, provare a rilevare questo errore con try .. except intorno alle chiamate urllib2.

Problemi correlati