Email header decode python

Электронная почта:Интернационализированные заголовки

Этот модуль является частью устаревшего ( Compat32 ) почтового API. В текущем API кодирование и декодирование заголовков прозрачно обрабатывается аналогичным словарю API класса EmailMessage . Помимо использования в устаревшем коде, этот модуль может быть полезен в приложениях, которым необходимо полностью контролировать наборы символов, используемые при кодировании заголовков.

Остальной текст в этом разделе является оригинальной документацией модуля.

RFC 2822 — это базовый стандарт, описывающий формат сообщений электронной почты. Он происходит от более старого стандарта RFC 822 , который получил широкое распространение в то время, когда большая часть электронной почты состояла только из символов ASCII. RFC 2822 — это спецификация, написанная в предположении, что электронная почта содержит только 7-битные символы ASCII.

Конечно, по мере распространения электронной почты по всему миру она стала интернационализированной, так что теперь в сообщениях электронной почты можно использовать наборы символов для конкретных языков. Базовый стандарт по-прежнему требует, чтобы сообщения электронной почты передавались с использованием только 7-битных символов ASCII, поэтому было написано множество RFC, описывающих, как кодировать электронную почту, содержащую символы, отличные от ASCII, в формат, совместимый с RFC 2822 . Эти RFC включают RFC 2045 , RFC 2046 , RFC 2047 и RFC 2231 . Пакет email поддерживает эти стандарты в своих email.header и email.charset .

Если вы хотите включить не-ASCII символы в ваших электронной почте заголовки, скажем , в Subject или Для полей, вы должны использовать Header и назначаете поле в Message объекте к экземпляру Header вместо того , чтобы использовать строку для значения заголовка . Импортируйте класс Header из модуля email.header . Например:

>>> from email.message import Message >>> from email.header import Header >>> msg = Message() >>> h = Header('p\xf6stal', 'iso-8859-1') >>> msg['Subject'] = h >>> msg.as_string() 'Subject: =?iso-8859-1?q?p=F6stal?=\n\n'

Обратите внимание, как мы хотели, чтобы поле « Тема » содержало не-ASCII-символ? Мы сделали это, создав экземпляр Header и передав набор символов, в котором была закодирована строка байтов. Когда последующий экземпляр Message был сведен, поле Subject было правильно закодировано в соответствии с RFC 2047 . Читатели почты с поддержкой MIME будут отображать этот заголовок, используя встроенный символ ISO-8859-1.

Читайте также:  Settings php bitrix cache

class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=’ ‘, errors=’strict’)

Создайте MIME-совместимый заголовок,который может содержать строки в различных наборах символов.

Необязательный параметр s — это начальное значение заголовка. Если None (по умолчанию), начальное значение заголовка не устанавливается. Позже вы можете добавить к заголовку вызовы метода append() .s может быть экземпляром bytes или str , но семантику смотрите в документации append() .

Необязательный набор символов служит двум целям: он имеет то же значение, что и аргумент набора символов в методе append() .Он также устанавливает набор символов по умолчанию для всех последующих вызовов append() , которые пропускают аргумент charset . Если набор символов не указан в конструкторе (по умолчанию), набор символов us-ascii используется как в качестве исходного набора символов s , так и по умолчанию для последующих вызовов append() .

Максимальная длина строки может быть указана явно через maxlinelen . Для разделения первой строки на более короткое значение (для учета заголовка поля, который не включен в s , например Subject ) передайте имя поля в header_name . Значение maxlinelen по умолчанию равно 76, а значение по умолчанию для header_name — None , что означает, что оно не учитывается для первой строки длинного разделенного заголовка.

Необязательный continue_ws должен соответствовать стандарту RFC 2822 и обычно представляет собой либо пробел, либо символ жесткой табуляции. Этот символ будет добавлен к строкам продолжения. continue_ws по умолчанию использует один символ пробела.

Необязательные ошибки передаются прямо в метод append() .

append(s, charset=None, errors=’strict’)

Добавьте строку s в заголовок MIME.

Дополнительный набор символов , если дано, должно быть Charset экземпляр (см email.charset ) или имя набора символов, который будет преобразован в Charset инстанции. Значение None (по умолчанию) означает, что используется кодировка, указанная в конструкторе.

s может быть экземпляром bytes или str . Если это экземпляр bytes , то charset — это кодировка этой строки байтов, и UnicodeError будет вызван, если строка не может быть декодирована с этим набором символов.

Если s является экземпляром str , то charset является подсказкой, определяющей набор символов в строке.

В любом случае, при создании заголовка , совместимого с RFC 2822 , с использованием правил RFC 2047 , строка будет закодирована с использованием выходного кодека набора символов. Если строка не может быть закодирована с помощью выходного кодека, будет выдано сообщение об ошибке UnicodeError.

Необязательные ошибки передаются в качестве аргумента ошибок в вызове декодирования, если s является байтовой строкой.

encode(splitchars=’;, \t’, maxlinelen=None, linesep=’\n’)

Кодируйте заголовок сообщения в RFC-совместимом формате,возможно,обертывая длинные строки и инкапсулируя не-ASCII части в кодировки base64 или в кодировках,пригодных для печати в кавычках.

Необязательные разделительные символы — это строка, содержащая символы, которым алгоритм разделения должен придавать дополнительный вес при обычном переносе заголовка. Это очень грубая поддержка « синтаксических разрывов более высокого уровня» RFC 2822 : точки разделения, которым предшествует разделительный символ, предпочтительны при разделении строки, при этом символы предпочтительны в том порядке, в котором они появляются в строке. Пробел и табуляция могут быть включены в строку, чтобы указать, следует ли отдавать предпочтение одному над другим в качестве точки разделения, когда другие символы разделения не появляются в разделяемой строке. Splitchars не влияет на закодированные строки RFC 2047 .

maxlinelen , если задано, переопределяет значение экземпляра для максимальной длины строки.

linesep определяет символы, используемые для разделения строк загнутого заголовка. По умолчанию используется наиболее полезное значение для кода приложения Python ( \n ), но можно указать \r\n для создания заголовков с разделителями строк, совместимыми с RFC.

Изменено в версии 3.2: Добавлен аргумент linesep .

Класс Header также предоставляет ряд методов для поддержки стандартных операторов и встроенных функций.

Возвращает аппроксимацию Header в виде строки с неограниченной длиной строки. Все фрагменты конвертируются в Unicode с использованием указанной кодировки и соответствующим образом соединяются. Любые фрагменты с кодировкой ‘unknown-8bit’ декодируются как ASCII с использованием обработчика ошибок ‘replace’ .

Изменено в версии 3.2: Добавлена ​​обработка кодировки ‘unknown-8bit’ .

Этот метод позволяет сравнить два экземпляра Header предмет равенства.

Этот метод позволяет сравнить два экземпляра Header предмет неравенства.

Модуль email.header также предоставляет следующие удобные функции.

Расшифруйте значение заголовка сообщения без преобразования набора символов. Значение заголовка находится в заголовке .

Эта функция возвращает список (decoded_string, charset) содержащих каждую из декодированных частей заголовка. charset — None для незакодированных частей заголовка, в противном случае — строка нижнего регистра, содержащая имя набора символов, указанного в кодированной строке.

>>> from email.header import decode_header >>> decode_header('=?iso-8859-1?q?p=F6stal?=') [(b'p\xf6stal', 'iso-8859-1')]

Создайте экземпляр Header из последовательности пар, возвращаемых decode_header() .

decode_header() принимает строку значения заголовка и возвращает последовательность пар формата (decoded_string, charset) где charset — это имя набора символов.

Эта функция принимает одну из этих последовательностей пар и возвращает экземпляр Header . Необязательные maxlinelen , header_name и continue_ws такие же, как в конструкторе Header .

Python 3.11

Вот несколько примеров использования пакета электронной почты для чтения,записи и отправки простых сообщений,а также более сложных MIME Во-первых,давайте посмотрим,как создавать и

Исходный код:Lib/email/generator.py Одной из наиболее распространенных задач является генерация плоской (сериализованной)версии почтового сообщения,представленного объектной структурой.

Исходный код:Lib/email/headerregistry.py Новое в версии 3.6:1 Заголовки представлены специализированными подклассами str.

Исходный код:Lib/email/iterators.py Итерация по дереву объектов сообщений довольно проста с помощью метода Message.walk.

Источник

sdkn104 / decode_email.py

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

import imaplib , email , email . parser , email . policy
import html2text
import pprint , sys
#
# Utilities for Debug
#
pp = pprint . PrettyPrinter ( indent = 4 , width = 80 )
def myprint ( str ):
print ( str . encode ( ‘cp932’ , ‘replace’ ). decode ( ‘cp932’ ))
#
# search mails in IMAP
#
def search_imap ():
#mail = imaplib.IMAP4_SSL(«imap.mail.com», 993)
mail = imaplib . IMAP4_SSL ( «imap.mail.yahoo.co.jp» )
mail . login ( «sdkn104@yahoo.co.jp» , «xxxxxx» )
mail . list ()
mail . select ( ‘Inbox’ ) # specify inbox
#mail.select(‘register’) # specify label
#typ, [data] = mail.search(None, «UNSEEN»)
typ , [ data ] = mail . search ( None , «(ALL)» )
print ( «searched» )
print ( typ )
pp . pprint ( data . split ())
#check
if typ == «OK» :
if data != » :
print ( «New Mail» )
else :
print ( «Non» )
# for each mail searched
for num in data . split ():
print ( «START » + str ( num ) + «—————————————————» )
# fetch whole message as RFC822 format
result , d = mail . fetch ( num , «(RFC822)» )
# save to file
f = open ( «mail_» + str ( num ) + «.txt» , «bw» )
f . write ( d [ 0 ][ 1 ])
f . close ()
print ( «####################################» )
msg = email2Text ( d [ 0 ][ 1 ])
print ( «————————————» )
myprint ( msg [ «subject» ])
myprint ( msg [ «date» ])
myprint ( msg [ «from» ])
myprint ( msg [ «body» ])
# closing
mail . close ()
mail . logout ()
#
# Get subject, date, from and body as text from email RFC822 style string
#
def email2Text ( rfc822mail ):
# parse the message
msg_data = email . message_from_bytes ( rfc822mail , policy = email . policy . default )
mail_value = <>
# Get From, Date, Subject
mail_value [ «from» ] = header_decode ( msg_data . get ( ‘From’ ))
mail_value [ «date» ] = header_decode ( msg_data . get ( ‘Date’ ))
mail_value [ «subject» ] = header_decode ( msg_data . get ( ‘Subject’ ))
#print( mail_value[«date»] )
#print( mail_value[«from»] )
#print( mail_value[«subject»] )
# Get Body
#print(«— body —«)
mail_value [ «body» ] = «»
if msg_data . is_multipart ():
for part in msg_data . walk ():
#print(«— part —«)
ddd = msg2bodyText ( part )
if ddd is not None :
mail_value [ «body» ] = mail_value [ «body» ] + ddd
else :
#print(«— single —«)
ddd = msg2bodyText ( msg_data )
mail_value [ «body» ] = ddd
return mail_value
#
# get body text from a message (EmailMessage instance)
#
def msg2bodyText ( msg ):
ct = msg . get_content_type ()
cc = msg . get_content_charset () # charset in Content-Type header
cte = msg . get ( «Content-Transfer-Encoding» )
print ( «part: » + str ( ct ) + » » + str ( cc ) + » : » + str ( cte ))
# skip non-text part/msg
if msg . get_content_maintype () != «text» :
return None
# get text
ddd = msg . get_content ()
# html to text
if msg . get_content_subtype () == «html» :
try :
ddd = html2text . html2text ( ddd )
except :
print ( «error in html2text» )
return ddd
def header_decode ( header ):
hdr = «»
for text , encoding in email . header . decode_header ( header ):
if isinstance ( text , bytes ):
text = text . decode ( encoding or «us-ascii» )
hdr += text
return hdr
if __name__ == «__main__» :
search_imap ()

Источник

Оцените статью