JSON из (RIOT) API отформатирован неправильно

#python #json #api #riot-games-api

#python #json #API #riot-games-api

Вопрос:

Я импортирую данные JSON в Python из API и столкнулся со следующей ошибкой декодирования:

 JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
  

Просматривая онлайн-примеры, сразу становится ясно, что мои данные JSON имеют ' то, что есть у других " .

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

Я решил, что исправить формат JSON должно быть легко, но и здесь я потерпел неудачу. Пожалуйста, смотрите приведенный ниже код о том, как я получаю данные JSON и мою попытку их исправить.

 #----------------------------------------
#---Read this only if you want to download 
#---the data yourself. 
#----------------------------------------

#Built from 'Towards Data Science' guide
#https://towardsdatascience.com/how-to-use-riot-api-with-python-b93be82dbbd6

#Must first have installed riotwatcher

#Info in my example is made up, I can't supply a real API code or
#I get in trouble. Sorry about this. You could obtain one from their website
#but this would be a lot of faff for what is probably a simple StackOverflow
#question

#If you were to get/have a key you could use the following information:
#<EUW> for region
#<Agurin> for name

#----------------------------------------
#---Code
#----------------------------------------


#--->Set Variables


#Get installed riotwatcher module for
#Python
import riotwatcher

#Import riotwatcher tools.
from riotwatcher import LolWatcher, ApiError

#Import JSON (to read the JSON API file)
import json

# Global variables
# Get new API from
# https://developer.riotgames.com/
api_key = 'RGAPI-XXXXXXX-XXX-XXXX-XXXX-XXXX'
watcher = LolWatcher(api_key)
my_region = 'MiddleEarth'

#need to give path to where records
#are to be stored
records_dir = "/home/solebaysharp/Projects/Riot API/Records"


#--->Obtain initial data, setup new varaibles

#Use 'watcher' to get basic stats and setup my account as a variable (me)
me = watcher.summoner.by_name(my_region, "SolebaySharp")

# Setup retrieval of recent match info
my_matches = watcher.match.matchlist_by_account(my_region, me["accountId"])
print(my_matches)

#--->Download the recent match data

#Define where the JSON data is going to go
recent_matches_index_json = (records_dir   "/recent_matches_index.json")

#get that JSON data
print ("Downloading recent match history data")
file_handle = open(recent_matches_index_json,"w ")
file_handle.write(str(my_matches))
file_handle.close()

#convert it to python
file_handle = open(recent_matches_index_json,)
recent_matches_index = json.load(file_handle)
  

Кроме этого выдает следующую ошибку…

 JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
  

Поэтому вместо того, чтобы исправить это, я попытался:

 file_handle = open(recent_matches_index_json)

json_sanitised = json.loads(file_handle.replace("'", '"'))
  

Это возвращает…

 AttributeError: '_io.TextIOWrapper' object has no attribute 'replace'
  

Для полноты картины ниже приведен пример того, как выглядит JSON. Я добавил абзацы для улучшения читаемости. Это происходит не так.

 {'matches': [
  {'platformId': 'NA1',
   'gameId': 5687555181,
   'champion': 235,
   'queue': 400,
   'season': 13,
   'timestamp': 1598243995076,
   'role': 'DUO_SUPPORT',
   'lane': 'BOTTOM'
   },
   {'platformId': 'NA1',
   'gameId': 4965733458,
   'champion': 235,
   'queue': 400,
   'season': 13,
   'timestamp': 1598240780841,
   'role': 'DUO_SUPPORT',
   'lane': 'BOTTOM'
   },
   {'platformId': 'NA1',
   'gameId': 4583215645,
   'champion': 111,
   'queue': 400,
   'season': 13,
   'timestamp': 1598236666162,
   'role': 'DUO_SUPPORT',
   'lane': 'BOTTOM'
   }],
'startIndex': 0,
'endIndex': 100,
'totalGames': 186}
  

Ответ №1:

Это происходит потому, что Python преобразует JSON в строку ( str ).

 file_handle.write(str(my_matches))
  

Поскольку он не видит разницы между ' и " , он просто использует значение по умолчанию ' .

Мы можем предотвратить это с помощью JSON.dumps . Это частично (конечно, не полностью) отвечает и на вторую часть вопроса, поскольку мы используем правильно отформатированную команду JSON.

Вышеупомянутая строка просто должна быть заменена на эту:

 file_handle.write(json.dumps(my_matches))
  

Это сохранит форматирование JSON.