2009-03-31 4 views
47

Возможные дублирует:Преобразование HTML сущности в Unicode и наоборот

Как преобразовать HTML сущности в Юникод и наоборот в Python ?

+16

@Jarret Hardie: на самом деле, показать и рассказать совершенно отлично на SO. Из первой записи в FAQ (http://stackoverflow.com/faq) «Также прекрасно спросить и ответить на свой собственный вопрос программирования». Хотя, также рекомендуется искать дубликаты. – chauncey

+12

Я отправляю вопросы, которые я сам ответил в прошлом, в интересах других пользователей, которые ищут похожие ответы. – hekevintran

+6

+1 Он вносит свой вклад в набор данных. –

ответ

22

Необходимо иметь 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; 
+1

Изменения в BeautifulSoup api. См. Последний документ [doc] (http://www.crummy.com/software/BeautifulSoup/bs4/doc/). – bahmait

+0

@hekevintran: Возможно ли напечатать '& # x00A2 ;, & # x00A3 ;, & # x00A5 ;, & # x20AC ;, & # x00A7 ;, & # x00A9;' вместо ¢, £, ¥, €, §, © '. Есть идеи? – Jagath

78

Как «наоборот» (который мне нужен сам, ведя меня, чтобы найти этот вопрос, не помогло, и впоследствии another site which had the answer):

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

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

+1

Я забыл про xmlcharrefreplace, и это было очень полезно. Каждый раз, когда мне нужно безопасно хранить закодированные или не ascii символы в mysql, я считаю, что мне нужно использовать этот метод. – cybertoast

+1

Это не работает с строковым литералом, содержащим символ юникода U + 2019, эквивалент HTML-эквивалента. ’ . Разве это не то, о чем просил вопрос (этот ответ преобразует ascii, который является подмножеством юникода)? text.decode ('utf-8'). Encode ('ascii', 'xmlcharrefreplace') –

+1

@MikeS Он работает без проблем; '>>> u '\ u2019'.encode (' utf-8 '). decode (' utf-8 '). encode (' ascii ',' xmlcharrefreplace ')' дает '' ’ '' –

4

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

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

также html.unescape(s) был introduced in version 3.4.

Так питон 3.4 вы можете:

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

В Python 2.7 вы может использовать HTMLParser.unescape (текст) – frank

12

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

экранирования в - Unicode HTML в юникод с htmlparser (Python 2.7 стандартных Lib):

>>> 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 

экранирования в - Unicode, 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' 
+0

upvote для показа стандартного решения библиотеки без зависимостей –

+0

Пересмотр Я только что видел комментарий @bobince, оставленный на вопросе, указывающем на [этот ответ] (http://stackoverflow.com/a/663128/1599229). Поскольку 'htmlparser' документирован сейчас, и поскольку этот комментарий не является заметным, оставляя эту часть ответа. – bahmait

0

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

надеюсь, что это полезно для кого-то

0

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

отметить также, что набор символов по умолчанию, как в html5 является UTF-8 это ISO-8859-1 для HTML4

Таким образом, нам придется обойти каким-то образом (найти & заменить те, на первом)

Reference (начальная точка) из документации в Mozilla

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

Смежные вопросы