2013-12-13 46 views
47

urllib2でPython 2.7を使用してAPIからデータを取得すると、エラー[Errno 104] Connection reset by peerが返されます。何が原因でエラーが発生し、スクリプトがクラッシュしないようにエラーを処理する必要がありますか?Pythonハンドリングsocket.error:[Errno 104]接続先のリセット

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

アーチlinuxでは、get_rateがうまく動作します。フィルタリングされていないと確信していますか?そのURLをブラウザに読み込むことはできますか? – korylprince

+0

@korylprinceブラウザで正常に動作し、エラーが表示される前にスクリプトがしばらく実行されます。エラーを回避できない場合は、クラッシュしないようにエラーをどのように処理すればよく、取得した最新の値を使用するのでしょうか? –

答えて

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)

だから、あなたはそれについて何もできない、それはサーバーの問題です。

しかし、あなたはその例外を処理するためにtry .. exceptブロックを使用することができます。

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

通常、サーバーの管理者はこの方法を使用して、クライアントによる潜在的なスクラップ要求をブロックすることはできますか、それとも単に意図しないバグである可能性はありますか?今私が意図的にブロックされているのかどうか、私は不思議です... – Blaszard

0

あなたのコードにいくつかのtime.sleep呼び出しを追加しようとすることができます。

セキュリティ上の問題として、サーバー側でtimeunit(時間、日、秒)ごとの要求量が制限されているようです。あなたはどれくらいの数を推測する必要がありますか(カウンタで別のスクリプトを使用するのでしょうか?)、この制限を超えないようにスクリプトを調整します。

コードがクラッシュしないようにするには、urllib2呼び出しの周りでtry .. exceptを使用してこのエラーをキャッチしてください。

関連する問題