Python ElementTree 写入函数

3 投票
1 回答
967 浏览
提问于 2025-04-17 01:41

我正在使用Python的ElementTree来读取和修改我的HTML文件中的一些内容。当我完成修改并使用ElementTree的write函数时,

1) 它会在所有标签前面加上多余的html:前缀。我该怎么避免这个问题呢?

2) 它还会在我有特殊字符的地方加上&符号。我该怎么避免这个问题呢?

谢谢,

Divya。

1 个回答

1

你不能这样做。ElementTree 是通过加载 XML 文件,解析它,然后只保存一个抽象的表示来工作的。它通过遍历这个抽象表示把内容写成字符串,但它并不记得哪些字符是被转义成实体的,或者一个元素是以 <foo/> 形式存储的,还是以 <foo></foo> 形式存储的(在 HTML 中也是 <foo><foo></foo>)。

现在,由于 ElementTree 只处理 XML(而不是 HTML),我猜你在使用 lxml.html。在这种情况下,它实际上会自动修正某些错误的 HTML 格式,因为否则它无法正确存储这些内容。

如果你想处理 HTML 数据,并且希望除了你修改的部分外,其他内容都能被 完全 保留,正确的方法是抓取那些能记住原始表示的标记。我曾经使用过 sgmllib 来做到这一点,但这并不完美——例如,有一个 get_starttag_text 方法可以获取开始标签的 确切 内容,但没有对应的结束标签的方法。不过,这可能已经足够用了。

举个例子,如果想写出一个去掉所有段落的 HTML,可以这样写这个函数:

from cStringIO import StringIO

class SGMLModifier(sgmllib.SGMLParser):
    def __init__(self, *args, **kwargs):
        sgmllib.SGMLParser.__init__(self, *args, **kwargs)
        self._file = StringIO()

    def getvalue(self):
        return self._file.getvalue()

    def start_b(self, attributes):
        # skip it
        pass

    def end_b(self):
        # skip it
        pass

    def unknown_starttag(self, tag, attributes):
        self._file.write(self.get_starttag_text())

    def unknown_endtag(self, tag):
        # we can't get this verbatim.
        self._file.write('</%s>' % tag)

    def handle_comment(self, comment):
        # no verbatim here either.
        self._file.write('<!-- %s -->' % comment)

    def handle_data(self, data):
        self._file.write(data)

    def convert_entityref(self, ref):
        return '&' + ref + ';'

def remove_bold(html):
    parser = SGMLModifier()
    parser.feed(html)
    return parser.getvalue()

这可能需要更多的工作,以确保不会搞乱输入。查看文档以获取详细信息。

撰写回答