代码之家  ›  专栏  ›  技术社区  ›  dangee1705

在python中将bz2 xml文件转换为json[重复]

  •  3
  • dangee1705  · 技术社区  · 6 年前

    所以我用下面的代码,用bz2和lxml解析了planet.osm文件的一部分

    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]
    

    Geofabrick extracts . 但是,当我尝试用相同的脚本解析planet-latest.osm.bz2时,会得到错误:

    xml.etree.XMLSyntaxError:属性num_change的规范委托值,第3684行,第60列

    以下是我尝试过的:

    • 检查planet-latest.osm.bz2 md5sum
    • 查看planet-latest.osm中bz2脚本停止的位置。没有明显的错误,属性被称为“num_changes”,而不是错误中指出的“num_change”
    • 我也做了一些愚蠢的事情,但这个错误让我困惑:我在模式'rb'[c=bz2 file('file.osm.bz2','rb')]中打开planet-latest.osm.bz2,然后将c.read()传递给iterparse(),后者返回一个错误,告诉我(很长的字符串)无法打开。奇怪的是,(很长的字符串)在“规范授权值”错误所指的地方结束。。。

    然后我尝试用一个简单的

    bzcat planet.osm.gz2 > planet.osm
    

    直接在planet.osm上运行解析器。还有。。。成功了!我对此非常困惑,找不到任何线索来说明为什么会发生这种情况以及如何解决。我猜解压和解析之间会有什么问题,但我不确定。请帮助我理解!

    0 回复  |  直到 10 年前
        1
  •  5
  •   scities    10 年前

    结果发现问题出在压缩的planet.osm文件上。

    如所示 OSM Wiki ,行星文件被压缩为 ,并且bz2 python模块无法读取多流文件。但是,bz2文档指出了一个可以读取这些文件的替代模块, bz2file . 我用过了,效果很好!

    所以代码应该是:

    from lxml import etree as et
    from bz2file 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]
    

    imposm.parser ,一个python模块,它实现了OSM数据的通用解析器(pbf或xml格式)。你可能想看看这个!

        2
  •  2
  •   Messa    10 年前

    作为替代方案,您可以使用 bzcat

    p = subprocess.Popen(["bzcat", "data.bz2"], stdout=subprocess.PIPE)
    parser = et.iterparse(p.stdout, ...)
    # at the end just check that p.returncode == 0 so there were no errors