Я использую BeautifulSoup для чистки сайта. Страница веб-сайта хорошо отображается в моем браузере:
Отчет Oxfam International под названием «Офсайд!
http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271
В частности, одинарные и двойные кавычки выглядят хорошо. Они выглядят как символы html, а не как ascii, хотя странно, когда я смотрю на источник в FF3, они кажутся нормальными ascii.
К сожалению, когда я чищу, я получаю что-то вроде этого
Отчет u'Oxfam International \ xe2 €
озаглавленный \ xe2 € -Offside!
Упс, я имею в виду это:
u'Oxfam International\xe2€™s report entitled \xe2€œOffside!
Метаданные страницы обозначают кодировку iso-88959-1. Я пробовал разные кодировки, играл с функциями сторонних производителей unicode-> ascii и html-> ascii и смотрел на несоответствие MS / iso-8859-1, но факт в том, что ™ не имеет ничего общего с одиночная кавычка, и я не могу превратить комбо unicode + htmlsymbol в правильный символ ascii или html - насколько мне известно, поэтому я и обращаюсь за помощью.
Я был бы счастлив с двойными кавычками ascii, "или"
Проблема в том, что я обеспокоен тем, что есть другие забавные символы, декодированные неправильно.
\xe2€™
Ниже приведен какой-то питон, воспроизводящий то, что я вижу, и то, что я пробовал.
import twill
from twill import get_browser
from twill.commands import go
from BeautifulSoup import BeautifulSoup as BSoup
url = 'http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271'
twill.commands.go(url)
soup = BSoup(twill.commands.get_browser().get_html())
ps = soup.body("p")
p = ps[52]
>>> p
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe2' in position 22: ordinal not in range(128)
>>> p.string
u'Oxfam International\xe2€™s report entitled \xe2€œOffside!<elided>\r\n'
http://groups.google.com/group/comp.lang.python/browse_frm/thread/9b7bb3f621b4b8e4/3b00a890cf3a5e46?q=htmlentitydefs&rnum=3&hl=en#3b00a890cf3a5e46
http://www.fourmilab.ch/webtools/demoroniser/
http://www.crummy.com/software/BeautifulSoup/documentation.html
http://www.cs.tut.fi/~jkorpela/www/windows-chars.html
>>> AsciiDammit.asciiDammit(p.decode())
u'<p>Oxfam International\xe2€™s report entitled \xe2€œOffside!
>>> handle_html_entities(p.decode())
u'<p>Oxfam International\xe2\u20ac\u2122s report entitled \xe2\u20ac\u0153Offside!
>>> unicodedata.normalize('NFKC', p.decode()).encode('ascii','ignore')
'<p>Oxfam International€™s report entitled €œOffside!
>>> htmlStripEscapes(p.string)
u'Oxfam International\xe2TMs report entitled \xe2Offside!
EDIT:
Я пытался использовать другой парсер BS:
import html5lib
bsoup_parser = html5lib.HTMLParser(tree=html5lib.treebuilders.getTreeBuilder("beautifulsoup"))
soup = bsoup_parser.parse(twill.commands.get_browser().get_html())
ps = soup.body("p")
ps[55].decode()
, что дает мне это
u'<p>Oxfam International\xe2\u20ac\u2122s report entitled \xe2\u20ac\u0153Offside!
лучший вариант декодирования, похоже, дает мне те же результаты:
unicodedata.normalize('NFKC', p.decode()).encode('ascii','ignore')
'<p>Oxfam InternationalTMs report entitled Offside!
РЕДАКТИРОВАТЬ 2:
Я использую Mac OS X 4 с FF 3.0.7 и Firebug
Python 2.5 (вау, не могу поверить, я не утверждал это с самого начала)