Кодирование Декодирование строк Python - PullRequest
7 голосов
/ 25 марта 2012

У меня есть список HTML-страниц, которые могут содержать определенные закодированные символы. Некоторые примеры как ниже -

<a href="mailto:lad%20at%20maestro%20dot%20com">
<em>ada&#x40;graphics.maestro.com</em>
<em>mel&#x40;graphics.maestro.com</em>

Я хотел бы расшифровать эти строки (escape, я не уверен в текущей терминологии) в -

 <a href="mailto:lad at maestro dot com">
<em>ada@graphics.maestro.com</em>
<em>mel@graphics.maestro.com</em>

Обратите внимание, что HTML-страницы представлены в строковом формате. Кроме того, я не хочу использовать какую-либо внешнюю библиотеку, такую ​​как BeautifulSoup или lxml, только нативные библиотеки Python в порядке.

Редактировать -

Приведенное ниже решение не идеально. HTML Parser, не выходящий с urllib2, выбрасывает

UnicodeDecodeError: 'ascii' codec can't decode byte 0x94 in position 31: ordinal not in range(128)

ошибка в некоторых случаях.

1 Ответ

7 голосов
/ 25 марта 2012

Вам необходимо удалить HTML-сущности и URL-кавычки.
В стандартной библиотеке есть HTMLParser и urllib2, чтобы помочь с этими задачами.

import HTMLParser, urllib2

markup = '''<a href="mailto:lad%20at%20maestro%20dot%20com">
<em>ada&#x40;graphics.maestro.com</em>
<em>mel&#x40;graphics.maestro.com</em>'''

result = HTMLParser.HTMLParser().unescape(urllib2.unquote(markup))
for line in result.split("\n"): 
    print(line)

Результат:

<a href="mailto:lad at maestro dot com">
<em>ada@graphics.maestro.com</em>
<em>mel@graphics.maestro.com</em>

Редактировать:
Если ваши страницы могут содержать символы не-ASCII, вам необходимо позаботиться о декодировании на входе и кодировании на выходе.
В загруженном образце файла для набора символов установлено значение cp-1252, поэтому давайте попробуем декодировать его в Unicode:

import codecs 
with codecs.open(filename, encoding="cp1252") as fin:
    decoded = fin.read()
result = HTMLParser.HTMLParser().unescape(urllib2.unquote(decoded))
with codecs.open('/output/file.html', 'w', encoding='cp1252') as fou:
    fou.write(result)

Edit2:
Если вас это не волнуетсимволы не ASCII, которые вы можете немного упростить:

with open(filename) as fin:
    decoded = fin.read().decode('ascii','ignore')
...
...