'str' nesnesinin 'decode' özelliği yoktur. Python 3 hatası?


182

İşte benim kod:

import imaplib
from email.parser import HeaderParser

conn = imaplib.IMAP4_SSL('imap.gmail.com')
conn.login('example@gmail.com', 'password')
conn.select()
conn.search(None, 'ALL')
data = conn.fetch('1', '(BODY[HEADER])')
header_data = data[1][0][1].decode('utf-8')

bu noktada hata mesajı alıyorum

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

Python 3'te kod çözme artık yok, değil mi? bunu nasıl düzeltebilirim?

Ayrıca:

data = conn.fetch('1', '(BODY[HEADER])')

Sadece 1. e-postayı seçiyorum. Tümünü nasıl seçerim?

Yanıtlar:


181

Zaten kodu çözülmüş bir nesnenin kodunu çözmeye çalışıyorsunuz . Artık bir strUTF-8 kodunu çözmenize gerek yok.

Sadece .decode('utf-8')parçayı bırakın :

header_data = data[1][0][1]

fetch()Aramanıza gelince , açıkça sadece ilk mesajı istiyorsunuz. Daha fazla mesaj almak istiyorsanız bir aralık kullanın. Belgelere bakın :

Aşağıdaki komutlara yönelik message_set seçenekleri, işlem yapılacak bir veya daha fazla iletiyi belirten bir dizedir. Basit bir mesaj numarası ( '1'), bir dizi mesaj numarası ( '2:4') veya virgül ( '1:3,6:9') ile ayrılmış bitişik olmayan aralıklardan oluşan bir grup olabilir . Bir aralık, sonsuz bir üst sınırı ( '3:*') belirtmek için bir yıldız işareti içerebilir .


6
Bunu şartlı olarak yapmanın basit bir yolu var mı? (Sadece mesaj kodlanmışsa kodunu çözmek istiyorum.)
devinbost

5
@devinbost: Python 3'te mi? Nesne türünü veya decodeniteliğini test edin veya sadece istisnayı yakalayın. try: data = data.decode('...') except AttributeError: pass.
Martijn Pieters

2
@devinbost: Ancak, genellikle tam olarak neye sahip olduğunuzu bileceğiniz verilerin kaynağına daha yakın olan kod çözme işleminden daha iyi durumdasınızdır.
Martijn Pieters

37

Python 3 ile başlayın, tüm dize unicode nesnesidir.

  a = 'Happy New Year' # Python 3
  b = unicode('Happy New Year') # Python 2

önceki kod aynı. Yani bence kaldırmalısınız .decode('utf-8'). Çünkü zaten unicode nesnesini aldınız.


37

Bu yöntemle kullanın:

str.encode().decode()

1
bytearray(str, 'encoding').decode('another_encoding')kod çözme idnaveya başka bir kodlama gerekiyorsa işi yapardı
Alex

20
Bu işe yaramaz. UTF-8 olarak kodluyorsunuz ve sonuçta elde edilen baytların UTF-8 olarak kodunu çözüyorsunuz ve sonunda başladığınız yerde bitiyorsunuz. CPU'yu başka bir fayda olmadan sıcak tutuyorsunuz.
Martijn Pieters

1
@MartijnPieters "başladığınız yerde bitiyor" - dizenizde kaçış dizileri varsa değil, örneğin: >>> '\ u0159'.encode (). Decode ()' ř '
Peter

1
@Peter: hayır, bunun için kodlamaya veya kod çözmeye ihtiyacınız yok. '\u0159'aynı çıktıyı yazdırır. Dize değişmez sözdizimini, değerin standart gösterimi ile karıştırıyorsunuz.
Martijn Pieters

2
Doğrudan kullanabilirsiniz, Kodlamaya ve daha sonra tekrar kod çözmeye gerek yoktur.
Aditya

10

Python3 için

html = """\\u003Cdiv id=\\u0022contenedor\\u0022\\u003E \\u003Ch2 class=\\u0022text-left m-b-2\\u0022\\u003EInformaci\\u00f3n del veh\\u00edculo de patente AA345AA\\u003C\\/h2\\u003E\\n\\n\\n\\n \\u003Cdiv class=\\u0022panel panel-default panel-disabled m-b-2\\u0022\\u003E\\n \\u003Cdiv class=\\u0022panel-body\\u0022\\u003E\\n \\u003Ch2 class=\\u0022table_title m-b-2\\u0022\\u003EInformaci\\u00f3n del Registro Automotor\\u003C\\/h2\\u003E\\n \\u003Cdiv class=\\u0022col-md-6\\u0022\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003ERegistro Seccional\\u003C\\/label\\u003E\\n \\u003Cp\\u003ESAN MIGUEL N\\u00b0 1\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EDirecci\\u00f3n\\u003C\\/label\\u003E\\n \\u003Cp\\u003EMAESTRO ANGEL D\\u0027ELIA 766\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EPiso\\u003C\\/label\\u003E\\n \\u003Cp\\u003EPB\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EDepartamento\\u003C\\/label\\u003E\\n \\u003Cp\\u003E-\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EC\\u00f3digo postal\\u003C\\/label\\u003E\\n \\u003Cp\\u003E1663\\u003C\\/p\\u003E\\n \\u003C\\/div\\u003E\\n \\u003Cdiv class=\\u0022col-md-6\\u0022\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003ELocalidad\\u003C\\/label\\u003E\\n \\u003Cp\\u003ESAN MIGUEL\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EProvincia\\u003C\\/label\\u003E\\n \\u003Cp\\u003EBUENOS AIRES\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003ETel\\u00e9fono\\u003C\\/label\\u003E\\n \\u003Cp\\u003E(11)46646647\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EHorario\\u003C\\/label\\u003E\\n \\u003Cp\\u003E08:30 a 12:30\\u003C\\/p\\u003E\\n \\u003C\\/div\\u003E\\n \\u003C\\/div\\u003E\\n\\u003C\\/div\\u003E \\n\\n\\u003Cp class=\\u0022text-center m-t-3 m-b-1 hidden-print\\u0022\\u003E\\n \\u003Ca href=\\u0022javascript:window.print();\\u0022 class=\\u0022btn btn-default\\u0022\\u003EImprim\\u00ed la consulta\\u003C\\/a\\u003E \\u0026nbsp; \\u0026nbsp;\\n \\u003Ca href=\\u0022\\u0022 class=\\u0022btn use-ajax btn-primary\\u0022\\u003EHacer otra consulta\\u003C\\/a\\u003E\\n\\u003C\\/p\\u003E\\n\\u003C\\/div\\u003E"""
print(html.replace("\\/", "/").encode().decode('unicode_escape'))

Seni çok seviyorum!
Gal Shahar

8

Kütüphaneye aşina değilim, ancak sorununuz bayt dizisi istemiyorsanız, kolay bir yol doğrudan bir dökümde bir kodlama türü belirtmektir:

>>> my_byte_str
b'Hello World'

>>> str(my_byte_str, 'utf-8')
'Hello World'

bytesBaşlamak için bir nesneleri yok ve str(bytes_object, codec)sadece alternatif bir yazım bytes_object.decode(codec). Gerçekten bir tane varsa her ikisi de başarısız olur str.
Martijn Pieters

1
Haklısın, bu özel sorunun strzaten bir sorusu var . Bu cevap, gelecekte byte dizileri olabilecek insanlar için yararlı olabilir (bu, bu yazıyı ilk kez tökezlediğimde karşılaştığım sorundu).
Broper

Ancak, bu gönderiyi nasıl tökezlediğinden emin değilim, çünkü my_byte_str.decodevar ve çalışıyor ve sorudaki istisnayı atmayacak.
Martijn Pieters


0

Diğer cevaplar bir tür ipucu verir, ancak sorun bir bayt nesnesi beklemekten kaynaklanabilir. Python 3'te kod çözme, sınıf baytlık bir nesneniz olduğunda geçerlidir. Kod çözme işleminden önce kodlamanın çalıştırılması sorunu "düzeltebilir", ancak sorunu bize yukarı yönde gösteren gereksiz işlemlerdir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.