【问题标题】:Convert HTML entities to Unicode and vice versa将 HTML 实体转换为 Unicode,反之亦然
【发布时间】:2010-10-16 15:31:38
【问题描述】:

如何在 Python 中将 HTML 实体转换为 Unicode,反之亦然?

【问题讨论】:

  • @Jarret Hardie:实际上,show-and-tell 非常适合 SO。从常见问题解答 (stackoverflow.com/faq) 的第一个条目开始,“询问和回答您自己的编程问题也很好”。不过,也鼓励寻找重复项。
  • 我发布了我过去为自己回答过的问题,以帮助其他用户搜索类似的答案。
  • 也可以在没有外部库的情况下完成。见stackoverflow.com/questions/663058/html-entity-codes-to-text/…
  • +1 他正在为数据集做出贡献。
  • 这个问题的范围比“重复”链接所指向的范围更广:这个问题还要求“反之亦然”,即从 Unicode 到 HTML 实体。

标签: python html html-entities


【解决方案1】:

至于“反之亦然”(我需要自己,导致我找到这个问题,这没有帮助,随后another site which had the answer):

u'some string'.encode('ascii', 'xmlcharrefreplace')

将返回一个纯字符串,其中任何非 ascii 字符都转换为 XML (HTML) 实体。

【讨论】:

  • 我忘记了 xmlcharrefreplace,这很有帮助。每当我需要将编码或非 ascii 字符安全地存储到 mysql 时,我发现我需要使用这种方法。
  • 这不适用于包含 unicode 字符 U+2019 HTML 实体等效项 ’ 的字符串文字。这不是问题所要求的吗(这个答案转换了作为 unicode 子集的 ascii)? text.decode('utf-8').encode('ascii', 'xmlcharrefreplace')
  • @MikeS 没有问题; >>> u'\u2019'.encode('utf-8').decode('utf-8').encode('ascii', 'xmlcharrefreplace')'’'
【解决方案2】:

你需要有BeautifulSoup

from BeautifulSoup import BeautifulStoneSoup
import cgi

def HTMLEntitiesToUnicode(text):
    """Converts HTML entities to unicode.  For example '&' becomes '&'."""
    text = unicode(BeautifulStoneSoup(text, convertEntities=BeautifulStoneSoup.ALL_ENTITIES))
    return text

def unicodeToHTMLEntities(text):
    """Converts unicode to HTML entities.  For example '&' becomes '&'."""
    text = cgi.escape(text).encode('ascii', 'xmlcharrefreplace')
    return text

text = "&, ®, <, >, ¢, £, ¥, €, §, ©"

uni = HTMLEntitiesToUnicode(text)
htmlent = unicodeToHTMLEntities(uni)

print uni
print htmlent
# &, ®, <, >, ¢, £, ¥, €, §, ©
# &amp;, &#174;, &lt;, &gt;, &#162;, &#163;, &#165;, &#8364;, &#167;, &#169;

【讨论】:

  • BeautifulSoup api 已更改。请查看最新的doc
  • @hekevintran: 是否可以打印'¢, £, ¥, €, §, ©'而不是“¢、£、¥、€、§、©”。有什么想法吗?
  • 这个答案迫切需要 Python3 更新。
【解决方案3】:

Python 2.7 和 BeautifulSoup4 更新

Unescape -- 使用htmlparser(Python 2.7 标准库)将 Unicode HTML 转换为 unicode:

>>> escaped = u'Monsieur le Cur&eacute; of the &laquo;Notre-Dame-de-Gr&acirc;ce&raquo; neighborhood'
>>> from HTMLParser import HTMLParser
>>> htmlparser = HTMLParser()
>>> unescaped = htmlparser.unescape(escaped)
>>> unescaped
u'Monsieur le Cur\xe9 of the \xabNotre-Dame-de-Gr\xe2ce\xbb neighborhood'
>>> print unescaped
Monsieur le Curé of the «Notre-Dame-de-Grâce» neighborhood

Unescape -- Unicode HTML to unicode with bs4 (BeautifulSoup4):

>>> html = '''<p>Monsieur le Cur&eacute; of the &laquo;Notre-Dame-de-Gr&acirc;ce&raquo; neighborhood</p>'''
>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup(html)
>>> soup.text
u'Monsieur le Cur\xe9 of the \xabNotre-Dame-de-Gr\xe2ce\xbb neighborhood'
>>> print soup.text
Monsieur le Curé of the «Notre-Dame-de-Grâce» neighborhood

转义 -- 使用bs4 (BeautifulSoup4) 将 Unicode 转换为 unicode HTML:

>>> unescaped = u'Monsieur le Curé of the «Notre-Dame-de-Grâce» neighborhood'
>>> from bs4.dammit import EntitySubstitution
>>> escaper = EntitySubstitution()
>>> escaped = escaper.substitute_html(unescaped)
>>> escaped
u'Monsieur le Cur&eacute; of the &laquo;Notre-Dame-de-Gr&acirc;ce&raquo; neighborhood'

【讨论】:

  • 赞成展示一个没有依赖关系的标准库解决方案
  • 重温我刚刚看到@bobince 在指向this answer 的问题上留下的评论。由于htmlparser 现在已记录在案,并且由于该评论不突出,因此保留那部分答案。
【解决方案4】:

正如 hekevintran 回答所暗示的,您可以使用 cgi.escape(s) 对字符串进行编码,但请注意,该函数中默认情况下引号的编码是错误的,传递 @987654324 可能是个好主意@ 关键字参数在您的字符串旁边。但是即使通过quote=True,该函数也不会转义单引号("'")(由于这些问题,该函数自3.2版以来一直是deprecated

建议使用html.escape(s) 而不是cgi.escape(s)。 (3.2 版新增)

还有html.unescape(s) 一直是introduced in version 3.4

所以在 python 3.4 中你可以:

  • 使用 html.escape(text).encode('ascii', 'xmlcharrefreplace').decode() 将特殊字符转换为 HTML 实体。
  • html.unescape(text) 用于将 HTML 实体转换回纯文本表示形式。

【讨论】:

  • 在 Python 2.7 中你可以使用 HTMLParser.unescape(text)
【解决方案5】:
$ python3 -c "
> import html
> print(
>     html.unescape('&amp;&#169;&#x2014;')
> )"
&©—

$ python3 -c "
> import html
> print(
>     html.escape('&©—')
> )"
&amp;©—

$ python2 -c "
> from HTMLParser import HTMLParser
> print(
>     HTMLParser().unescape('&amp;&#169;&#x2014;')
> )"
&©—

$ python2 -c "
> import cgi
> print(
>     cgi.escape('&©—')
> )"
&amp;©—

HTML 仅严格要求对 &amp;(与号)和 &lt;(左尖括号/小于号)进行转义。 https://html.spec.whatwg.org/multipage/parsing.html#data-state

【讨论】:

    【解决方案6】:

    对于python3,请使用html.unescape()

    import html
    s = "&amp;"
    decoded = html.unescape(s)
    # &
    

    【讨论】:

      【解决方案7】:

      如果像我这样的人想知道为什么像&amp;#153; (for trademark symbol), &amp;#128; (for euro symbol) 这样的实体编号(代码)没有正确编码,原因是在 ISO-8859-1(又名 Windows-1252)中没有定义这些字符。

      另请注意,html5 的默认字符集是 utf-8,html4 的默认字符集是 ISO-8859-1

      因此,我们将不得不以某种方式解决(首先找到并替换它们)

      来自 Mozilla 文档的参考(起点)

      https://developer.mozilla.org/en-US/docs/Web/Guide/Localizations_and_character_encodings

      【讨论】:

        【解决方案8】:

        我使用以下函数将从 xls 文件中提取的 unicode 转换为 html 文件,同时保留 xls 文件中的特殊字符:

        def html_wr(f, dat):
            ''' write dat to file f as html
                . file is assumed to be opened in binary format
                . if dat is nul it is replaced with non breakable space
                . non-ascii characters are translated to xml       
            '''
            if not dat:
                dat = '&nbsp;'
            try:
                f.write(dat.encode('ascii'))
            except:
                f.write(html.escape(dat).encode('ascii', 'xmlcharrefreplace'))
        

        希望这对某人有用

        【讨论】:

          【解决方案9】:
          #!/usr/bin/env python3
          import fileinput
          import html
          
          for line in fileinput.input():
              print(html.unescape(line.rstrip('\n')))
          

          【讨论】:

            猜你喜欢
            • 2015-04-26
            • 1970-01-01
            • 2010-12-03
            • 2011-10-08
            • 2013-03-15
            • 2019-09-19
            • 2013-12-29
            • 2011-09-22
            • 2012-05-14
            相关资源
            最近更新 更多