HTMLParser: Problem mit Umlauten

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Mazze
User
Beiträge: 2
Registriert: Sonntag 13. April 2014, 12:18

Mit diesem Scipt

Code: Alles auswählen

import urllib
from HTMLParser import HTMLParser
from htmlentitydefs import name2codepoint

class MyHTMLParser(HTMLParser):
    def handle_starttag(self, tag, attrs):
        print "Start tag:", tag
        for attr in attrs:
            print "     attr:", attr
    def handle_endtag(self, tag):
        print "End tag  :", tag
    def handle_data(self, data):
        print "Data     :", data

parser = MyHTMLParser()

file = urllib.urlopen("http://www.clever-tanken.de/tankstelle_liste?spritsorte=5&r=20&ort=97816&lat=&lon=")
content = file.read()

parser.feed(content)
bekomme ich mit Python 2.7.3 folgenden Fehler

Traceback (most recent call last):
File "tanken.py", line 20, in <module>
parser.feed(content)
File "/usr/lib/python2.7/HTMLParser.py", line 114, in feed
self.goahead(0)
File "/usr/lib/python2.7/HTMLParser.py", line 158, in goahead
k = self.parse_starttag(i)
File "/usr/lib/python2.7/HTMLParser.py", line 305, in parse_starttag
attrvalue = self.unescape(attrvalue)
File "/usr/lib/python2.7/HTMLParser.py", line 472, in unescape
return re.sub(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));", replaceEntities, s)
File "/usr/lib/python2.7/re.py", line 151, in sub
return _compile(pattern, flags).sub(repl, string, count)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 18: ordinal not in range(128)

Grund sind die Umlaute in:
<div id="tankstelle-46157" class="row price_entry" ng-init="addPoi('50,25168', '9,290797','','Globus Handelshof GmbH & Co. KG Betriebsstätte Wächtersbach',null,2209,2210,60,'1,569')">

Wie kann ich das lösen?
BlackJack

@Mazze: Das `HTMLParser`-Modul aus der Standardbibliothek ist für echtes HTML sowieso ungeeignet. Die Lösung wäre also `lxml.html` oder `BeautifulSoup` zu verwenden.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das konkrete Problem hat aber nichts mit dem qualitativ eher schlechten HTML-Parser zu tun, der mit Python ausgeliefert wird, sondern lässt sich recht einfach lösen, indem die "feed"-Zeile wie folgt abgeändert wird:

Code: Alles auswählen

parser.feed(content.decode('utf-8'))
Mazze
User
Beiträge: 2
Registriert: Sonntag 13. April 2014, 12:18

snafu hat geschrieben:

Code: Alles auswählen

parser.feed(content.decode('utf-8'))
Danke.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Mazze, @snafu: die konkrete Lösung hat aber nichts mit dem Problem zu tun, das eigentlich existiert. Werden html-Seiten über das HTTP-Protokoll abgefragt, gibt es ein kompliziertes System, wie das Encoding festgelegt wird, von HTTP-Headerzeilen über <?..?>-Deklaration bis hin zu meta-Tags. Das gute daran ist, dass Module wie `lxml.html` oder `BeautifulSoup` dieses Problem intern lösen, indem sie direkt von URLs lesen können. Also Mazze, nutze eine dieser Bibliotheken und nicht irgendeinen Workaround mit dem Du früher oder später Probleme bekommen wirst.
Antworten