首页 > 解决方案 > Python:如何从包含页面@odata.nextLink 的 Odata API 中提取数据

问题描述

我需要从 Odata API 中提取数据。使用下面的代码,我确实收到了数据,但只有 250 行。

JSON 包含一个名为:的键@odata.nextLink,它包含一个值,这是BASE_URL + endpoint + ?$skip=250

如何循环浏览下一页?

import requests
import pandas as pd
import json

BASE_URL = "base_url"


def session_token():
    url = BASE_URL + '/api/oauth/token'

    headers = {"Accept": "application\json",
                "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"}

    body = {"username":"user",
            "password": "pwd",
            "grant_type": "password"}

    return "Bearer "+ requests.post(url, headers = headers, data = body).json()["access_token"]

def make_request(endpoint, token = session_token()):
    headers = {"Authorization": token}
    response = requests.get(BASE_URL + endpoint, headers = headers)
    if response.status_code == 200:
        json_data = json.loads(response.text)
        return json_data


make_request("/odata/endpoint")

按照@Marek Piotrowski 的建议,我修改并找到了解决方案:

def main():
    url = "endpoint"
    while True:
        if not url:
            break
        response = make_request("endpoint")
        if response.status_code == 200:
            json_data = json.loads(response.text)
            url = json_data["@odata.nextLink"] # Fetch next link
            yield json_data['value']

result = pd.concat((json_normalize(row) for row in main()))
print(result) # Final dataframe, works like a charm :)

标签: pythonapiodata

解决方案


我相信这样的事情会检索所有记录(假设确实@odata.nextLinkjson_data):

def retrieve_all_records(endpoint, token = session_token()):
    all_records = []
    headers = {"Authorization": token}
    url = BASE_URL + endpoint
    while True:
        if not url:
            break
        response = requests.get(url, headers = headers)
        if response.status_code == 200:
            json_data = json.loads(response.text)
            all_records = all_records + json_data['records']
            url = json_data['@odata.nextLink']
    return all_records

不过,该代码未经测试。让我知道它是否有效。或者,您可以对 进行一些递归调用make_request,我相信,但是您必须将结果存储在函数本身之上的某个位置。


推荐阅读