Python imaplib .search тема электронной почты Китайцы получили ошибку

Я хочу использовать imaplib для поиска определенных электронных писем, темы которых содержат китайский язык. Я получил ошибку следующим образом:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

поэтому я использую .encode для кодирования в «UTF-8», и у меня ничего не получается. Распечатка распечатки

0
[]

Правильный ответ должен быть 71, который я ищу в своем почтовом ящике. Это мой код:

import imaplib,email
host = 'imap.263.net'
user = '***@***'
psw = '*****'
count = 0
con = imaplib.IMAP4(host,143)
con.login(user,psw)
con.select('INBOX',readonly =True)
eva = '日报'
# eva = eva.encode('utf-8') 
resp,liujf = con.search('UTF-8','SUBJECT','%s'%eva, 'Since','01-Feb-2018')
items = liujf[0].split()
print(len(items))
print(items)

Я думаю, это должна быть проблема с юникодом. Как я могу это исправить?


person Carol Chan    schedule 26.02.2018    source источник


Ответы (2)


Вы передаете необработанную строку Unicode, где вы должны передавать строку в виде последовательности байтов UTF-8. Вы даже пометили его как UTF-8! Это говорит о том, что вы, возможно, захотите прочитать о разнице.

Изменять

'%s'%eva

to

eva.encode('utf-8')

Для получения дополнительной информации, возможно, прочитайте https://www.unicode.org/faq/utf_bom.html#UTF8 и/или https://nedbatchelder.com/text/unipain.html< /а>

Конструкция '%s'%string - это просто уродливый и неидиоматический способ сказать string, но здесь это на самом деле ошибка: '%s'%string.encode('utf-8') создает строку байтов, но затем интерполирует ее в строку Unicode, что дает совершенно неверный результат. Наблюдать:

>>> eva = '日报'
>>> eva.encode('utf-8')              # correct
b'\xe6\x97\xa5\xe6\x8a\xa5'
>>> '%s'%eva.encode('utf-8')         # incorrect
"b'\\xe6\\x97\\xa5\\xe6\\x8a\\xa5'"
>>> b'%s'%eva.encode('utf-8')        # correct but terribly fugly
b'\xe6\x97\xa5\xe6\x8a\xa5'

Обратите внимание, как '%s'%eva.encode('utf-8') берет закодированную строку байтов и преобразует ее обратно в представление Unicode. Закомментированная строка показывает, что вы пробовали eva = eva.encode('utf-8'), но затем, по-видимому, получили неправильный результат из-за ненужной интерполяции % в строку Unicode.

person tripleee    schedule 26.02.2018
comment
Я меняю '%s'%eva на eva.encode('utf-8'). Код теперь такой: resp,liujf = con.search('utf-8','SUBJECT',eva.encode('utf-8'), 'Since','01 февраля 2018'). Результат правильный. Спасибо!!! - person Carol Chan; 26.02.2018
comment
Тем не менее '%s'%something — расточительный и неэлегантный способ написать something. - person tripleee; 26.02.2018
comment
В чем разница между: eva = eva.encode('utf-8') resp,liujf = con.search('utf-8','SUBJECT','%s'%eva и eva.encode('utf- 8') - person Carol Chan; 26.02.2018
comment
О да, тогда '%s'%eva на самом деле неправильно, потому что вы конвертируете его обратно в Unicode (если я правильно понимаю ваш вопрос). b'%s'%eva поступил бы правильно и просто был бы ужасно уродливым. Смотрите обновленный ответ. - person tripleee; 26.02.2018

Я думаю, вы должны сначала декодировать, а затем кодировать китайские литералы. Если мы интерпретируем это как закодированное в латинице-1, то вы сначала декодируете его, а затем кодируете. Ex- eva.decode('latin-1').encode('utf-8')

person Rock    schedule 26.02.2018
comment
он показывает ошибку: eva = eva.decode('latin-1').encode('utf-8') AttributeError: объект 'str' не имеет атрибута 'decode' - person Carol Chan; 26.02.2018
comment
Невозможно декодировать Unicode в Latin-1, если строка Unicode содержит символы, которые не могут быть представлены в Latin-1. Если у вас есть строка байтов, то декодирование ее как Latin-1 преобразует ее в строку Unicode, но тогда у вас есть ошибка где-то еще - Python 3 специально заставляет вас знать кодировку ваших данных, или же сохранить ее как байт. - person tripleee; 26.02.2018