C'est un problème tellement étrange que je ne sais même pas comment poser, mais je vais essayer. J'ai quelques fichiers json qui contiennent des données Web scrape, plusieurs entrées par fichier et ils ressemblent à ceci:
# Read the file f = codecs.open(file, 'r', encoding='utf-8-sig', errors='replace') text = f.read() f.close() # Check if }{ was found; # this prints nothing for original files but finds everything in a hand written file pattern = '}{' print('Before editing: ', (re.findall(pattern, text))) # Getting rid of excess newlines and whitespaces newtext = " ".join(text.split()) # Check if } { was found; # this prints nothing for original files but finds everything in a hand written file pattern = '} {' print('After editing: ', (re.findall(pattern, newtext))) # Put newlines in the right places finaltext = re.sub('} {', '}\n{', newtext) # Write the new JSON newfile = file[:-5]+'_ED.json' nf = codecs.open(newfile, 'w', encoding='utf-8', errors='replace') nf.write(finaltext) nf.close()
J'essayais de les formater pour que chaque entrée soit indépendante ligne, comme ceci:
{"doc_id": blah blah....} {"doc_id": blah blah blah...}
J'ai donc fait ceci:
{ "doc_id": "some_number", "url": "www.seedurl1.com", "scrape_date": "2019-10-22 16:17:22", "publish_date": "unknown", "author": "unknown", "urls_out": [ "https://www.something.com", "https://www.sometingelse.com/smth" ], "text": "lots of text here" } { "doc_id": "some_other_number", "url": "www.seedurl2.com/smth", "scrape_date": "2019-10-22 17:44:40", "publish_date": "unknown", "author": "unknown", "urls_out": [ "www.anotherurl.com/smth", "http://urlx.com/smth.htm" ], "text": "lots more text over here." }
Le fait est que le code fonctionne parfaitement sur un fichier de test écrit à la main avec la même structure, mais pas avec les fichiers originaux, ou les fichiers de test plus petits dérivés des originaux.
J'ai essayé de faire une recherche simple pour "}" et "{" séparément dans un éditeur de texte, ce qui s'avère correct. Mais si j'essaye de rechercher "} {" ou "} {", rien n'est trouvé. Bien que je puisse voir qu'ils sont clairement là.
Une dernière découverte: j'ai essayé d'ouvrir la version modifiée de mon petit fichier de test dans Nano sous Linux et je me suis déplacé sur la zone à problèmes. Pour une raison quelconque, il faut deux pressions sur la touche fléchée droite pour se déplacer sur le crochet "{". Il y a donc clairement quelque chose de bizarre là-dedans. Comment savoir quoi? Ou toute autre suggestion qui pourrait vous aider?
3 Réponses :
La solution la plus simple serait de créer un tableau JSON pour commencer ...
Sinon, je suggérerais de ne rien remplacer et de compter simplement les crochets correspondants.
{"doc_id": "some_number","url": "www.seedurl1.com","scrape_date": "2019-10-22 16:17:22","publish_date": "unknown","author": "unknown","urls_out": ["https://www.something.com","https://www.sometingelse.com/smth"],"text": "lots of text here"} {"doc_id": "some_other_number","url": "www.seedurl2.com/smth","scrape_date": "2019-10-22 17:44:40","publish_date": "unknown","author": "unknown","urls_out": ["www.anotherurl.com/smth","http://urlx.com/smth.htm"],"text": "lots more text over here."} found 2 objects
Pour le texte donné, je me suis retrouvé avec ceci
count = 0 objects = 0 with open('file.txt') as f: for i, c in enumerate(f.read()): if c == '\n': continue elif c == '{': if i > 0 and count == 0: print() # start new line before printing bracket count += 1 elif c == '}': count -= 1 if count == 0: # found a complete JSON object objects += 1 print(c, end='') print(f'\n\nfound {objects} objects') # for debugging
Cela fonctionnait même avec les fichiers problématiques! Merci beaucoup!
J'ai choisi celle-ci comme réponse acceptée car elle fonctionnait avant de découvrir quel était le problème avec mes fichiers. Après avoir découvert mon problème, la réponse de @Saharsh a également fonctionné et était plus simple (à mon avis).
C'est une approche.
{'doc_id': 'some_number', 'url': 'www.seedurl1.com',..... {'doc_id': 'some_other_number', 'url': 'www.seedurl2.com/smth',.....
Sortie:^
import json with open(filename) as infile: data = json.loads("[" + infile.read().replace("}\n{", "},\n{") + "]") for i in data: print(i)
p>
Voici une autre solution qui est un peu proche de ce que vous tentiez de tenter
{'doc_id': 'some_number', 'url': 'www.seedurl1.com', 'scrape_date': '2019-10-22 16:17:22', 'publish_date': 'unknown', 'author': 'unknown', 'urls_out': ['https://www.something.com', 'https://www.sometingelse.com/smth'], 'text': 'lots of text here'} {'doc_id': 'some_number', 'url': 'www.seedurl1.com', 'scrape_date': '2019-10-22 16:17:22', 'publish_date': 'unknown', 'author': 'unknown', 'urls_out': ['https://www.something.com', 'https://www.sometingelse.com/smth'], 'text': 'lots of text here'}
json
est utilisé ici pour valider le JSON individuel uniquement. Cela donne
import json with open('test.txt') as f: file = f.readlines() file = ['{'+i+'}'for i in "".join("".join(file).split("\n"))[1:-1].split("}{")] for i in file: print(json.loads(i))
Oops. Besoin de gérer l'espace, je pense et nous devrions être d'accord. Laissez-moi travailler là-dessus. Merci @ cricket_007
Mise à jour de la réponse. J'ai complètement oublié d'ajouter \ n
dans split ()
qui supprimait tous les espaces blancs.
J'ai essayé celui-ci et il s'est avéré très utile. Au début, il ne s'est pas divisé en "} {"
mais après avoir imprimé le résultat, il m'a montré qu'il y avait un \ ufeff
caché entre les accolades, donc split ("} \ ufeff {")
a résolu le problème. Merci!
Au lieu de donner le {ou}, pouvez-vous essayer de copier-coller le modèle directement à partir des données? Parfois, il y a des caractères non-utf-8 cachés à la vue de tous.
Pourquoi n'utilisez-vous pas la bibliothèque
json
de python? C'est beaucoup plus pratique pour les opérations et le débogage comme celui-ci.@Saharsh Parce que le fichier n'est pas JSON valide?
est-ce que cela aide? pypi.org/project/json-lines
@ cricket_007 mon mauvais. Je ne savais pas que le fichier initial peut avoir la syntaxe définie par OP.
@Saharsh J'ai d'abord essayé de créer un dictionnaire à partir du fichier json avec la bibliothèque, mais cela n'a pas fonctionné.
@morko cela ne fonctionnera que si le fichier est un JSON valide et à partir de votre message, il semble qu'il y ait une possibilité que ce ne soit pas le cas (à cause de votre formatage personnalisé)
".. mais pas avec les fichiers originaux .." Pas comment ? Que se passe-t-il à la place? "Cela n'a pas fonctionné" peut être une description précise, mais cela ne nous aide pas.