#python #api #odata
#python #API #odata
Вопрос:
Мне нужно извлечь данные из 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": "applicationjson",
"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 :)
Ответ №1:
Я полагаю, что что-то подобное восстановит все записи (при условии, что они действительно есть @odata.nextLink
в json_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
, но тогда вам пришлось бы хранить результаты где-то над самой функцией.
Комментарии:
1. И
?$skip=250
часть?2. Вы сами написали, что odata.nextLink уже содержит это, верно? Я полагаю, что next
odata.nextLink
пропустит первые 500 записей и так далее.3. Спасибо, получил мое решение. Реализуйте свой совет и добавьте немного логики 🙂
4. Приятно это слышать! Был бы признателен, если бы вы приняли ответ тогда. Спасибо!
Ответ №2:
Я знаю, что это поздно, но вы могли бы взглянуть на эту статью из К науке о данных Ephram Мваи
Он довольно решил проблему с помощью хорошего скрипта.