Recorrido recursivo a través de un archivo JSON que extrae cadenas SELECCIONADAS
Necesito recorrer recursivamente los archivos JSON (publicar respuestas de una API), extrayendo las cadenas que tienen ["texto"] como clave{"text":"this is a string"}
Necesito comenzar a analizar desde la fuente que tiene la fecha más antigua en los metadatos, extraer las cadenas de esa fuente y luego pasar a la segunda fuente más antigua y así sucesivamente. El archivo JSON podría estar mal anidado y el nivel donde se encuentran las cadenas puede cambiar de vez en cuando.
Problema: hay muchas claves llamadas ["texto"] y no las necesito todas, SOLO necesito las que tienen valores como cadena. Mejor, el "texto": "cadena" que necesito SIEMPRE está en el mismo objeto {} de un"type":"sentence"
. Ver imagen
Lo que pregunto
Modifique el segundo código a continuación para recorrer recursivamente el archivo y extraer SOLAMENTE los valores ["texto"] cuando están en el mismo objeto {} junto con "tipo": "oración".
Debajo de un fragmento de archivo JSON (en verde el texto que necesito y la metadada, en rojo los que no necesito extraer):
Enlace al ejemplo completo de JSON:http://pastebin.com/0NS5BiDk
Lo que he hecho hasta ahora:
1) La manera fácil: transformar el archivo json en cadena y buscar contenido entre comillas dobles ("") porque en todas las respuestas de la publicación json las "cadenas" que necesito son las únicas entre comillas dobles. Sin embargo, esta opción me impide ordenar los recursos previamente, por lo tanto, no es lo suficientemente bueno.
r1 = s.post(url2, data=payload1)
j = str(r1.json())
sentences_list = (re.findall(r'\"(.+?)\"', j))
numentries = 0
for sentences in sentences_list:
numentries += 1
print(sentences)
print(numentries)
2) Manera más inteligente: recorre recursivamente un archivo JSON y extrae los valores ["texto"]
def get_all(myjson, key):
if type(myjson) is dict:
for jsonkey in (myjson):
if type(myjson[jsonkey]) in (list, dict):
get_all(myjson[jsonkey], key)
elif jsonkey == key:
print (myjson[jsonkey])
elif type(myjson) is list:
for item in myjson:
if type(item) in (list, dict):
get_all(item, key)
print(get_all(r1.json(), "text"))
Extrae todos los valores que tienen ["texto"] como clave. Desafortunadamente en el archivo hay otras cosas (que no necesito) que tienen ["texto"] como clave. Por lo tanto, devuelve texto que no necesito.
Por favor avise.
ACTUALIZAR
He escrito 2 códigos para ordenar la lista de objetos por una determinada clave. El primero se ordena por el 'texto' del xml. El segundo por valor 'Comprender período de'.
El primero funciona, pero algunos de los XML, incluso si son más altos en número, en realidad tienen documentos más antiguos de lo que esperaba.
Para el segundo código, el formato de 'Período comprendido desde' no es consistente y, a veces, el valor no está presente en absoluto. El segundo también me da un error, pero no puedo entender por qué:string indices must be integers
.
# 1st code (it works but not ideal)
j=r1.json()
list = []
for row in j["tree"]["children"][0]["children"]:
list.append(row)
newlist = sorted(list, key=lambda k: k['text'][-9:])
print(newlist)
# 2nd code I need something to expect missing values and to solve the
# list index error
list = []
for row in j["tree"]["children"][0]["children"]:
list.append(row)
def date(key):
return dparser.parse((' '.join(key.split(' ')[-3:])),fuzzy=True)
def order(list_to_order):
try:
return sorted(list_to_order,
key=lambda k: k[date(["metadata"][0]["value"])])
except ValueError:
return 0
print(order(list))