Декодировать объекты HTML в строке Python?
Я разбираю некоторый HTML с Beautiful Soup 3, но он содержит объекты HTML, которые Beautiful Soup 3 не меняет автоматически для меня:
>>> from BeautifulSoup import BeautifulSoup
>>> soup = BeautifulSoup("<p>£682m</p>")
>>> text = soup.find("p").string
>>> print text
£682m
Как я могу декодировать объекты HTML в text
, чтобы получить "£682m"
вместо "£682m"
.
Ответы
Ответ 1
Python 3. 4+
Используйте html.unescape()
:
import html
print(html.unescape('£682m'))
К вашему сведению html.parser.HTMLParser.unescape
устарела, и должен был быть удален через 3.5, хотя он был оставлен по ошибке. Он будет удален из языка в ближайшее время.
Python 2.6-3.3
Вы можете использовать HTMLParser.unescape()
из стандартной библиотеки:
>>> try:
... # Python 2.6-2.7
... from HTMLParser import HTMLParser
... except ImportError:
... # Python 3
... from html.parser import HTMLParser
...
>>> h = HTMLParser()
>>> print(h.unescape('£682m'))
£682m
Вы также можете использовать библиотеку совместимости six
, чтобы упростить импорт:
>>> from six.moves.html_parser import HTMLParser
>>> h = HTMLParser()
>>> print(h.unescape('£682m'))
£682m
Ответ 2
Beautiful Soup обрабатывает преобразование сущности. В Beautiful Soup 3 вам нужно указать аргумент convertEntities
конструктору BeautifulSoup
(см. Раздел 'Преобразование сущности в разделе архивированные документы). В Beautiful Soup 4 объекты автоматически декодируются.
Красивый суп 3
>>> from BeautifulSoup import BeautifulSoup
>>> BeautifulSoup("<p>£682m</p>",
... convertEntities=BeautifulSoup.HTML_ENTITIES)
<p>£682m</p>
Красивый суп 4
>>> from bs4 import BeautifulSoup
>>> BeautifulSoup("<p>£682m</p>")
<html><body><p>£682m</p></body></html>
Ответ 3
Вы можете использовать replace_entities из библиотеки w3lib.html
In [202]: from w3lib.html import replace_entities
In [203]: replace_entities("£682m")
Out[203]: u'\xa3682m'
In [204]: print replace_entities("£682m")
£682m
Ответ 4
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>
Ответ 5
Это, вероятно, не имеет значения. Но для устранения этих html-entites из целого документа вы можете сделать что-то вроде этого: (предположим, что document = page и прошу простить неаккуратный код, но если у вас есть идеи о том, как сделать его лучше, Im all ears - Im new to это).
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