2016-08-16 64 views
0

我想製作一個程序,讓可汗學院的數學問題離線複製。我有一個巨大的21.6MB文本文件,其中包含所有練習的數據,但我不知道如何開始分析它,更不用說開始從中提取問題。如何開始拉開JSON數據塊?

Here是一個包含JSON數據樣本的pastebin。如果你想看到它,你可以找到它here。長時間加載的警告。

我從來沒有使用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

您沒有考慮嵌套括號......您可以使用堆棧來跟蹤它。 – danielfranca

+1

您可以使用[jsonlint](http://jsonlint.com/)之類的內容來複制/粘貼部分JSON,以便至少以可讀格式獲取它。我想我已經在那裏找到了重複的模式,但是你知道你實際需要的數據嗎?一旦你把它加載到'json'中,那麼你就可以開始將它作爲嵌套列表和字典來處理。 – roganjosh

+1

這似乎是你的重複模式:http://pastebin.com/4nSnLEFZ – roganjosh

回答

1

確定,重複模式似乎是這樣的:http://pastebin.com/4nSnLEFZ

獲得響應的結構的想法,你可以使用JSONlint複製你的字符串/粘貼部分和「驗證」。即使您複製的部分無效,仍會將其格式化爲您實際可以讀取的內容。

首先,我使用requests庫來爲您拉動JSON。當你處理這樣的事情時,這是一個超級簡單的圖書館。該API響應緩慢,因爲它似乎你拉動一切,但它應該工作正常。

從API獲取響應後,可以使用.json()直接將其轉換爲python對象。你所擁有的基本上是嵌套列表和詞典的混合體,你可以遍歷並獲取特定的細節。在下面的示例中,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] 
+0

非常感謝!現在我要弄清楚如何使用這個表格作爲問題文本。我正在考慮將網頁抓取工具定向到「相對網址」項目。再次感謝你! – Xeneficus

+0

@Xeneficus非常歡迎:) API響應很麻煩,以我的方式挖掘。您應該嘗試更多地瞭解API本身以針對您的請求,並且只獲取您感興趣的信息。這將a)提高響應時間並且b)停止像'item ['translated_problem_types'] [0 ] ['items'] [1] ['sha']'爲單個值。祝你好運:) – roganjosh