2016-10-13 10 views
2

ich eine Zeichenfolge von Web-Crawl-Skript extrahiert haben, wie folgend:Python, wie Unicode mit Hex-Zeichen dekodieren

u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91' 

I u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91' mit utf-8 entschlüsseln wollen. Mit http://ddecode.com/hexdecoder/, kann ich das Ergebnis sehen '【中字】'

Ich habe versucht, mit der folgenden Syntax, aber gescheitert.

msg = u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91' 
result = msg.decode('utf8') 

Fehler:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-11: ordi 
nal not in range(128) 

Darf ich fragen, wie die Zeichenfolge richtig zu entschlüsseln?

Danke für Hilfe.

+2

Die Zeichenfolge, die Sie empfangen, ist doppelt codiert. Es funktioniert gut ohne das "u" vor der Zeichenfolge. Sie sollten das Crawl-Skript überprüfen! –

Antwort

1

Das Problem mit

msg = u'\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91' 
result = msg.decode('utf8') 

ist, dass Sie Unicode zu entschlüsseln versuchen. Das macht keinen Sinn. Sie können von Unicode in eine Art Codierung kodieren, oder Sie können eine Bytezeichenfolge in Unicode dekodieren.

Wenn Sie

msg.decode('utf8') 

Python 2 tun sieht, dass msg Unicode ist. Es weiß, dass es Unicode nicht decodieren kann, so dass es "hilfreich" davon ausgeht, dass Sie msg mit dem Standard-ASCII-Codec codieren möchten, sodass das Ergebnis dieser Umwandlung mit dem UTF-8-Codec in Unicode decodiert werden kann. Python 3 verhält sich viel sinnvoller: der Code würde einfach nicht mit

AttributeError: 'str' object has no attribute 'decode' 

Die in kennytm Antwort gegeben Technik:

msg.encode('latin1').decode('utf-8') 

funktioniert, weil die Unicode-Codepunkte weniger als 256 entsprechen direkt die Zeichen im Latin1 Kodierung (aka ISO 8859-1).

Hier einige Python 2-Code, der dies veranschaulicht:

for i in xrange(256): 
    lat = chr(i) 
    uni = unichr(i) 
    assert lat == uni.encode('latin1') 
    assert lat.decode('latin1') == uni 

Und hier ist das Äquivalent Python 3-Code:

for i in range(256): 
    lat = bytes([i]) 
    uni = chr(i) 
    assert lat == uni.encode('latin1') 
    assert lat.decode('latin1') == uni 

Sie finden diesen Artikel hilfreich: Pragmatic Unicode, die durch SO geschrieben wurde Veteran Ned Batchelder.

Sofern Sie nicht gezwungen sind, Python 2 zu verwenden, rate ich Ihnen dringend, zu Python 3 zu wechseln. Es wird die Handhabung von Unicode viel weniger schmerzhaft machen.

0

Nur msg als Zeichenfolge nicht Unicode beibehalten.

msg = '\xe3\x80\x90\xe4\xb8\xad\xe5\xad\x97\xe3\x80\x91' 
result = msg.decode('utf8') 
+0

Ich hatte das schon mal versucht, aber auch gescheitert. Ich habe Fehler wie "UnicodeEncodeError: 'ascii' Codec kann nicht codieren Zeichen in Position 0-11: ordi nicht im Bereich (128)" –

2
  1. Vielleicht sollen Sie das Crawling-Skript stattdessen beheben, ein Unicode-String sollte u'【中字】' (u'\u3010\u4e2d\u5b57\u3011') bereits anstelle des rohen UTF-8-Bytes enthalten.

  2. Um msg auf die richtige Codierung zu konvertieren, müssen Sie zuerst den falschen Unicode-String zurück auf Byte-String drehen (kodieren sie als Latin-1), dann dekodieren es als UTF-8:

    >>> print msg.encode('latin1').decode('utf-8') 
    【中字】 
    
+0

WOW, also msg.encode ('latin1') bedeutet, dass es in Byte-String Es scheint funktioniert !!! vielen Dank!!! –

+0

@ShootingChuang Art von Art. :) Bitte lesen Sie meine Antwort und den verlinkten Wikipedia-Artikel für weitere Details. –