Декодировать сущности HTML в строку Python? - PullRequest
232 голосов
/ 18 января 2010

Я разбираю немного HTML с Beautiful Soup 3, но он содержит HTML-сущности, которые Beautiful Soup 3 автоматически не декодирует для меня:

>>> from BeautifulSoup import BeautifulSoup

>>> soup = BeautifulSoup("<p>&pound;682m</p>")
>>> text = soup.find("p").string

>>> print text
&pound;682m

Как я могу декодировать HTML-объекты в text, чтобы получить "£682m" вместо "&pound;682m".

Ответы [ 5 ]

454 голосов
/ 18 января 2010

Python 3.4 +

Использование html.unescape():

import html
print(html.unescape('&pound;682m'))

FYI html.parser.HTMLParser.unescape устарело, а предполагалось удалить в 3.5 , хотя оно было оставлено по ошибке Это будет удалено из языка в ближайшее время.


Python 2.6-3.3

Вы можете использовать HTMLParser.unescape() из стандартной библиотеки:

  • Для Python 2.6-2.7 он находится в HTMLParser
  • Для Python 3 он находится в html.parser
>>> try:
...     # Python 2.6-2.7 
...     from HTMLParser import HTMLParser
... except ImportError:
...     # Python 3
...     from html.parser import HTMLParser
... 
>>> h = HTMLParser()
>>> print(h.unescape('&pound;682m'))
£682m

Вы также можете использовать библиотеку совместимости six для упрощения импорта:

>>> from six.moves.html_parser import HTMLParser
>>> h = HTMLParser()
>>> print(h.unescape('&pound;682m'))
£682m
62 голосов
/ 18 января 2010

Beautiful Soup управляет преобразованием сущностей. В Beautiful Soup 3 вам необходимо указать аргумент convertEntities для конструктора BeautifulSoup (см. Раздел «Преобразование сущностей» заархивированных документов). В Beautiful Soup 4 сущности декодируются автоматически.

Красивый суп 3

>>> from BeautifulSoup import BeautifulSoup
>>> BeautifulSoup("<p>&pound;682m</p>", 
...               convertEntities=BeautifulSoup.HTML_ENTITIES)
<p>£682m</p>

Красивый суп 4

>>> from bs4 import BeautifulSoup
>>> BeautifulSoup("<p>&pound;682m</p>")
<html><body><p>£682m</p></body></html>
13 голосов
/ 09 августа 2016

Вы можете использовать replace_entities из библиотеки w3lib.html

In [202]: from w3lib.html import replace_entities

In [203]: replace_entities("&pound;682m")
Out[203]: u'\xa3682m'

In [204]: print replace_entities("&pound;682m")
£682m
2 голосов
/ 14 января 2014

Beautiful Soup 4 позволяет вам установить форматер для вывода

Если вы введете formatter=None, Beautiful Soup не будет изменять строки вообще на выходе.Это самый быстрый вариант, но он может привести к созданию Beautiful Soup неверного HTML / XML, как в следующих примерах:

print(soup.prettify(formatter=None))
# <html>
#  <body>
#   <p>
#    Il a dit <<Sacré bleu!>>
#   </p>
#  </body>
# </html>

link_soup = BeautifulSoup('<a href="http://example.com/?foo=val1&bar=val2">A link</a>')
print(link_soup.a.encode(formatter=None))
# <a href="http://example.com/?foo=val1&bar=val2">A link</a>
0 голосов
/ 18 декабря 2012

Это, вероятно, не имеет значения здесь. Но чтобы исключить эти HTML-элементы из всего документа, вы можете сделать что-то вроде этого: (Допустим, document = page и, пожалуйста, простите неаккуратный код, но если у вас есть идеи, как сделать его лучше, я все слышу - я новичок в это).

import re
import HTMLParser

regexp = "&.+?;" 
list_of_html = re.findall(regexp, page) #finds all html entites in page
for e in list_of_html:
    h = HTMLParser.HTMLParser()
    unescaped = h.unescape(e) #finds the unescaped value of the html entity
    page = page.replace(e, unescaped) #replaces html entity with unescaped value
...