Seite 1 von 1

utf-8 vs. ascii: Codierungsproblem beim urrlib.request-Modul

Verfasst: Donnerstag 30. Juli 2015, 21:53
von pixewakb
Ich stehe gerade auf dem Schlauch, weil ich ein kleineres Verständnisproblem bei nachfolgendem Traceback habe:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\...\spider.py", line 237, in <module>
    spider = Spider(url)
  File "C:\Python34\lib\site-packages\spider_bib.py", line 84, in __init__
    self.__getHTML()
  File "C:\Python34\lib\site-packages\spider_bib.py", line 281, in __getHTML
    self.__htmlseite = urllib.request.urlopen(self.url).read().decode('utf-8')
  File "C:\Python34\lib\urllib\request.py", line 153, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Python34\lib\urllib\request.py", line 455, in open
    response = self._open(req, data)
  File "C:\Python34\lib\urllib\request.py", line 473, in _open
    '_open', req)
  File "C:\Python34\lib\urllib\request.py", line 433, in _call_chain
    result = func(*args)
  File "C:\Python34\lib\urllib\request.py", line 1261, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "C:\Python34\lib\urllib\request.py", line 1235, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "C:\Python34\lib\http\client.py", line 1066, in request
    self._send_request(method, url, body, headers)
  File "C:\Python34\lib\http\client.py", line 1094, in _send_request
    self.putrequest(method, url, **skips)
  File "C:\Python34\lib\http\client.py", line 958, in putrequest
    self._output(request.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode character '\xf3' in position 20: ordinal not in range(128)
Das Tool ist ein älter Crawler von mir, der im Netz Webseiten analysiert und Daten bereitstellt. Im konkreten Fall scheint das Sonderzeichen in der URL und in der Seite aufzutreten, d. h. von außen kann ich da die Fehlerquelle nicht eingrenzen. Ein weiteres Problem für mich bei der Fehlersuche ist, dass die URL aus einer Liste geholt wird, die ein anderes Tool auf Basis einer Online-Quelle bereitstellt.

Ich habe die Kernfunktionen mal herausgelöst, kann dann aber das Problem nicht reproduzieren, d. h. mit einer neuen py-Quellcode-Datei tritt das Problem nicht auf.

Mich irritiert, dass ich oben utf-8 im Quelltext setze und unten etwas von ascii lesen muss. Hat jemand eine Idee, wo ich nach dem Fehler suchen muss? Ich habe jetzt mal an Codierung der URL gedacht (spielt aber beim Versuch den Fehler zu reduzieren keine Rolle), dann an die Codierung der Quelldateien (.py, utf-8) und dann an ein Problem des Moduls.

Der Code ist schon älter und ich müsste da mal eine größere Überarbeitung starten, was auch schon angedacht ist, nur momentan kann ich dem keine Priorität widmen und es ist auch keine Freude, weil das Spaghetti-Code ** 2 ist. Für mich sieht es so aus, als würde alles funktionieren und die Seite abgerufen werden; der Fehler tritt dann erst auf, wenn urllib.request eine Rückgabe an das Hauptprogramm versucht?

PS Der Umstieg auf das request-Modul ist angedacht; neuere Programme nutzen das Modul schon, nur dieses Schätzchen noch nicht.

Re: utf-8 vs. ascii: Codierungsproblem beim urrlib.request-M

Verfasst: Donnerstag 30. Juli 2015, 22:01
von DasIch
An dem Traceback siehst du doch ganz genau was das Problem ist. `request` ist ein String mit einem Zeichen dass sich nicht in ascii repräsentieren lässt. Ich würde empfehlen einen Debugger zu nehmen und damit zu schauen was genau `request` ist und zu schauen wo es herkommt. Entweder es gibt einen Bug in urllib oder du hast irgendwo einen Fehler gemacht und der ist bis an die Stelle durchgerutscht.

Re: utf-8 vs. ascii: Codierungsproblem beim urrlib.request-M

Verfasst: Donnerstag 30. Juli 2015, 22:08
von pixewakb
Soweit war ich gedanklich auch schon, hatte aber nicht erfasst, dass request der Rückgabewert ist und auf einen Debugger war ich auch noch nicht gekommen (schaue ich mir direkt einmal an).

Was mich irritiert ist, dass ich den Fehler, wenn ich den Kernquelltext herauslöse, nicht reproduzieren kann. Das haut mich gerade etwas um.

Für mich ist folgende Sache unklar: Wenn ich oben doch klar sage, dass ich utf-8 wünsche, warum geht dann das Modul wieder auf ascii?

Mein Quellcode an der Stelle:

Code: Alles auswählen

urllib.request.urlopen(self.url).read().decode('utf-8')
Und dann das Modul:

Code: Alles auswählen

self._output(request.encode('ascii'))

Re: utf-8 vs. ascii: Codierungsproblem beim urrlib.request-M

Verfasst: Donnerstag 30. Juli 2015, 22:29
von /me
pixewakb hat geschrieben:Für mich ist folgende Sache unklar: Wenn ich oben doch klar sage, dass ich utf-8 wünsche, warum geht dann das Modul wieder auf ascii?

Code: Alles auswählen

urllib.request.urlopen(self.url).read().decode('utf-8')
Dort sagst du aber nicht, dass du UTF-8 wünschst. Dort gehst du davon aus, dass du via read() bereits eine in UTF-8 kodierte Bytefolge bekommst aus der du Unicode machen möchtest.

Re: utf-8 vs. ascii: Codierungsproblem beim urrlib.request-M

Verfasst: Donnerstag 30. Juli 2015, 22:43
von BlackJack
@pixewakb: Was Du Dir *wünscht* ist völlig Wurst, URLs sind halt reines ASCII. Zeichen ausserhalb dieses Wertebereichs müssen als Punycode kodiert werden.