Sto cercando di analizzare il pianeta.osm di OpenStreetMap, compresso in formato bz2. Poiché è già 41G, non voglio decomprimere completamente il file.Analisi di un file .bz2 di grandi dimensioni (40 GB) con lxml iterparse in python. Errore non visualizzato con file non compresso
Così ho capito come analizzare parti del file planet.osm utilizzando bz2 e lxml, utilizzando il seguente codice
from lxml import etree as et
from bz2 import BZ2File
path = "where/my/fileis.osm.bz2"
with BZ2File(path) as xml_file:
parser = et.iterparse(xml_file, events=('end',))
for events, elem in parser:
if elem.tag == "tag":
continue
if elem.tag == "node":
(do something)
## Do some cleaning
# Get rid of that element
elem.clear()
# Also eliminate now-empty references from the root node to node
while elem.getprevious() is not None:
del elem.getparent()[0]
che funziona perfettamente con il Geofabrick extracts. Tuttavia, quando si tenta di analizzare il pianeta-latest.osm.bz2 con lo stesso script ottengo l'errore:
xml.etree.XMLSyntaxError: Specification mandate value for attribute num_change, line 3684, column 60
Qui ci sono le cose che ho provato:
- Controllare il pianeta-latest. osm.bz2 md5sum
- Controlla il pianeta-latest.osm in cui lo script con bz2 si interrompe. Non c'è nessun errore apparente e l'attributo è chiamato "num_changes", non "num_change" come indicato nell'errore
- Inoltre ho fatto qualcosa di stupido, ma l'errore mi ha lasciato perplesso: ho aperto il pianeta-latest.osm.bz2 in mode 'rb' [c = BZ2File ('file.osm.bz2', 'rb')] e poi ha passato c.read() a iterparse(), che mi ha restituito un errore che dice che (stringa molto lunga) non può essere aperta. cosa strana, (molto lunga stringa) termina proprio dove l'errore "Specification mandato valore" si riferisce a ...
Poi provato per decomprimere il primo planet.osm.gz2 usin una semplice
bzcat planet.osm.gz2 > planet.osm
E ha eseguito il parser direttamente su planet.osm. E ... ha funzionato! Sono molto perplesso e non sono riuscito a trovare alcun puntatore sul perché questo possa accadere e su come risolverlo. La mia ipotesi sarebbe che ci sia qualcosa tra la decompressione e l'analisi, ma non ne sono sicuro. Per favore aiutami a capire!
non posso dire per certo, naturalmente, ma il BZ2File (file.osm.bz2 ' , 'rb') 'sembra errato perché il primo argomento è supposto essere un _filename_ (cioè una stringa) secondo i documenti. – martineau
Grazie per aver segnalato questo! Ma era corretto nel codice originale, ho appena modificato la mia domanda per evitare confusione. – scities
Ci potrebbe essere un bug nel modulo bz2 (dubito che venga testato dai manutentori sugli ingressi da 40GB molto spesso). Prova a scrivere uno script Python che usa il modulo bz2 per decomprimere i dati e scriverlo in un nuovo file, e verificare che l'output corrisponda all'output 'bzcat'. –