Как прочитать следующую страницу в API с помощью итератора python?

#python #api #iterator

#python #API #итератор

Вопрос:

Существует API, который выдает только сто результатов на страницу. Я пытаюсь создать цикл while, чтобы он просматривал все страницы и получал результаты со всех страниц, но это не работает. Я был бы признателен, если бы вы помогли мне разобраться.

     params = dict(
    order_by='salary_desc',
    text=keyword,
    area=area,
    period=30, # days
    per_page=100,
    page = 0,
    no_magic='false',  # disable magic
    search_field='name'  # available: name, description, company_name
)
response = requests.get(
    BASE_URL   '/vacancies',
    headers={'User-Agent': generate_user_agent()},
    params=params,
)
response

items = response.json()['items']
vacancies = []
for item in items:
    vacancies.append(dict(
        id=item['id'],
        name=item['name'],
        salary_from=item['salary']['from'] if item['salary'] else None,
        salary_to=item['salary']['to'] if item['salary'] else None,
        currency = item['salary']['currency'] if item['salary'] else None,
        created=item['published_at'],
        company=item['employer']['name'],
        area = item['area']['name'],
        url=item['alternate_url']
    ))
 

Я перебираю словарь, если в словаре есть результат, я добавляю 1 к параметру страницы в качестве итератора:

 while vacancies == True:
  params['page']  = 1
 

Результат в параметрах словаря [‘page’] = остается ноль (страницы в API начинаются с нуля).

При вызове параметров после запуска цикла результат:

 {'area': 1,
'no_magic': 'false',
'order_by': 'salary_desc',
'page': 0,
'per_page': 100,
'period': 30,
'search_field': 'name',
'text': '"python"'}
 

Возможно, я неправильно выполняю цикл, исходя из логики, согласно которой, пока в словаре есть результат, цикл должен быть выполнен.

Ответ №1:

 while vacancies == True: # 
  params['page']  = 1
 

никогда не будет вычисляться до буквального True , независимо от его содержимого. Python dict ; даже думал, что они правдивы, но это не так True . Вам нужно уменьшить строгость инструкции.

 if vacancies: # is truthy if it's len > 0, falsey otherwise
    # Do something
 

Или вы можете явно проверить, есть ли в нем содержимое

 if len(vacancies) > 0:
    # Do something
 

Это решает проблему оценки на основе объекта, но не решает общую логическую проблему.

 for _ in vacancies:
    params["page"]  = 1
    # Does something for every item in vacancies
 

То, что вы делаете в каждом цикле, будет зависеть от проблемы и потребует другого вопроса!

исправлено ниже

 params = dict(
    order_by='salary_desc',
    text=keyword,
    area=area,
    period=30, # days
    per_page=100,
    page = 0,
    no_magic='false',  # disable magic
    search_field='name'  # available: name, description, company_name
)
pages = []
while True:
  params["page"]  = 1
  response = requests.get(BASE_URL   '/vacancies', headers={'User-Agent': generate_user_agent()}, params=params,)
  items = response.json()['items']
  if not items:
    break
  pages.append(items) # Do it for each page
 

Создайте вакансии для каждой страницы

 results = []
for page in pages:
  vacancies = []
  for item in page:
      vacancies.append(dict(
          id=item['id'],
          name=item['name'],
          salary_from=item['salary']['from'] if item['salary'] else None,
          salary_to=item['salary']['to'] if item['salary'] else None,
          currency = item['salary']['currency'] if item['salary'] else None,
          created=item['published_at'],
          company=item['employer']['name'],
          area = item['area']['name'],
          url=item['alternate_url']
      ))
  results.append(vacancies)
 

Результатом будет прекрасный список всех элементов.

Комментарии:

1. Этот код, если len (вакансии)> 0: переходит на следующую страницу, но не переходит на следующую и не сохраняет полный результат всех страниц. Это дает результат только для страницы, на которую я перешел, мне нужно собрать результаты по всем страницам.

2. Странный этот код для i в вакансиях: params[«страница»] = 1 находит сотню страниц. Хотя результатов всего пять страниц.

3. Вы могли бы посмотреть мой colab colab.research.google.com/drive /… ?

4. Я изменил Colab для выполнения вычисления для каждого элемента на странице и отредактировал свой ответ, чтобы показать обновленный код

5. Извините, я забыл включить режим редактора, результаты не были сохранены. Если это не сложно, отредактируйте его еще раз.

Ответ №2:

vacancies никогда. True Если вы хотите протестировать логическое значение «вакансий», вы можете использовать bool(vacancies) . Но с помощью Python вы можете использовать

 while vacancies:
  # some code logic
 

Таким образом, Python автоматически преобразует ваш список в bool.
Если ваш список как что-то внутри ( len(your_list) > 0 ), bool(your_list) вычисляется True , иначе это False .

Кроме того, вместо использования dict() вы могли бы написать свой dict таким образом:

 params = {
    'order_by': 'salary_desc',
    'text':keyword,
    'area': area,
    'period': 30, # days
    'per_page': 100,
    'page': 0,
    'no_magic': 'false',  # disable magic
    'search_field': 'name'  # available: name, description, company_name
}
 

что является более питоническим.

Комментарии:

1. Не могли бы вы показать ответ на ваш запрос api? Я не видел, чтобы логика в этом случае была плохой, вы действительно получите бесконечный цикл

2. Я делаю запрос в Google colab. Он не дает ответа, он просто вращается в ячейке. Вы можете увидеть мою статью по ссылке colab.research.google.com/drive /…