【问题标题】:What is the most efficient way of extracting information from a large number of xml files in python?从python中的大量xml文件中提取信息的最有效方法是什么?
【发布时间】:2010-09-25 13:34:19
【问题描述】:

我有一个完整的目录 (~103, 104) 的 XML 文件,我需要从中提取几个字段的内容。 我已经测试了不同的 xml 解析器,并且由于我不需要验证内容(昂贵),我正在考虑简单地使用 xml.parsers.expat (最快的)来遍历文件,一个一个地提取数据。

  1. 有没有更有效的方法? (简单的文本匹配不起作用)
  2. 是否需要为每个新文件(或字符串)发出一个新的 ParserCreate(),或者我可以为每个文件重复使用相同的 ParserCreate()?
  3. 有什么注意事项吗?

谢谢!

【问题讨论】:

  • 你能提供更多关于这些文件的信息吗?他们是一样的吗?它们都包含所需的信息吗?为什么文本匹配没有用?一两个例子也会有所帮助。
  • 您尝试了哪些其他解析器?出于非常相似的目的,我测试了xml.dom.ext.reader,并且 libxml2 和 libxml2 的 Python 绑定要快得多。
  • @muhuk:文本匹配是无用的,因为 XML 特定的东西,例如搜索“foo”与文本匹配不会发现“foo”,即使它是相同的东西在 XML 中。

标签: python xml performance large-files expat-parser


【解决方案1】:

通常,我建议使用 ElementTree 的 iterparse,或者为了提高速度,使用 lxml 的对应项。还可以尝试使用Processing(2.6 内置)进行并行化。

iterparse 的重要之处在于,您可以在解析元素(子)结构时获得它们。

import xml.etree.cElementTree as ET
xml_it = ET.iterparse("some.xml")
event, elem = xml_it.next()

event 在这种情况下将始终是字符串 "end",但您也可以初始化解析器,以便在解析新元素时告诉您它们的信息。您无法保证此时所有子元素都已被解析,但如果您只对此感兴趣,属性就在那里。

另一点是您可以提前停止从迭代器中读取元素,即在整个文档被处理之前。

如果文件很大(是吗?),有一个常见的习惯用法来保持内存使用量不变,就像在流解析器中一样。

【讨论】:

    【解决方案2】:

    最快的方法是匹配字符串(例如,正则表达式)而不是解析 XML - 取决于您的 XML,这实际上可以工作。

    但最重要的是:与其考虑几个选项,不如实施它们并在一个小集合上计时。这将花费大致相同的时间,并且会为您提供真实的数字,确实会推动您前进。

    编辑:

    • 文件是在本地驱动器还是网络驱动器上?网络 I/O 将在这里杀死你。
    • 问题并行化很简单 - 您可以在多台计算机(或多核计算机上的多个进程)之间拆分工作。

    【讨论】:

    • 嗨,我已经想到了,这就是我选择 expat 的方式(这是我发现的最快的)。我稍微澄清了这个问题以反映这一点。我想知道我是否遗漏了什么,或者是否有任何可以加快速度的技巧。
    • 正则表达式只适用于很小的 XML 文档子集,并且充满了隐藏的缺陷,除非你真的、真的知道你在做什么(例如,你知道你将如何处理编码和空格的所有排列)。
    • @Robert - 或者除非您的 XML 碰巧以易于生成的方式生成。这就是接受任何与模式匹配的 XML 和一堆恰好生成相同的 XML 之间的区别。
    【解决方案3】:

    您没有指出的一件事是您是否正在将 XML 读入某种 DOM。我猜你可能不是,但如果你是,不要。请改用 xml.sax。使用 SAX 代替 DOM 将显着提升性能。

    【讨论】:

    • 另一方面,对于程序员来说,SAX 比 DOM 复杂得多。
    【解决方案4】:

    如果您知道 XML 文件是使用相同的算法生成的,那么根本不进行任何 XML 解析可能会更有效。例如。如果您知道数据在第 3、4 和 5 行,您可以逐行阅读文件,然后使用正则表达式。

    当然,如果文件不是机器生成的,或者来自不同的生成器,或者生成器随时间发生变化,那么这种方法就会失败。不过,我很乐观地认为它会更有效率。

    您是否回收解析器对象在很大程度上无关紧要。将创建更多对象,因此单个解析器对象并不算多。

    【讨论】:

      猜你喜欢
      • 2023-03-05
      • 1970-01-01
      • 2019-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-23
      • 2012-07-13
      相关资源
      最近更新 更多