python - 无法通过调用堆栈深处的第 3 方库捕获异常
问题描述
我正在使用 API 收集网站的大量统计信息,但网站限制了我可以通过在达到此速率后关闭连接来从服务器提取数据的速率(通常会提高 a requests.exceptions.ConnectionError
,但有时会提高其他相关的连接超时等错误)。
我试图解决这个问题的方法是围绕打开连接并提取数据的 3rd 方库函数构建一个包装器。该函数try_request()
如下,但基本上每次调用该函数时,我都会使用 try 语句来查看是否可以拉取数据,并使用 except 子句捕获任何异常,等待 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/except ,它会捕获一个异常,但这不是我想要做的,因为我需要重试失败的函数。
这是我经常得到的错误代码的一个例子......我认为这会在我的try_request()
函数的 except 子句中被捕获,但它没有被拾取
Traceback (most recent call last):
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 384, in _make_request
six.raise_from(e, None)
File "<string>", line 2, in raise_from
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 380, in _make_request
httplib_response = conn.getresponse()
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\Lib\http\client.py", line 1321, in getresponse
response.begin()
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\Lib\http\client.py", line 296, in begin
version, status, reason = self._read_status()
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\Lib\http\client.py", line 257, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\Lib\socket.py", line 589, in readinto
return self._sock.recv_into(b)
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\Lib\ssl.py", line 1052, in recv_into
return self.read(nbytes, buffer)
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\Lib\ssl.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:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\adapters.py", line 449, in send
timeout=timeout
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 638, in urlopen
_stacktrace=sys.exc_info()[2])
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\retry.py", line 367, in increment
raise six.reraise(type(error), error, _stacktrace)
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\packages\six.py", line 686, in reraise
raise value
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 600, in urlopen
chunked=chunked)
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 386, in _make_request
self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.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:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\nba_api\stats\endpoints\commonplayerinfo.py", line 32, in __init__
self.get_request()
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\nba_api\stats\endpoints\commonplayerinfo.py", line 40, in get_request
timeout=self.timeout,
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\nba_api\library\http.py", line 123, in send_api_request
response = requests.get(url=base_url, params=parameters, headers=request_headers, proxies=proxies, timeout=timeout)
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\api.py", line 75, in get
return request('get', url, params=params, **kwargs)
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\sessions.py", line 524, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\sessions.py", line 637, in send
r = adapter.send(request, **kwargs)
File "C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\adapters.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
子句(就像您在问题中显示的那样)有隐藏可能发生的其他错误的危险。
这对你有帮助吗?
在您将错误堆栈跟踪编辑到您的问题中后,我注意到您的try_request()
函数似乎没有被调用,因为它没有出现在您的堆栈跟踪中(注意它是如何从文件C:/Users/jaked/PycharmProjects/NBA/src/classes/scratch.py
直接转到 3rd-party NBA lib 的C:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\nba_api\stats\endpoints\commonplayerinfo.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:\Users\jaked\AppData\Local\Programs\Python\Python37\lib\site-packages\nba_api\stats\endpoints\commonplayerinfo.py", line 32, in __init__
self.get_request()
您确定这是您使用函数时的错误堆栈跟踪try_request()
吗?因为这里似乎有些不对劲。
推荐阅读
- python-3.x - GradientTape 丢失变量的轨迹
- java - 注册页面 else/if
- reactjs - Antd中使用数组对象分组复选框
- python - 当我从 Python 将数据导出到 csv 时,该文件是空白的。当我使用 Print 函数查看数据时,返回第一个字符串
- path - SwiftUI 中 Path.addArc 的顺时针方向错了吗?
- swift - 未知的 116 字节 ECDSA 私钥格式
- python - 我可以将循环的结果保存到列表中(Python)吗?
- ios - 如何正确格式化单元格?
- nix - 如何禁用解压阶段以防止出现“不知道如何解压源存档”错误?
- ios - GADBannerView removeFromSuperview 不起作用