Decodificar entidades HTML com Python
-
05-07-2019 - |
Pergunta
Eu estou tentando decodificar HTML entradas a partir daqui NYTimes.com e eu não consigo descobrir o que estou fazendo de errado.
Tome por exemplo:
"U.S. Adviser’s Blunt Memo on Iraq: Time ‘to Go Home’"
Eu tentei BeautifulSoup, decodificar ( 'iso-8859-1'), e smart_str de django.utils.encoding sem qualquer sucesso.
Solução
Tente isto:
import re
def _callback(matches):
id = matches.group(1)
try:
return unichr(int(id))
except:
return id
def decode_unicode_references(data):
return re.sub("&#(\d+)(;|(?=\s))", _callback, data)
data = "U.S. Adviser’s Blunt Memo on Iraq: Time ‘to Go Home’"
print decode_unicode_references(data)
Outras dicas
Na verdade o que você tem não são entidades HTML. Há três variedades daqueles & .....; thingies -. por exemplo    
todos média U + 00A0 NO-BREAK ESPAÇO
 
(o tipo que você tem) é uma "referência de caráter numérico" (decimal).
 
é uma "referência de caráter numérico" (hexadecimal).
é uma entidade.
Além disso leitura: http://htmlhelp.com/reference/html40/entities/
Aqui você vai encontrar o código para python2.x que faz todos os três em uma varredura através da entrada: http://effbot.org/zone/re-sub.htm#unescape-html
>>> from HTMLParser import HTMLParser
>>> print HTMLParser().unescape('U.S. Adviser’s Blunt Memo on Iraq: '
... 'Time ‘to Go Home’')
U.S. Adviser’s Blunt Memo on Iraq: Time ‘to Go Home’
A função não está documentada em Python 2. Ele é fixado em Python 3.4+ : ele é exposto como html.unescape()
há .
Isto funciona:
from BeautifulSoup import BeautifulStoneSoup
s = "U.S. Adviser’s Blunt Memo on Iraq: Time ‘to Go Home’"
decoded = BeautifulStoneSoup(s, convertEntities=BeautifulStoneSoup.HTML_ENTITIES)
Se você quer uma cadeia em vez de um objeto Unicode, você precisa decodificá-lo para uma codificação que suporta os caracteres a ser utilizado; ISO-8859-1 não:
result = decoded.encode("UTF-8")
É lamentável que você precisa de um módulo externo para algo como isto; simples entidade decodificação HTML / XML deve ser na biblioteca padrão, e não me obrigar a usar uma biblioteca com nomes de classe sem sentido como "BeautifulStoneSoup". (Classe e nomes de função não deve ser "criativo", que deve ser significativa.)