【问题标题】:Loading huge XML files and dealing with MemoryError加载巨大的 XML 文件并处理 MemoryError
【发布时间】:2013-02-02 04:03:48
【问题描述】:

我有一个非常大的 XML 文件(准确地说是 20GB,是的,我需要全部)。当我尝试加载文件时,我收到此错误:

Python(23358) malloc: *** mmap(size=140736680968192) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Traceback (most recent call last):
  File "file.py", line 5, in <module>
    code = xml.read()
MemoryError

这是我当前的代码,用于读取 XML 文件:

from bs4 import BeautifulSoup
xml = open('pages_full.xml', 'r')
code = xml.read()
xml.close()
soup = BeautifulSoup(code)

现在,我将如何消除此错误并继续编写脚本。我会尝试将文件拆分为单独的文件,但由于我不知道这会如何影响 BeautifulSoup 以及 XML 数据,我宁愿不这样做。

(XML 数据是我自愿加入的一个 wiki 的数据库转储,使用它来导入来自不同时间段的数据,使用来自许多页面的直接信息)

【问题讨论】:

  • 你有 20GB 的内存吗?如果没有,即使你可以让它工作,它也会在换入和换出时变得难以忍受。不过,可能有一种方法可以让您一次只对块进行操作,例如 lxml。

标签: python xml beautifulsoup mediawiki


【解决方案1】:

不要使用 BeautifulSoup 来尝试解析这么大的 XML 文件。请改用ElementTree API。具体来说,使用iterparse() function 将文件解析为流,在收到元素通知时处理信息,然后再次删除元素:

from xml.etree import ElementTree as ET

parser = ET.iterparse(filename)

for event, element in parser:
    # element is a whole element
    if element.tag == 'yourelement'
         # do something with this element
         # then clean up
         element.clear()

通过使用事件驱动的方法,您无需将整个 XML 文档保存在内存中,您只需提取所需的内容并丢弃其余部分。

请参阅iterparse() tutorial and documentation

或者,您也可以使用lxml library;它以更快、功能更全的软件包提供相同的 API。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多