2013-12-13 17 views
47

Khi sử dụng Python 2.7 với urllib2 để truy xuất dữ liệu từ API, tôi gặp lỗi [Errno 104] Connection reset by peer. Whats gây ra lỗi, và làm thế nào lỗi nên được xử lý để kịch bản không sụp đổ?Xử lý lệnh socket.error: [Errno 104] Thiết lập lại kết nối theo ngang hàng

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

Trên linux của kiến ​​trúc, get_rate hoạt động tốt cho tôi. Bạn có chắc là bạn không bị lọc không? Bạn có thể tải url đó trong trình duyệt không? – korylprince

+0

@korylprince Nó hoạt động tốt trong một trình duyệt, và kịch bản chạy tốt trong một thời gian trước khi lỗi bắt đầu xuất hiện. Nếu tôi không thể tránh được lỗi, lỗi sẽ được xử lý như thế nào để lỗi đó không bị lỗi và có thể sử dụng giá trị gần đây nhất được truy xuất? –

Trả lời

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)

Vì vậy, bạn không thể làm bất cứ điều gì về nó, nó là vấn đề của máy chủ.

Nhưng bạn có thể sử dụng try .. except khối để xử lý ngoại lệ rằng:

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

Có đúng là quản trị viên của máy chủ thường sử dụng phương pháp này để chặn các yêu cầu cạo tiềm ẩn của khách hàng hoặc có nhiều khả năng chỉ là lỗi không chủ định không? Bây giờ tôi tự hỏi nếu tôi bị chặn cố ý hay không ... – Blaszard

0

Bạn có thể cố gắng thêm một số time.sleep cuộc gọi đến mã của bạn.

Dường như phía máy chủ giới hạn số lượng yêu cầu theo thời gian (giờ, ngày, giây) dưới dạng sự cố bảo mật. Bạn cần phải đoán có bao nhiêu (có thể sử dụng một kịch bản khác với một bộ đếm?) Và điều chỉnh kịch bản của bạn để không vượt quá giới hạn này.

Để tránh mã của bạn bị lỗi, hãy cố gắng gặp lỗi này với try .. except xung quanh cuộc gọi urllib2.

Các vấn đề liên quan