BeautifulSoup gibt mir Unicode + html Symbole, anstatt gerade nach oben Unicode. Ist das ein Fehler oder ein Missverständnis?

StackOverflow https://stackoverflow.com/questions/629999

Frage

Ich verwende BeautifulSoup eine Website zu kratzen. Die Seite der Website macht in meinem Browser fein:

  

Oxfam International Bericht mit dem Titel „Offside!    http://www.coopamerica.org/programs/responsibleshopper/company.cfm ? id = 271

Insbesondere die einfache und doppelte Anführungszeichen sehen gut aus. Sie sehen aus HTML Symbole anstatt ascii, obwohl seltsam, wenn ich Quelle sehen in FF3 sie normal erscheinen ascii sein.

Leider, wenn ich kratzen ich so etwas wie dieses erhalten

  

u'Oxfam Internationale \ XE2 € ™ s Bericht   Titel \ XE2 € œOffside!

oops, ich meine dies:

u'Oxfam International\xe2€™s report entitled \xe2€œOffside!

Die Meta-Daten Seite zeigt 'iso-88959-1' Codierung. Ich habe verschiedene Kodierungen versucht, gespielt mit Unicode-> ascii und html-> ascii Dritten Funktionen und schaute auf der MS / iso-8859-1 Diskrepanz, aber die Tatsache der Angelegenheit ist, dass ™ nichts mit einem zu tun hat Apostroph, und ich kann nicht scheinen, um die Unicode + htmlsymbol Combo in dem richtigen ASCII- oder hTML-Symbol zu drehen -. in meiner begrenzten Kenntnis, weshalb ich Hilfe bin auf der suche

ich mit einem ascii Doppel Zitat glücklich sein würde, „oder“

Das Problem ist folgendes, dass ich bin besorgt darüber, es gibt auch andere lustige Symbole decodiert falsch.

\xe2€™

Im Folgenden finden Sie einige Python zu reproduzieren, was ich sehe, gefolgt von den Dingen, die ich ausprobiert habe.

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:

Ich habe versucht, einen anderen BS-Parser verwenden:

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

das gibt mir diese

u'<p>Oxfam International\xe2\u20ac\u2122s report entitled \xe2\u20ac\u0153Offside!

der beste Fall dekodieren scheint mir die gleichen Ergebnisse zu erhalten:

unicodedata.normalize('NFKC', p.decode()).encode('ascii','ignore')
'<p>Oxfam InternationalTMs report entitled Offside! 

EDIT 2:

Ich arbeite mit Mac OS X 4 mit FF 3.0.7 und Firebug

Python 2.5 (wow, kann nicht glauben, dass ich das nicht von Anfang an angegeben hätte)

War es hilfreich?

Lösung

Das ist eine ernst verkorkste Seite, Encoding-weise: -)

Es gibt nichts wirklich falsch mit Ihrem Ansatz alle an. Ich würde wahrscheinlich die Umwandlung neigen zu tun, bevor es zu BeautifulSoup, nur weil ich Persnickity bin übergeben:

import urllib
html = urllib.urlopen('http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271').read()
h = html.decode('iso-8859-1')
soup = BeautifulSoup(h)

In diesem Fall wird die Meta-Tag-Seite wird über die Kodierung liegt. Die Seite ist eigentlich in utf-8 ... Firefox Seite Info zeigt die reale Codierung, und man kann tatsächlich diese charset in der Antwort-Header sieht vom Server zurückgegeben:

curl -i http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271
HTTP/1.1 200 OK
Connection: close
Date: Tue, 10 Mar 2009 13:14:29 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Set-Cookie: COMPANYID=271;path=/
Content-Language: en-US
Content-Type: text/html; charset=UTF-8

Wenn Sie tun, um die decode mit ‚utf-8‘, wird es für Sie arbeiten (oder zumindest für mich getan ist):

import urllib
html = urllib.urlopen('http://www.coopamerica.org/programs/responsibleshopper/company.cfm?id=271').read()
h = html.decode('utf-8')
soup = BeautifulSoup(h)
ps = soup.body("p")
p = ps[52]
print p

Andere Tipps

Es ist eigentlich UTF-8 misencoded als CP1252:

>>> print u'Oxfam International\xe2€™s report entitled \xe2€œOffside!'.encode('cp1252').decode('utf8')
Oxfam International’s report entitled “Offside!
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top