如何从跨多个页面的 GET 请求中提取所有结果?

Posted

技术标签:

【中文标题】如何从跨多个页面的 GET 请求中提取所有结果?【英文标题】:How do I extract all results from a GET request that spans multiple pages? 【发布时间】:2021-10-07 20:24:56 【问题描述】:

我已经成功编写了调用 API 并将结果转换为 DataFrame 的代码。

wax_wallet = "zqsfm.wam"

# Get Assets from AtomicHub API
response1 = requests.get(
    "https://wax.api.atomicassets.io/atomicassets/v1/assets?"
    f"owner=wax_wallet"
    "&collection_whitelist=nftdraft2121"
    "&page=1"
    "&limit=1000"
    "&order=asc"
    "&sort=name")

# Save Response as JSON
json_assets = response1.json()

# Convert JSON to DataFrame
df = pd.json_normalize(json_assets['data'])

此 API 每页最多返回 1000 个项目,因此我需要让它循环遍历所需的多个页面,并最终将结果存储到 DataFrame 中。

我试图用下面的代码解决它,但没有成功。

asset_count = 2500
pages = int(math.ceil(asset_count / 1000))

# Get Assets from AtomicHub API
all_assets = []
for page in range(1, pages):
    url = f'https://wax.api.atomicassets.io/atomicassets/v1/assets?owner=wax_wallet' \
          f'&collection_whitelist=nftdraft2121&page=page&limit=1000&order=asc&sort=name'
    response = rq.get(url)
    all_assets.append(json.loads(response.text))["response"]

提前感谢您的帮助!

【问题讨论】:

最好使用params 参数而不是手动形成查询字符串:requests.get("https://wax.api.atomicassets.io/atomicassets/v1/assets", params="owner": wax_wallet, "collection_whitelist": "nftdraft2121", "page": "1", "limit": "1000", "order": "asc", "sort": "name")。你也可以使用response.json() 【参考方案1】:

您可以将它们转换为数据帧,然后将各个帧连接成最终结果:

def get_page(page_num):
    wax_wallet = "zqsfm.wam"

    response = requests.get(
        "https://wax.api.atomicassets.io/atomicassets/v1/assets",
        params=
            "owner": wax_wallet,
            "collection_whitelist": "nftdraft2121",
            "page": page_num,
            "limit": "1000",
            "order": "asc",
            "sort": "name"
        
    )

    json_assets = response.json()
    return pd.json_normalize(json_assets['data'])

# The number of pages you want
number_of_pages_requested = 10

# Get all pages as dataframes
pages = [get_page(n + 1) for n in range(number_of_pages_requested)]

# Combine pages to single dataframe
df = pd.concat(pages)

编辑:根据Olvin Roght的评论使用参数更新

编辑 2: 修复索引错误

【讨论】:

不确定您的问题是什么意思。但是使用参数的好建议 您已经编辑了您的答案,包括我来自 cmets 的建议,所以我的问题现在没有意义了。我只是想指出,如果您手动形成 url,则需要将每个值编码为 url 编码,最好使用 params,它会在内部执行此操作。 @tituszban 感谢您的回复!这几乎可以完美地工作;但是,它并没有完全返回我所希望的。我需要返回 3 页,但此代码返回第一页两次,然后返回第二页一次。例如,我有 2,500 个项目跨越 3 个页面。此输出返回 1-1000、1-1000,然后是 1,001-2,000。有什么想法吗? @python_noob_5,使用range(1, number_of_pages_requested + 1) @OlvinR​​oght 是正确的。我更喜欢n + 1。更新了我的答案【参考方案2】:

我认为这应该会有所帮助:-

import requests

all_assets = []
URL = 'https://wax.api.atomicassets.io/atomicassets/v1/assets'
params = 
    'owner': 'zqsfm.wam',
    'collection_whitelist': 'nftdraft2121',
    'page': 1,
    'order': 'asc',
    'sort': 'name',
    'limit': 1000

with requests.Session() as session:
    while True:
        print(f"Getting page params['page']")
        response = session.get(URL, params=params)
        response.raise_for_status()
        _j = response.json()
        data = _j['data']
        if len(data) > 0:
            all_assets.append(data)
            params['page'] += 1
        else:
            break
print('Done')

【讨论】:

最好避免可能会影响导入的变量名称。无限循环也大多是不好的模式,最好添加一些严格的条件。 我假设您指的是名为“json”的变量。在我不导入json的基础上,我没有看到问题。此外,在这种特殊情况下,无法知道可能会返回多少页。它只能通过请求超出可用范围的页面来推断,当这种情况发生时,就会出现明确定义的条件

以上是关于如何从跨多个页面的 GET 请求中提取所有结果?的主要内容,如果未能解决你的问题,请参考以下文章

从跨域 http.get 请求的 ASP.NET Web API 2 响应中获取 Angular 中的特定响应标头(例如 Content-Disposition)

Python请求数据错误?

芝麻HTTP:Ajax结果提取

AWS ECS Fargate 从跨账户 ECR 存储库中提取映像

嗨,我正在尝试解析谷歌结果页面以提取所有 URL

使用输入框从React.js中提取GET请求的结果