从默认的Python xml.sax转换为lxml SAX接口

0 投票
2 回答
698 浏览
提问于 2025-04-17 12:19

我想加快解析大约5GB的维基百科内容。目前我在用一个脚本,这个脚本使用了Python的sax接口,而lxml似乎是一个简单直接的加速解决方案。

不过,我对lxml的sax文档有点困惑,所以如果能给我一些简单示例的链接或者指点就太好了。这里是我想转换的脚本,https://gist.github.com/1739351

2 个回答

0

你可以试试 lxml.etree,这是一个用 Python 处理 XML 的方法,既高效又简洁。

4

lxml.sax 不是 xml.sax 的替代品,它提供了一些额外的功能:

>>> import lxml.sax
>>> help(lxml.sax)
Help on module lxml.sax in lxml:

NAME
    lxml.sax - SAX-based adapter to copy trees from/to the Python standard libra
ry.

FILE
    c:\python27\lib\site-packages\lxml\sax.py

DESCRIPTION
    Use the `ElementTreeContentHandler` class to build an ElementTree from
    SAX events.

    Use the `ElementTreeProducer` class or the `saxify()` function to fire
    the SAX events of an ElementTree against a SAX ContentHandler.
[snip]

你有两个选择:

选择1:继续使用SAX,试着通过去掉所有的断言或者至少让它们更高效来加速代码,比如:

def characters(self, content):
    # assert content is not None and len(content) > 0
    assert content
    # if len(self.stack) == 0:
    if not self.stack:
        return
    if self.stack[-1] == "title":
        self.title += content
    elif self.stack[-1] == "text":
        # assert self.title is not None
        assert self.title # This assertion is gross overkill IMHO
        self.text += content

选择2:放弃SAX,使用ElementTree接口,利用 iterparse 进行解析,并在解析的过程中清理掉已经处理过的部分。可以参考 这个链接。你有三种ElementTree接口的选择:

(a) import xml.etree.ElementTree as et ... 用Python写的;速度太慢
(b) import xml.etree.cElementTree as et ... 用C写的;快得多
(c) import lxml.etree as et ... 可能比(b)慢,但有额外的功能。

如果你需要关于选择(2)的帮助,可以在Stack Overflow上搜索 “[python] iterparse”,如果有必要再单独提问(也就是说,不要在这个问题的评论里问)。

撰写回答