Декодирование HTML-объектов с помощью Python - PullRequest
18 голосов
/ 30 июля 2009

Я пытаюсь декодировать записи HTML отсюда NYTimes.com и не могу понять, что я делаю неправильно.

Взять например:

"U.S. Adviser’s Blunt Memo on Iraq: Time ‘to Go Home’"

Я пробовал BeautifulSoup, decode ('iso-8859-1') и django.utils.encoding's smart_str безуспешно

Ответы [ 4 ]

20 голосов
/ 31 июля 2009

На самом деле то, что у вас есть, не является сущностями HTML. Есть ТРИ разновидности этих & .....; штуковины - например       все означают U + 00A0 БЕЗ ПРОСТРАНСТВА.

  (тип, который у вас есть) - это «цифровая ссылка на символ» (десятичное число).
  - это «числовая ссылка на символ» (шестнадцатеричное).
  это сущность.

Дальнейшее чтение: http://htmlhelp.com/reference/html40/entities/

Здесь вы найдете код для Python2.x, который выполняет все три в одном сканировании через ввод: http://effbot.org/zone/re-sub.htm#unescape-html

19 голосов
/ 21 декабря 2013
>>> 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’

Функция недокументирована в Python 2. Она исправлена ​​в Python 3.4 + : она выставлена ​​как html.unescape() там .

18 голосов
/ 31 июля 2009

Это работает:

from BeautifulSoup import BeautifulStoneSoup
s = "U.S. Adviser’s Blunt Memo on Iraq: Time ‘to Go Home’"
decoded = BeautifulStoneSoup(s, convertEntities=BeautifulStoneSoup.HTML_ENTITIES)

Если вы хотите использовать строку вместо объекта Unicode, вам нужно будет декодировать ее в кодировку, которая поддерживает используемые символы; ISO-8859-1 не:

result = decoded.encode("UTF-8")

К сожалению, вам нужен внешний модуль для чего-то подобного; простое декодирование сущностей HTML / XML должно быть в стандартной библиотеке и не требовать от меня использования библиотеки с бессмысленными именами классов, такими как «BeautifulStoneSoup». (Имена классов и функций не должны быть «креативными», они должны быть осмысленными.)

6 голосов
/ 30 июля 2009

Попробуйте это:

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