【问题标题】:API Data Extraction - PythonAPI 数据提取 - Python
【发布时间】:2021-10-15 03:04:27
【问题描述】:

我正在尝试使用 python 中的以下代码从此 API:https://www.balldontlie.io/#get-all-stats 中提取数据:

import requests
import json
import time

total_results = []
pages_to_read = 11000
counter = 0

for page_num in range(1, pages_to_read + 1):
    url = "https://balldontlie.io/api/v1/stats?per_page=100&page=" + str(page_num)
    print("reading", url)
    response = requests.get(url)
    data = response.json()
    total_results = total_results + data['data']
    counter = counter+ 1
    print(counter)
    if counter == 59:
        counter = 0
        print('break')
        time.sleep(60)

print("Total of", len(total_results), "results")

with open('test.json', 'w', encoding='utf-8') as d:
    json.dump(total_results, d, ensure_ascii=False, indent=4)

但是,我总是收到此错误:https://cdn1.gnarususercontent.com.br/1/292460/5c2858ca-33df-4bd8-9b44-0d50a48ab3e0.png

API 应该支持每秒 60 个请求,有时甚至超过 60 个,但最后总是出现这个错误。有人有什么建议可以帮助我吗?

PS:我需要来自所有 11000 页“统计”的数据。只有页面的json'data'数据,不包括'meta data'和页码。

【问题讨论】:

  • 如果您尝试非常快速地访问某些 API,您可能会在一段时间后收到错误(例如,HTTP 502 - bad gateway)。在 get() 之后尝试 response.raise_for_status()。如果 HTTP 状态不是 200,这将引发异常
  • @BrutusForcus 刚试过,没用,我收到这个错误:raise SSLError(e, request=request) requests.exceptions.SSLError: HTTPSConnectionPool(host='balldontlie.io', port=443): Max retries exceeded with url: /api/v1/stats?per_page=100&page=2 (Caused by SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:748)'),))
  • 这只是证明并非所有 HTTP GET 请求都成功并且是问题的根源
  • 您也可能会遇到 HTTP 429 错误

标签: python api


【解决方案1】:

找到这个答案:

import requests
import json
import time
from datetime import datetime

resultados_totais = []
paginas_totais_para_ler = 11486

def get_api_data(page_num): 
    url = "https://balldontlie.io/api/v1/stats?per_page=100&page=" + str(page_num)

    current_time = datetime.now().strftime("%H:%M:%S")
    print("{} - Lendo {}".format(current_time, url))
    
    start_request = datetime.now()
    response = requests.get(url)

    end_request = datetime.now()
    delta = end_request - start_request

    if delta.seconds <= 0:
        time.sleep(1)

    if response.status_code == 200:
        data = response.json()
        response.raise_for_status()
        return data['data']
    else:
        current_time = datetime.now().strftime("%H:%M:%S")
        print("{} - ({}) Limite de request ... aguardando 15 seg para tentar novamente".format(current_time, response.status_code))
        time.sleep(15)
        return get_api_data(page_num)

for page_num in range(1, paginas_totais_para_ler + 1):
    resultados_totais.extend(get_api_data(page_num))
    if page_num == paginas_totais_para_ler:
        print('\nSalvando Arquivo json..')
        with open('all_stats.json', 'w', encoding='utf-8') as d:
            json.dump(resultados_totais, d, ensure_ascii=False, indent=4)
        print('\nArquivo Salvo!!')

print("\nTemos um total de", len(resultados_totais), "resultados.")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2021-08-28
    • 2017-04-16
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 2022-07-20
    相关资源
    最近更新 更多