Как начать разбирать этот блок данных JSON?

Я хотел бы сделать программу, которая делает автономные копии математических вопросов из Академии Хана. У меня огромный текстовый файл размером 21,6 МБ, содержащий данные обо всех их упражнениях, но я не знаю, как начать анализировать его, тем более начать извлекать из него вопросы.

Вот пастбин, содержащий образец данных JSON. Если вы хотите увидеть все это, вы можете найти его здесь. Предупреждение о длительной загрузке.

Я никогда раньше не использовал JSON, но я написал быстрый скрипт на Python, чтобы попытаться загрузить отдельные "подблоки" (или эквивалентный, правильный термин) данных.

import sys
import json

exercises = open("exercises.txt", "r+b")
byte = 0
frontbracket = 0
backbracket = 0
while byte < 1000: #while byte < character we want to read up to
                   #keep at 1000 for testing purposes
    char = exercises.read(1)
    sys.stdout.write(char)
    #Here we decide what to do based on what char we have
    if str(char) == "{":
        frontbracket = byte
        while True:
            char = exercises.read(1)
            if str(char)=="}":
                backbracket=byte
                break
        exercises.seek(frontbracket)
        block = exercises.read(backbracket-frontbracket)
        print "Block is " + str(backbracket-frontbracket) + " bytes long"
        jsonblock = json.loads(block)
        sys.stdout.write(block)
        print jsonblock["translated_display_name"]
        print "\nENDBLOCK\n"


    byte = byte + 1

1 ответ

Решение

Хорошо, повторяющийся шаблон выглядит так: http://pastebin.com/4nSnLEFZ

Чтобы получить представление о структуре ответа, вы можете использовать JSONlint для копирования / вставки фрагментов вашей строки и "проверки". Даже если скопированная вами часть недопустима, она все равно отформатирует ее во что-то, что вы действительно сможете прочитать.

Сначала я использовал requests библиотека, чтобы вытащить JSON для вас. Это очень простая библиотека, когда вы имеете дело с такими вещами. API реагирует медленно, потому что кажется, что вы все тянете, но оно должно работать нормально.

Получив ответ от API, вы можете преобразовать его непосредственно в объекты Python, используя .json(), То, что у вас есть, - это, по сути, смесь вложенных списков и словарей, по которым вы можете перебирать и извлекать конкретные детали. В моем примере ниже, my_list2 должен использовать try/except структура, потому что может показаться, что некоторые записи не имеют двух элементов в списке под translated_problem_types, В этом случае вместо него будет просто "Нет". Возможно, вам придется использовать метод проб и ошибок для таких вещей.

Наконец, поскольку вы раньше не использовали JSON, также стоит отметить, что он может вести себя как сам словарь; Вам не гарантирован порядок, в котором вы получаете детали. Однако в этом случае кажется, что самая внешняя структура - это список, поэтому теоретически возможно, что существует последовательный порядок, но мы не полагаемся на него - мы не знаем, как составлен список.

import requests

api_call = requests.get('https://www.khanacademy.org/api/v1/exercises')
json_response = api_call.json()

# Assume we first want to list "author name" with "author key"
# This should loop through the repeated pattern in the pastebin 
# access items as a dictionary
my_list1 = []

for item in json_response:
    my_list1.append([item['author_name'], item['author_key']])

print my_list1[0:5]

# Now let's assume we want the 'sha' of the SECOND entry in translated_problem_types
# to also be listed with author name

my_list2 = []

for item in json_response:
    try:
        the_second_entry = item['translated_problem_types'][0]['items'][1]['sha']
    except IndexError:
        the_second_entry = 'None'

    my_list2.append([item['author_name'], item['author_key'], the_second_entry])
print my_list2[0:5]
Другие вопросы по тегам