2016-08-16 9 views
0

Ich möchte ein Programm machen, das Offline-Kopien von mathematischen Fragen von Khan Academy macht. Ich habe eine riesige 21,6 MB große Textdatei, die Daten zu allen ihren Übungen enthält, aber ich habe keine Ahnung, wie ich anfangen soll, sie zu analysieren, geschweige denn, die Fragen daraus zu ziehen.Wie kann ich diesen Block von JSON-Daten auseinanderziehen?

Here ist eine Pastebin, die eine Probe der JSON-Daten enthält. Wenn Sie alles sehen wollen, können Sie es here finden. Warnung für lange Ladezeit.

Ich habe noch nie zuvor JSON verwendet, aber ich schrieb ein schnelles Python-Skript, um zu versuchen, einzelne "Unterblöcke" (oder gleichwertige, korrekte Begriffe) von Daten zu laden.

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

Sie sind nicht in Betracht verschachtelten Klammern unter ... können Sie einen Stapel verwenden Spur davon zu halten. – danielfranca

+1

Sie können etwas wie [jsonlint] (http://jsonlint.com/) verwenden, um Teile des JSON zu kopieren oder einzufügen, um es zumindest lesbar zu machen. Ich denke, ich habe ein wiederholtes Muster gefunden, aber weißt du, nach welchen Daten du eigentlich suchst? Sobald Sie es in 'json' laden, können Sie es als verschachtelte Listen und Wörterbücher behandeln. – roganjosh

+1

Dies scheint Ihr sich wiederholendes Muster zu sein: http://pastebin.com/4nSnLEFZ – roganjosh

Antwort

1

Ok, das sich wiederholendes Muster, dies zu sein scheint: http://pastebin.com/4nSnLEFZ

Um eine Vorstellung von der Struktur der Antwort zu erhalten, können Sie JSONlint verwenden zum Kopieren/Einfügen Teile Ihrer Zeichenfolge und ‚Validate‘. Selbst wenn der kopierte Teil nicht gültig ist, wird er dennoch in etwas formatiert, das Sie tatsächlich lesen können.

Zuerst habe ich requests Bibliothek verwendet, um den JSON für Sie zu ziehen. Es ist eine sehr einfache Bibliothek, wenn Sie mit solchen Dingen zu tun haben. Die API ist langsam zu reagieren, weil es scheint, dass Sie alles ziehen, aber es sollte gut funktionieren. Wenn Sie eine Antwort von der API erhalten, können Sie diese direkt in Python-Objekte konvertieren, indem Sie .json() verwenden. Was Sie haben, ist im Wesentlichen eine Mischung aus verschachtelten Listen und Wörterbüchern, die Sie durchlaufen und spezifische Details ziehen können. In meinem Beispiel unten muss my_list2 eine try/except Struktur verwenden, da einige Einträge scheinbar nicht zwei Einträge in der Liste unter translated_problem_types enthalten. In diesem Fall wird nur "None" gesetzt. Sie müssen möglicherweise für diese Dinge Versuch und Irrtum verwenden.

Da Sie JSON noch nicht zuvor verwendet haben, ist es auch erwähnenswert, dass es sich wie ein Wörterbuch selbst verhalten kann; Sie sind nicht sicher, in welcher Reihenfolge Sie Details erhalten. In diesem Fall scheint die äußerste Struktur jedoch eine Liste zu sein, so dass es theoretisch möglich ist, dass es eine konsistente Ordnung gibt, aber verlassen Sie sich nicht darauf - wir wissen nicht, wie die Liste aufgebaut ist.

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

Vielen Dank! Jetzt bin ich dran, um herauszufinden, wie man den Fragetext daraus als Tabelle zieht. Ich denke Web-Scraper gerichtet auf den "Relativ-URL" -Element. Danke nochmal! – Xeneficus

+0

@Xeneficus sehr willkommen :) Die API-Antwort ist umständlich zu graben in der Art, die ich habe. Sie sollten wahrscheinlich versuchen, etwas mehr über die API selbst zu verstehen, um Ihre Anfrage anzusprechen und nur die Informationen zu erhalten, die Sie interessieren. Dies wird a) die Antwortzeit verbessern und b) lächerliche Dinge wie 'item [' translated_problem_types '] [0 ] ['items'] [1] ['sha'] 'für einen einzelnen Wert. Viel Glück :) – roganjosh

Verwandte Themen