簡體   English   中英

使用 lxml 解析大型 XML 文件

[英]Parsing large XML file with lxml

我正在嘗試使用 lxml 解析 dblp.xml 文件(3.2gb)。 以下是我的代碼。

from lxml import etree
from io import StringIO, BytesIO
tree = etree.parse("dblp.xml")

但是我收到一條錯誤消息:

OSError                                   Traceback (most recent call last)
<ipython-input-5-6a342013a160> in <module>
      1 from lxml import etree
      2 from io import StringIO, BytesIO
----> 3 tree = etree.parse("dblp.xml")

src/lxml/etree.pyx in lxml.etree.parse()

src/lxml/parser.pxi in lxml.etree._parseDocument()

src/lxml/parser.pxi in lxml.etree._parseDocumentFromURL()

src/lxml/parser.pxi in lxml.etree._parseDocFromFile()

src/lxml/parser.pxi in lxml.etree._BaseParser._parseDocFromFile()

src/lxml/parser.pxi in lxml.etree._ParserContext._handleParseResultDoc()

src/lxml/parser.pxi in lxml.etree._handleParseResult()

src/lxml/parser.pxi in lxml.etree._raiseParseError()

OSError: Error reading file 'dblp.xml': failed to load external entity "dblp.xml"

dblp.xml 和 dblp.dtd 都已經在根文件夾中。

請幫忙!

您可以使用etree.iterparse來避免在 memory 中加載整個文件:

events = ("start", "end")
with open("dblp.xml", "r") as fo:
    context = etree.iterparse(fo, events=events)
    for action, elem in context:
        # Do something

這將允許您只提取您需要的實體而忽略其他實體。

正如 Jan Jaap Meijerink 所說,您可以嘗試使用 iterparse。 可能您還可以禁用防止解析大文件的 lxml 安全功能(請參閱https://lxml.de/api/lxml.etree.XMLParser-class.html的文檔):

with open('', 'r') as fobj:
    for event, elem in  etree.iterparse(
                    fobj,
                    huge_tree=True,
                ):
            #do something with element or event

最后,如果您更喜歡嘗試使用 parse,您可以定義 xml 解析器並啟用 huge_tree 並將其設置為默認值,以便進一步使用 etree.parse:

xml_parser_settings = dict(
    huge_tree=True, # resolve_entities=False, remove_pis=True, no_network=True
)

XMLPARSER = etree.XMLParser(xml_parser_settings)
etree.set_default_parser(XMLPARSER)

在這些語句之后,您可以將 etree.parser 與配置的 XMLPARSER 一起使用。 不過要小心多線程( https://lxml.de/1.3/api/lxml.etree-module.html#set_default_parser )。

添加 resolve_entities、remove_pis 和 no_network 關鍵字可以(至少在一定程度上)降低解析巨大外部文件的風險,如果它們來自不受信任的來源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM