#json #python-3.x #python-requests #sparql #wikidata
#json #python-3.x #python-запросы #sparql #викиданные
Вопрос:
Я столкнулся с проблемой при попытке запросить данные из викиданных на python и был бы очень признателен за любую помощь.
Хотя в целом он работает (проиллюстрировано ФРАГМЕНТОМ КОДА 1), выполнение кода приводит к ошибке JSONDecodeError, когда запрос слегка модифицируется, чтобы охватить более длительный период (показано ФРАГМЕНТОМ КОДА 2)…
ФРАГМЕНТ КОДА 1:
query = """
SELECT ?person ?personLabel ?dob ?place_of_birth ?place_of_birthLabel ?date_of_death ?place_of_death ?place_of_deathLabel ?political_party ?political_partyLabel ?sex_or_gender ?sex_or_genderLabel ?Wikimedia_import_URL ?occupation ?occupationLabel ?work_location ?work_locationLabel ?educated_at ?educated_atLabel ?imported_from_Wikimedia_project ?imported_from_Wikimedia_projectLabel ?source_website_for_the_property ?stated_in ?stated_inLabel ?religion ?religionLabel ?VIAF_ID ?ISNI ?Deutsche_Biographie_ID ?DBS_ID ?place_of_detention ?place_of_detentionLabel ?country_of_citizenship ?country_of_citizenshipLabel ?member_of_military_unit ?member_of_military_unitLabel ?conflict ?conflictLabel ?military_rank ?military_rankLabel ?military_branch ?military_branchLabel ?participant_in ?participant_inLabel ?award_received ?award_receivedLabel ?described_by_source ?described_by_sourceLabel ?academic_degree ?academic_degreeLabel ?field_of_work ?field_of_workLabel ?noble_title ?noble_titleLabel WHERE {
?person wdt:P31 wd:Q5;
wdt:P569 ?dob.
FILTER(("1870-01-02"^^xsd:dateTime <= ?dob) amp;amp; (?dob <= "1870-01-04"^^xsd:dateTime))
SERVICE wikibase:label { bd:serviceParam wikibase:language "de". }
OPTIONAL { ?person wdt:P19 ?place_of_birth. }
OPTIONAL { ?person wdt:P570 ?date_of_death. }
OPTIONAL { ?person wdt:P20 ?place_of_death. }
OPTIONAL { ?person wdt:P102 ?political_party. }
OPTIONAL { ?person wdt:P21 ?sex_or_gender. }
OPTIONAL { ?person wdt:P4656 ?Wikimedia_import_URL. }
OPTIONAL { ?person wdt:P106 ?occupation. }
OPTIONAL { ?person wdt:P937 ?work_location. }
OPTIONAL { ?person wdt:P69 ?educated_at. }
OPTIONAL { ?person wdt:P143 ?imported_from_Wikimedia_project. }
OPTIONAL { ?person wdt:P1896 ?source_website_for_the_property. }
OPTIONAL { ?person wdt:P248 ?stated_in. }
OPTIONAL { ?person wdt:P140 ?religion. }
OPTIONAL { ?person wdt:P214 ?VIAF_ID. }
OPTIONAL { ?person wdt:P213 ?ISNI. }
OPTIONAL { ?person wdt:P7902 ?Deutsche_Biographie_ID. }
OPTIONAL { ?person wdt:P4007 ?DBS_ID. }
OPTIONAL { ?person wdt:P5019 ?occupation. }
OPTIONAL { ?person wdt:P2632 ?place_of_detention. }
OPTIONAL { ?person wdt:P27 ?country_of_citizenship. }
OPTIONAL { ?person wdt:P7779 ?member_of_military_unit. }
OPTIONAL { ?person wdt:P607 ?conflict. }
OPTIONAL { ?person wdt:P410 ?military_rank. }
OPTIONAL { ?person wdt:P241 ?military_branch. }
OPTIONAL { ?person wdt:P1344 ?participant_in. }
OPTIONAL { ?person wdt:P166 ?award_received. }
OPTIONAL { ?person wdt:P1343 ?described_by_source. }
OPTIONAL { ?person wdt:P512 ?academic_degree. }
OPTIONAL { ?person wdt:P101 ?field_of_work. }
OPTIONAL { ?person wdt:P97 ?noble_title. }
}
"""
import requests
url = 'https://query.wikidata.org/sparql'
r = requests.get(url, params={'format': 'json', 'query': query})
json_format = r.json()
Ошибка возникает, если эта строка из ФРАГМЕНТА КОДА 1:
FILTER(("1870-01-02"^^xsd:dateTime <= ?dob) amp;amp; (?dob <= "1870-01-04"^^xsd:dateTime))
Заменяется этой строкой (ФРАГМЕНТ КОДА 2):
FILTER(("1870-01-02"^^xsd:dateTime <= ?dob) amp;amp; (?dob <= "1874-01-04"^^xsd:dateTime))
Ошибка, возникающая в результате замены, выглядит следующим образом:
json.decoder.JSONDecodeError: Invalid control character at: line 2345752 column 44 (char 64968579)
После просмотра справки в Интернете я добавил «strict = False» в строку, которая отвечает за декодирование (чтобы избавиться от проблем, вызванных включением шаблонов, таких как ‘ n’, в извлеченные данные), в результате чего ФРАГМЕНТ КОДА 3:
import requests
url = 'https://query.wikidata.org/sparql'
r = requests.get(url, params={'format': 'json', 'query': query})
json_format = r.json(strict=False)
Однако это вызвало другой тип ошибки декодирования:
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 2031964 column 9 (char 56246827)
Поэтому я еще раз внес изменения в код, пытаясь избежать функции .json() из библиотеки запросов (ФРАГМЕНТ КОДА 4):
import requests
url = 'https://query.wikidata.org/sparql'
r = requests.get(url, params={'format': 'json', 'query': query})
json_str = r.text
import json
json_format = json.loads(json_str, strict=False)
в результате возникает ошибка декодирования третьего типа:
json.decoder.JSONDecodeError: Expecting ':' delimiter: line 1521988 column 12 (char 42127071)
Я также попытался вручную заменить шаблоны на ‘ n’ из переменной json_str, как определено в последнем фрагменте, установив ‘strict = True’. К сожалению, ни один из моих подходов не работает.
Хорошо, на данный момент это все. Если у кого-нибудь есть идея о том, как решить проблему, я был бы благодарен 🙂
Приветствия, Мариус
Комментарии:
1. Либо поток поврежден из-за явно большего результата, либо в сериализации JSON Blazegraoh есть какая-то ошибка. Вы проверили результат из командной строки?
2. Я попробовал ваш второй запрос из командной строки с
curl
помощью, и, как и ожидалось, он 1) приводит к таймауту 2) вот почему JSON является неполным и 3) содержит ошибку stacktrace, которая 4) делает его недопустимым JSON и 5) не может быть проанализирована стандартным анализатором JSON по уважительной причине. Короче говоря, ваш запрос слишком сложен для общедоступной общей конечной точки.3. Спасибо за ваши комментарии! Основываясь на вашей оценке, я решил проблему, повторяя каждый месяц и каждый год с отдельным запросом, чтобы уменьшить сложность запроса. Работает очень хорошо!