0

我想制作一个程序,可以离线复制可汗学院的数学问题。我有一个 21.6MB 的巨大文本文件,其中包含他们所有练习的数据,但我不知道如何开始分析它,更不用说开始从中提取问题了。

是一个包含 JSON 数据样本的 pastebin。如果您想查看所有内容,可以在这里找到。加载时间过长的警告。

我以前从未使用过 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
4

1 回答 1

1

好的,重复的模式似乎是这样的:http: //pastebin.com/4nSnLEFZ

要了解响应的结构,您可以使用JSONlint复制/粘贴部分字符串并“验证”。即使您复制的部分无效,它仍会将其格式化为您可以实际阅读的内容。

首先,我使用requests库为您提取 JSON。当你处理这样的事情时,它是一个超级简单的库。API 响应缓慢,因为您似乎正在拉动所有内容,但它应该可以正常工作。

从 API 获得响应后,您可以使用.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]
于 2016-08-16T16:07:01.173 回答