Я хочу извлечь значения научных публикаций из 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
Большое спасибо за Ваш ответ. Честно говоря, я уже пробовал оператор If, но не смог заставить его работать. Мне кажется, к сожалению, как будто у меня там ошибка мышления. В посте я добавил трассировку IndexError, которую я теперь получаю в Python. Спасибо за подсказку со списком. Я изменил это прямо в коде, очень хороший момент.
Я не знаю, что вы хотите сделать с результатом, в котором нет пункта для учреждений, но вы можете использовать try: char = {...}; except IndexError: print("an exception occured"); else: charlist.append(char);
Спасибо, Smack, за ваше решение! Код выполняется без сообщения об ошибке. Однако возможно ли, что эта функция не «пропускает» полный magID, а только заполняет отсутствующие значения «Null»? Этот список является лишь небольшой частью большого набора данных, который в настоящее время содержит только magID. Для многих magID отсутствует только учреждение, но присутствуют остальные данные. Поэтому данные для меня ценны, и недостающие данные я добавлю вручную или с помощью алгоритма позднее. Каждый бит данных, который мне не нужно добавлять вручную, очень ценен для меня.
Проверьте наличие значений, прежде чем пытаться получить к ним доступ:
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
Большое спасибо! Эта небольшая разница в коде заставила его работать! Спасибо вам всем!
Вам нужно убедиться, что элемент списка существует, прежде чем пытаться получить к нему доступ. Поскольку вы получаете доступ только к 0-му элементу любого из списков, это так же просто, как if item['institutions']:. Если вам нужна дополнительная помощь, предоставьте полную трассировку, есть несколько мест, где может возникнуть ошибка IndexError. Пожалуйста, никогда не используйте list в качестве имени переменной, это очень часто используемый встроенный объект, который затирается при использовании в качестве имени переменной.