【问题标题】:decoding entities for Element tree解码元素树的实体
【发布时间】:2018-07-31 16:18:03
【问题描述】:

是否有一种全面的方法来查找 HTML 实体(包括外语字符)并将它们转换为十六进制编码或 ElementTree 接受的其他编码类型?对此有最佳做法吗?

我正在解析一个大型 XML 数据集,它使用 HTML 实体来编码 unicode 和特殊字符。我的脚本逐行传入一个 XML 文件。当我使用 python ElementTree 解析数据时,出现以下错误。

ParseError: undefined entity: line 296, column 29

我首先构建了一个字典来解析字符串并编码为十六进制。这减轻了许多错误。例如,将商标符号™ 转换为™。然而,看不到尽头。这是因为我已经开始找到 unicode 转义字符,例如 'Å'和 'ö' 表示外语。我已经查看了几个选项,并将在下面描述它们。

xmlcharrefreplace:这没有找到外语 HTML 转义值。

line = line.encode('ascii', 'xmlcharrefreplace')

HTMLParser.enescape(): 没用,我相信是因为 XML 需要转义一些字符,例如 ''。

h = HTMLParser.HTMLParser()
line = h.unescape(line)

编码为 UTF-8:我相信这不起作用,因为 XML 需要转义一些字符。

line = line.encode('utf-8')

BeautifulSoup:这返回了一个 BeautifulSoup 对象,当转换为字符串时,会在每一行添加一个 XML 版本标记,即使在替换它时,也会添加一些其他类型的字符。

line = BeautifulSoup(line, "xml")
line = str(line).replace('<?xml version="1.0" encoding="utf-8"?>', "").replace("\n", "")

htmlentitydefs:仍然设法遗漏了许多字符。例如,仍然错过了'&quest;'和 '&equals;',但是,这比其他选项让我更进一步。

from htmlentitydefs import name2codepoint

line =  re.sub('&(%s);' % '|'.join(name2codepoint),
            lambda m: unichr(name2codepoint[m.group(1)]), line)

【问题讨论】:

标签: python xml elementtree html-entities


【解决方案1】:

这是我为解决此问题所做的工作。我使用了多管齐下的方法来代替一个模块或解决方案。我写了一个刮板并用它来构建一个大字典(replacement_dict),它比我在这里发布的示例字典大。刮掉这样的网站(https://www.freeformatter.com/html-entities.html#iso88591-characters)。然后,我在发送到 sanitize 函数的行中替换了该字典中的所有实体。从那里我使用了两个包来抓取包中包含的剩余 html 实体,最后使用基本的正则表达式替换来获取我似乎无法在“综合列表”或其他包中在线找到的 html 实体.这就是问题所在,存在错误的实体,以及即使是 Google 搜索也无法找到的实体,也无法找到类似这样的网站:http://www.graphemica.com。总之,问题解决了。处理所有的 html 实体,甚至是错误的实体。代码贴在下面。也许矫枉过正,但它得到了每一个!

    replacement_dict = {
        '&sect;' : '&#x00A7;',
        '&otilde;' : '&#x00F5;',
        '&iacute;' : '&#x00ED;',
        '&cent;' : '&#x00A2;',
        '&Ocirc;' : '&#x00D4;',
        '&mdash;' : '&#x2014;',
        '&aring;' : '&#x00E5;',
        '&frac12;' : '&#x00BD;',
        '&Ograve;' : '&#x00D2;',
        '&szlig;' : '&#x00DF;',
        '&ccedil;' : '&#x00E7;',
        '&Uuml;' : '&#x00DC;',
        '&Acirc;' : '&#x00C2;',
        '&brvbar;' : '&#x00A6;',
        '&commat;' : "",
        '&lE;' : "",
        '&mgr;' : "",
        '&angst;' : "A",
        '&ohgr;' : "",
        '&Dgr;' : ""

    }


    # Replace rare html entities not handled by other packages
    for key, value in replacement_dict.items():
        line = line.replace(key, value)

    # replace further known entities using library
    line =  re.sub('&(%s);' % '|'.join(name2codepoint),
            lambda m: unichr(name2codepoint[m.group(1)]), line)

    # further replace known xml char replace to ascii
    line = line.encode('ascii', 'xmlcharrefreplace')

    pattern = re.compile(r"\&[A-Za-z0-9]{1,}\;")
    # finally use regex to replace anyhting that looks like an html entity
    line = re.sub(pattern, "", line)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    相关资源
    最近更新 更多