#python #json #dataframe #python-requests #append
Вопрос:
Я успешно написал код, который вызывает API, а затем преобразует результаты в фрейм данных.
wax_wallet = "zqsfm.wam"
# Get Assets from AtomicHub API
response1 = requests.get(
"https://wax.api.atomicassets.io/atomicassets/v1/assets?"
f"owner={wax_wallet}"
"amp;collection_whitelist=nftdraft2121"
"amp;page=1"
"amp;limit=1000"
"amp;order=asc"
"amp;sort=name")
# Save Response as JSON
json_assets = response1.json()
# Convert JSON to DataFrame
df = pd.json_normalize(json_assets['data'])
Этот API возвращает не более 1000 элементов на страницу, поэтому мне нужно, чтобы он просматривал столько страниц, сколько необходимо, и в конечном итоге получал результаты, сохраненные во фрейме данных.
Я попытался решить эту проблему с помощью приведенного ниже кода, но безуспешно.
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'amp;collection_whitelist=nftdraft2121amp;page={page}amp;limit=1000amp;order=ascamp;sort=name'
response = rq.get(url)
all_assets.append(json.loads(response.text))["response"]
Заранее спасибо за любую помощь!
Комментарии:
1. Лучше использовать
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)
Изменить: обновлено с использованием параметров на основе комментария Олвина Рота
Правка 2: исправлена ошибка индексирования
Комментарии:
1. Не уверен, что вы имеете в виду под своим вопросом. Но хорошее предложение с использованием параметров
2. Вы уже отредактировали свой ответ, включая мое предложение из комментариев, поэтому мой вопрос сейчас не имеет смысла. Я просто хотел указать вам, что вам нужно кодировать каждое значение в кодировку url, если вы формируете URL вручную, и лучше использовать
params
то, что сделает это внутренне.3. @tituszban Спасибо за ответ! Это работает почти идеально; однако это не совсем то, на что я надеюсь. Мне нужно вернуть 3 страницы, но этот код возвращает первую страницу дважды, а затем вторую страницу один раз. Например, у меня есть 2500 элементов, разбросанных по 3 страницам. Этот вывод возвращает 1-1000, 1-1000, затем 1,001-2,000. Есть какие-нибудь идеи?
4. @python_noob_5, используйте
range(1, number_of_pages_requested 1)
5. @OlvinRoght прав. Я предпочитаю делать
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')
Комментарии:
1. Лучше избегать имен переменных, которые могут привести к теневому импорту. Кроме того, бесконечные петли-это в основном плохой шаблон, лучше добавить какое-то строгое условие.
2. Я предполагаю, что вы имеете в виду переменную с именем «json». На том основании, что я не импортирую json, я не вижу проблемы. Кроме того, в данном конкретном случае невозможно узнать, сколько страниц может быть возвращено. Это может быть выведено только путем запроса страницы, которая находится за пределами доступного диапазона, и когда это происходит, возникает четко определенное условие