it-swarm.com.ru

Конвертировать сущности HTML в Unicode и наоборот

Возможные дубликаты:

Как вы преобразуете сущности HTML в Unicode и наоборот в Python?

59
hekevintran

Вам нужно иметь 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;
28
hekevintran

Что касается "наоборот" (которое мне нужно было самостоятельно, что привело меня к поиску этого вопроса, который не помог, и впоследствии другой сайт, на котором был ответ ):

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

вернет простую строку с любыми не-ascii символами, превращенными в объекты XML (HTML).

89
Isaac

Обновление для Python 2.7 и BeautifulSoup4

Unescape - Unicode HTML в unicode с htmlparser (стандартная библиотека Python 2.7):

>>> 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 - Юникод HTML в юникод с 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

Escape - Юникод в юникод HTML с bs4 (BeautifulSoup4):

>>> 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'
19
scharfmn

Как следует из ответа hekevintran , вы можете использовать cgi.escape(s) для кодирования строк, но обратите внимание, что кодировка кавычек по умолчанию ложна в этой функции, и это может быть хорошим Идея передать аргумент ключевого слова quote=True вместе с вашей строкой. Но даже передавая quote=True, функция не будет экранировать одинарные кавычки ("'") (Из-за этих проблем функция была устарела с версии 3.2)

Было предложено использовать html.escape(s) вместо cgi.escape(s). (Новое в версии 3.2)

Также html.unescape(s) была введена в версии 3.4 .

Итак, в python 3.4 вы можете:

  • Используйте html.escape(text).encode('ascii', 'xmlcharrefreplace').decode() для преобразования специальных символов в объекты HTML.
  • И html.unescape(text) для преобразования HTML-сущностей обратно в текстовые представления.
8
AXO

Я использовал следующую функцию для преобразования unicode, скопированного из файла xls, в файл 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'))

надеюсь, это кому-нибудь пригодится

1
Stephen Ellwood

Если кто-то вроде меня не знает, почему некоторые номера сущностей (коды), такие как &#153; (for trademark symbol), &#128; (for euro symbol), не кодируются должным образом, причина в ISO-8859-1 (он же Windows-1252), эти символы не определены.

Также обратите внимание, что набор символов по умолчанию для html5 - это utf-8, это был ISO-8859-1 для html4.

Итак, нам придется как-то обойти (сначала найти и заменить их)

Ссылка (отправная точка) из документации Mozilla

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

1
brucekaushik