Percurso recursivo por um arquivo JSON extraindo cadeias SELECTED
Eu preciso percorrer recursivamente os arquivos JSON (postar respostas de uma API), extraindo as strings que têm ["text"] como chave{"text":"this is a string"}
Preciso começar a analisar a partir da fonte que possui a data mais antiga em metadados, extrair as seqüências de caracteres dessa fonte e depois passar para a segunda fonte mais antiga e assim por diante. O arquivo JSON pode estar muito aninhado e o nível em que as strings estão pode mudar de tempos em tempos.
Problema: Existem muitas chaves chamadas ["text"] e eu não preciso de todas, apenas as que possuem valores como string. Melhor, o "text": "string" que eu preciso está SEMPRE no mesmo objeto {} de um"type":"sentence"
. Veja a imagem.
O que estou perguntando
Modifique o 2º código abaixo para percorrer recursivamente o arquivo e extrair SOMENTE os valores ["text"] quando estiverem no mesmo objeto {} junto com "type": "sentença".
Abaixo de um trecho do arquivo JSON (em verde o texto que eu preciso e a medatada, em vermelho os que eu não preciso extrair):
Link para a amostra JSON completa:http://pastebin.com/0NS5BiDk
O que eu fiz até agora:
1) O caminho mais fácil: transforme o arquivo json em string e pesquise conteúdo entre aspas duplas (""), porque em todas as respostas do json post as "strings" que eu preciso são as únicas que aparecem entre aspas duplas. No entanto, esta opção me impede de solicitar os recursos anteriormente, portanto, não é bom o suficiente.
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) Maneira mais inteligente: percorra recursivamente um arquivo JSON e extraia os valores ["text"]
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"))
Extrai todos os valores que têm ["texto"] como chave. Infelizmente no arquivo existem outras coisas (das quais não preciso) que tenham ["text"] como Key. Portanto, ele retorna um texto que eu não preciso.
Por favor informar.
ATUALIZAR
Eu escrevi 2 códigos para classificar a lista de objetos por uma determinada chave. O primeiro classifica pelo 'texto' do xml. O segundo pelo valor 'Compreendendo o período de'.
O primeiro funciona, mas alguns XMLs, mesmo que sejam maiores em número, na verdade têm documentos dentro mais antigos do que eu esperava.
Para o segundo código, o formato 'Período compreensivo de' não é consistente e, às vezes, o valor não está presente. O segundo também me dá um erro, mas não consigo descobrir por que -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))