Соберите несколько значений из файла JSON через API в python, где некоторые значения могут быть пустыми / []

Я хочу извлечь значения научных публикаций из API openalex. Однако, поскольку этот API не имеет полных значений для всех публикаций, результирующий файл JSON не всегда является полным. Если файл завершен, мой код будет работать без проблем. Если у API нет всей доступной информации, может случиться так, что следующий результат будет найден, но не может быть интерпретирован: "учреждения":[] вместо "учреждения":[{"id":"https://openalex.org /I2057...}{...}].В результате я всегда получаю "IndexError: индекс списка вне допустимого диапазона".

После долгих поисков я уже пытался решить проблему с помощью try/except или if-запросов (если требуется, то могу и их предоставить). К сожалению, мне это не удалось.

Моя цель состоит в том, чтобы в charlist, в местах, где информация недоступна ([]), было введено None или Null. Цель состоит в том, чтобы запрограммировать код как можно более производительным, поскольку у меня будет большое шестизначное количество запросов. Это, конечно, уже согласовано с оператором API.

Мой приведенный ниже код уже работает для полных файлов JSON (верхний magid_list), но не для неполных записей (2301544176), как в нижнем, не закомментированном magid_list.

import requests
import json

baseurl = 'https://api.openalex.org/works?filter=ids.mag:'

#**upper magid_listworks without problems**
#magid_list = [2301543590, 2301543835]

#**error occur**
#**see page "https://api.openalex.org/works?filter=ids.mag:2301544176" no information for institution given**
magid_list = [2301543590, 2301543835, 2301544176]

def main_request(baseurl, endpoint):
    r = requests.get(baseurl + endpoint)
    return r.json()

def parse_json(response):
    charlist = []
    pupdate = data['results'][0]['publication_date']
    display_name = data['results'][0]['display_name']
    for item in response['results'][0]['authorships']:
        char = {
        'magid': str(x),
        'display_name': display_name,
        'pupdate': pupdate,
        'author': item['author']['display_name'],
        'institution_id': item['institutions'][0]['id']
        }
        
        charlist.append(char)
    return charlist

finallist = []

for x in magid_list:
    print(x)
    data = main_request(baseurl, str(x))
    finallist.extend(parse_json(main_request(baseurl, str(x))))

df = pd.DataFrame(finallist)

print(df.head(), df.tail())

Если я могу предоставить дополнительную информацию или разъяснения, дайте мне знать.

В приложении вы можете найти полную трассировку IndexError:

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
f:\AlexPE\__programming\Masterarbeit.ipynb Cell 153 in <cell line: 37>()
     37 for x in list:
     38     print(x)
---> 39     finallist.extend(parse_json(main_request(baseurl, str(x))))
     41 df = pd.DataFrame(finallist)
     43 #data = main_request(baseurl, endpoint)
     44 #print(get_pages(data))
     45 #print(parse_json(data))

f:\AlexPE\__programming\Masterarbeit.ipynb Cell 153 in parse_json(response)
     20 display_name = data['results'][0]['display_name']
     23 for item in response['results'][0]['authorships']:
     24     char = {
     25     'magid': str(x),
     26     'display_name': display_name,
     27     'pupdate': pupdate,
     28     'author': item['author']['display_name'],
---> 29     'institution_id': item['institutions'][0]['id']
     30     }
     32     charlist.append(char)
     33 return charlist

IndexError: list index out of range 

Вам нужно убедиться, что элемент списка существует, прежде чем пытаться получить к нему доступ. Поскольку вы получаете доступ только к 0-му элементу любого из списков, это так же просто, как if item['institutions']:. Если вам нужна дополнительная помощь, предоставьте полную трассировку, есть несколько мест, где может возникнуть ошибка IndexError. Пожалуйста, никогда не используйте list в качестве имени переменной, это очень часто используемый встроенный объект, который затирается при использовании в качестве имени переменной.

Michael Ruth 21.11.2022 18:50

Большое спасибо за Ваш ответ. Честно говоря, я уже пробовал оператор If, но не смог заставить его работать. Мне кажется, к сожалению, как будто у меня там ошибка мышления. В посте я добавил трассировку IndexError, которую я теперь получаю в Python. Спасибо за подсказку со списком. Я изменил это прямо в коде, очень хороший момент.

Alex Peter 21.11.2022 19:19

Я не знаю, что вы хотите сделать с результатом, в котором нет пункта для учреждений, но вы можете использовать try: char = {...}; except IndexError: print("an exception occured"); else: charlist.append(char);

Shmack 21.11.2022 19:20

Спасибо, Smack, за ваше решение! Код выполняется без сообщения об ошибке. Однако возможно ли, что эта функция не «пропускает» полный magID, а только заполняет отсутствующие значения «Null»? Этот список является лишь небольшой частью большого набора данных, который в настоящее время содержит только magID. Для многих magID отсутствует только учреждение, но присутствуют остальные данные. Поэтому данные для меня ценны, и недостающие данные я добавлю вручную или с помощью алгоритма позднее. Каждый бит данных, который мне не нужно добавлять вручную, очень ценен для меня.

Alex Peter 21.11.2022 19:49
Мутабельность и переработка объектов в Python
Мутабельность и переработка объектов в Python
Объекты являются основной конструкцией любого языка ООП, и каждый язык определяет свой собственный синтаксис для их создания, обновления и...
Другой маршрут в Flask Python
Другой маршрут в Flask Python
Flask - это фреймворк, который поддерживает веб-приложения. В этой статье я покажу, как мы можем использовать @app .route в flask, чтобы иметь другую...
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
Проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
Python PyPDF2 - запись метаданных PDF
Python PyPDF2 - запись метаданных PDF
Python скрипт, который будет записывать метаданные в PDF файл, для этого мы будем использовать PDF ридер из библиотеки PyPDF2 . PyPDF2 - это...
Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
Почему Python - идеальный выбор для проекта AI и ML
Почему Python - идеальный выбор для проекта AI и ML
Блог, которым поделился Harikrishna Kundariya в нашем сообществе Developer Nation Community.
0
4
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проверьте наличие значений, прежде чем пытаться получить к ним доступ:

def parse_json(response):
    charlist = []
    pupdate = display_name = None
    if data['results']:
        pupdate = data['results'][0].get('publication_date')
        display_name = data['results'][0].get('display_name')
    for item in response['results'][0]['authorships']:
        institution_id = None
        if item['institutions']:
            institution_id = item['institutions'][0].get('id')
        char = {
        'magid': str(x),
        'display_name': display_name,
        'pupdate': pupdate,
        'author': item['author']['display_name'],
        'institution_id': institution_id
        }
        
        charlist.append(char)
    return charlist

Большое спасибо! Эта небольшая разница в коде заставила его работать! Спасибо вам всем!

Alex Peter 21.11.2022 20:07

Другие вопросы по теме