Устранение неполадок, возникающих в сторонней библиотеке в стеке вызовов - PullRequest
0 голосов
/ 24 мая 2019

Я использую API для сбора большого количества статистики веб-сайта, но веб-сайт ограничивает скорость, с которой я могу получать данные с сервера, закрывая соединение, как только я достигаю этой скорости (обычно поднимая requests.exceptions.ConnectionError, но иногда вызывает другие ошибки, связанные с подключением, такие как тайм-ауты).

Как я пытался решить эту проблему, создавая оболочку вокруг сторонней библиотечной функции, которая открывает соединение и извлекает данные. Функция try_request() находится ниже, но, по сути, каждый раз, когда эта функция вызывается, я использую оператор try, чтобы посмотреть, могу ли я получить данные, и предложение исключить, чтобы перехватить любое исключение, подождать 5 секунд и рекурсивно повторить попытку (для 5 попыток). Проблема в том, что это, похоже, не ловит исключение.

PS Утверждение "в то время как истина" состоит в том, чтобы спамить сайт на секунду, чтобы получить ошибку ... Я знаю, что на практике это не очень хорошая идея

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:\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)

Спасибо и с нетерпением ждем обучения!

1 Ответ

0 голосов
/ 24 мая 2019

Я НЕ рекомендую использовать рекурсивную стратегию, как вы делаете. Вы пробовали петлю вместо этого? Может быть, что-то вроде этого:

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 непосредственно в Сторонний НБА 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()? Потому что здесь что-то не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...