2012-06-16 10 views
8

Ich habe dieses Problem versucht, alle Textknoten in einem HTML-Dokument mit lxml zu bekommen, aber ich bekomme einen UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 8995: ordinal not in range(128). Jedoch, wenn ich versuche, den Typ der Codierung dieser Seite (encoding = chardet.detect(response)['encoding']) herauszufinden, heißt es utf-8. Es scheint seltsam, dass eine einzelne Seite utf-8 und ascii hat. Eigentlich ist dies:UnicodeEncodeError beim Abrufen der URL

fromstring(response).text_content().encode('ascii', 'replace') 

löst das Problem.

Hier ist es mein Code:

from lxml.html import fromstring 
import urllib2 
import chardet 
request = urllib2.Request(my_url) 
request.add_header('User-Agent', 
        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)') 
request.add_header("Accept-Language", "en-us") 
response = urllib2.urlopen(request).read() 

print encoding 
print fromstring(response).text_content() 

Ausgang:

utf-8 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 8995: ordinal not in range(128) 

Was kann ich tun, um dieses Problem zu lösen ?. Denken Sie daran, dass ich dies mit ein paar anderen Seiten machen möchte, also möchte ich nicht auf einer individuellen Basis verschlüsseln.

UPDATE:

Vielleicht ist es etwas anderes, hier geht. Wenn ich dieses Skript auf dem Terminal ausführen, bekomme ich eine korrekte Ausgabe, aber wenn ich es in SublimeText ausführen, bekomme ich UnicodeEncodeError ... ¿?

UPDATE2:

Es passiert auch, wenn ich eine Datei mit dieser Ausgabe erstellen. .encode('ascii', 'replace') funktioniert, aber ich hätte gerne eine allgemeinere Lösung.

Grüße

+1

Erzeugt 'print u '\ u00A9" 'in Ihrem Skript auch den Fehler? – jfs

+0

Ja.UnicodeEncodeError: 'ascii' Codec kann nicht codieren Charakter u \ 'xA9' in Position 0: Ordnungszahl nicht in Reichweite (128) :-) –

+0

Sie PYTHONIOENCODING, was auch immer Zeichencodierung Sublime Text akzeptiert einstellen könnte. – jfs

Antwort

5

Können Sie versuchen, Ihre Zeichenfolge mit repr() zu umhüllen? This article könnte helfen.

print repr(fromstring(response).text_content()) 
+0

Dies funktioniert gut in Sublime Text und auch in Terminal. Ich denke, das ist ein Workarond. Vielen Dank! –

0

auf dem ersten Update Basierend würde ich sagen, dass das Terminal Python zur Ausgabe utf-8 erzählt und Sublime Text deutlich gemacht, es erwartet ascii. Ich denke, die Lösung wird darin bestehen, die richtigen Einstellungen in SublimeText zu finden.

Wenn Sie jedoch nicht ändern können, was SublimeText erwartet, ist es besser, die Funktion encode zu verwenden, wie Sie es bereits in einer separaten Funktion getan haben.

def smartprint(text) : 
    if sys.stdout.encoding == None : 
     print text 
    else : 
     print text.encode(sys.stdout.encoding , 'replace') 

können Sie diese Funktion verwenden, statt print. Beachten Sie, dass sich die Ausgabe Ihres Programms bei Ausführung in SublimeText von Terminal unterscheidet. Wegen der replace verlieren akzentuierte Zeichen ihre Akzente, wenn dieser Code in SublimeText ausgeführt wird, z. é wird als e angezeigt.

3

Soweit Schreiben in eine Datei wie in Ihrem bearbeiten gesagt, würde ich empfehlen, die Datei mit dem Codec-Modul zu öffnen:

import codecs 
output_file = codecs.open('filename.txt','w','utf8') 

ich Sublime Text weiß es nicht, aber es scheint versuchen, Ihre Ausgabe als ASCII zu lesen, daher der Codierungsfehler.

+0

Arbeiten. Vielen Dank! –