难以通过第三方图书馆在Call Stack深处捕获例外



我正在使用API收集大量网站的统计信息,但是该网站限制了我一旦达到此速率,我可以通过关闭连接来从服务器中获取数据的速率(通常会提出requests.exceptions.ConnectionError,但有时会引起其他与连接有关的错误,例如Time Out(。

我如何尝试通过在打开连接并拉出数据的第三方库函数周围构建包装器来解决此问题。该函数try_request()在下面,但是从本质上讲,每次调用此函数时,我都会使用一个try语句查看是否可以提取数据,除了等级以外的任何例子以捕获任何异常,等待5秒钟,然后递归重试(对于5次尝试(。问题是它似乎并没有抓住例外。

ps" while true"语句只是为了获取错误的垃圾邮件以获取错误...我知道这在实践中不是一个好主意

from nba_api.stats.endpoints import *
from nba_api.stats.static import players
from nba_api_helpers import try_request
active_players = players.get_active_players()
for player in active_players:
    if player['full_name'] == 'Stephen Curry':
        while True:
            dummy = try_request(commonplayerinfo.CommonPlayerInfo(player['id']))
            print('success')

和其他文件中的try_request()函数:

def try_request(api_call, number_tries=5):
    sleep_time = 5
    tries_left = number_tries
    if tries_left == 1:
        print("Final try...")
        return api_call
    else:
        try:
            api_call
        except:
            print("Caught exception in Endpoint request... Waiting {} seconds to try again".format(sleep_time))
            time.sleep(sleep_time)
            try_request(api_call, tries_left-1)

如果我在下面的顶级代码上进行尝试/除外,它会捕获一个例外,但这不是我要做的,因为我需要重试失败的功能。

这是我经常得到的错误代码的一个示例...我认为这会被抓住我的try_request()功能的条款,但没有被拾取

Traceback (most recent call last):
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesurllib3connectionpool.py", line 384, in _make_request
    six.raise_from(e, None)
  File "<string>", line 2, in raise_from
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesurllib3connectionpool.py", line 380, in _make_request
    httplib_response = conn.getresponse()
  File "C:UsersjakedAppDataLocalProgramsPythonPython37Libhttpclient.py", line 1321, in getresponse
    response.begin()
  File "C:UsersjakedAppDataLocalProgramsPythonPython37Libhttpclient.py", line 296, in begin
    version, status, reason = self._read_status()
  File "C:UsersjakedAppDataLocalProgramsPythonPython37Libhttpclient.py", line 257, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "C:UsersjakedAppDataLocalProgramsPythonPython37Libsocket.py", line 589, in readinto
    return self._sock.recv_into(b)
  File "C:UsersjakedAppDataLocalProgramsPythonPython37Libssl.py", line 1052, in recv_into
    return self.read(nbytes, buffer)
  File "C:UsersjakedAppDataLocalProgramsPythonPython37Libssl.py", line 911, in read
    return self._sslobj.read(len, buffer)
socket.timeout: The read operation timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesrequestsadapters.py", line 449, in send
    timeout=timeout
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesurllib3connectionpool.py", line 638, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesurllib3utilretry.py", line 367, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesurllib3packagessix.py", line 686, in reraise
    raise value
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesurllib3connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesurllib3connectionpool.py", line 386, in _make_request
    self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesurllib3connectionpool.py", line 306, in _raise_timeout
    raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='stats.nba.com', port=443): Read timed out. (read timeout=30)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "C:/Users/jaked/PycharmProjects/NBA/src/classes/scratch.py", line 13, in <module>
    dummy = try_request1(commonplayerinfo.CommonPlayerInfo(player['id']))
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesnba_apistatsendpointscommonplayerinfo.py", line 32, in __init__
    self.get_request()
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesnba_apistatsendpointscommonplayerinfo.py", line 40, in get_request
    timeout=self.timeout,
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesnba_apilibraryhttp.py", line 123, in send_api_request
    response = requests.get(url=base_url, params=parameters, headers=request_headers, proxies=proxies, timeout=timeout)
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesrequestsapi.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesrequestsapi.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesrequestssessions.py", line 524, in request
    resp = self.send(prep, **send_kwargs)
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesrequestssessions.py", line 637, in send
    r = adapter.send(request, **kwargs)
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesrequestsadapters.py", line 529, in send
    raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='stats.nba.com', port=443): Read timed out. (read timeout=30)

谢谢,期待学习!

我不会像您一样使用递归策略推荐。您是否尝试过循环?也许这样的东西:

def try_request(api_call_function, number_tries=5, sleep_seconds=5):
    for i in range(number_tries):
        try:
            return api_call_function()
        except Exception as ex:
            print('try', i)
            print(ex)
        time.sleep(sleep_seconds)
    # choose a default return value for the case when the API call
    # failed the max number of tries
    return None

并尝试捕获明确的异常类,然后打印出来,以便您可以看到提出了哪些类型的错误。一个空的except子句(如您在问题中所示(具有隐藏其他可能发生的错误的危险。

这对您有帮助吗?


在您将错误stacktrace编辑为问题后,我注意到您的 try_request()函数似乎没有被调用,因为它没有出现在您的stacktrace中(请注意,它是如何直接从文件C:/Users/jaked/PycharmProjects/NBA/src/classes/scratch.py转到第三方NBA的。lib C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesnba_apistatsendpointscommonplayerinfo.py(。

Traceback (most recent call last):
  File "C:/Users/jaked/PycharmProjects/NBA/src/classes/scratch.py", line 13, in <module>
    dummy = try_request1(commonplayerinfo.CommonPlayerInfo(player['id']))
  File "C:UsersjakedAppDataLocalProgramsPythonPython37libsite-packagesnba_apistatsendpointscommonplayerinfo.py", line 32, in __init__
    self.get_request()

您确定这是使用函数try_request()时的错误堆栈吗?因为这里似乎有些不对。

最新更新