使用 BeautifulSoup 读取 1000 份 XML 文档

Reading 1000s of XML documents with BeautifulSoup

我正在尝试读取一堆 xml 文件并对它们进行处理。我要做的第一件事是根据文件中的数字重命名它们。

您可以看到数据示例here警告这将启动 108MB zip 文件的下载!。这是一个巨大的 xml 文件,其中包含数千个较小的 xml 文件。我已经将它们分解成单独的文件。我想根据内部的数字重命名文件(预处理的一部分)。我有以下代码:

from __future__ import print_function
from bs4 import BeautifulSoup # To get everything
import os

def rename_xml_files(directory):
    xml_files = [xml_file for xml_file in os.listdir(directory) ]

    for filename in xml_files:
        filename = filename.strip()
        full_filename = directory + "/" +filename
        print (full_filename)
        f = open(full_filename, "r")
        xml = f.read()
        soup = BeautifulSoup(xml)
        del xml
        del soup
        f.close()

如果我注释掉 "soup =" 和 "del" 行,它会完美运行。如果我添加 "soup = ..." 行,它会工作片刻,然后它最终会崩溃——它只会使 python 内核崩溃。我正在使用 Enthought Canopy,但我已经从命令行尝试过它 运行,它也在那里出现问题。

我想,也许它没有为变量 "soup" 释放 space,所以我尝试添加 "del" 命令。同样的问题。

关于如何规避这个问题有什么想法吗?我没有被困在 BS 上。如果有更好的方法,我会喜欢的,但我需要一些示例代码。

尝试使用 Python 的标准 xml 库中的 cElementTree.parse() 而不是 BeautifulSoup。 'Soup 非常适合解析普通网页,但 cElementTree 速度非常快。

像这样:

import xml.etree.cElementTree as cET

# ...

def rename_xml_files(directory):
    xml_files = [xml_file for xml_file in os.listdir(directory) ]

    for filename in xml_files:
        filename = filename.strip()
        full_filename = directory + "/" +filename
        print(full_filename)
        parsed = cET.parse(full_filename)
        del parsed

如果您的 XML 格式正确,这应该可以解析它。如果您的机器仍然无法处理内存中的所有数据,您应该查看 streaming 和 XML。

我不会把那个文件分成许多小文件然后再处理它们,我会一次处理它们。

我只会使用 streaming api XML 解析器并解析主文件,获取名称并使用正确的名称写出子文件一次。

不需要 BeautifulSoup,它主要用于处理 HTML 并使用文档模型而不是流式解析器。

没有必要构建整个 DOM 只是为了一次获得一个元素。