Документация Python неофициальный перевод

email-examples.md

345 строк · 13.7 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.2/library/email-examples.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 18.1.11. [`email`](https://python-all.ru/3.2/library/email.html#module-email): Примеры89Вот несколько примеров использования пакета [`email`](https://python-all.ru/3.2/library/email.html#module-email) для чтения, записи и отправки простых email-сообщений, а также более сложных MIME-сообщений.1011Сначала посмотрим, как создать и отправить простое текстовое сообщение:1213```python14# Импорт smtplib для функции отправки15import smtplib1617# Импортируются необходимые модули email.18from email.mime.text import MIMEText1920# Открыть обычный текстовый файл для чтения. В этом примере предполагается, что21# текстовый файл содержит только символы ASCII.22fp = open(textfile, 'rb')23# Создать сообщение text/plain24msg = MIMEText(fp.read())25fp.close()2627# me == адрес электронной почты отправителя28# you == адрес электронной почты получателя29msg['Subject'] = 'The contents of %s' % textfile30msg['From'] = me31msg['To'] = you3233# Отправить сообщение через собственный SMTP-сервер.34s = smtplib.SMTP('localhost')35s.send_message(msg)36s.quit()37```3839Разбор заголовков RFC822 легко выполняется с помощью методов parse(filename) или parsestr(message\_as\_string) класса Parser():4041```python42# Импортируются необходимые модули email.43from email.parser import Parser4445#  Если заголовки электронного письма находятся в файле, раскомментируйте эту строку:46#headers = Parser().parse(open(messagefile, 'r'))4748#  Или для разбора заголовков из строки используйте:49headers = Parser().parsestr('From: <user@example.com>\n'50        'To: <someone_else@example.com>\n'51        'Subject: Test message\n'52        '\n'53        'Body would go here\n')5455#  Теперь к элементам заголовков можно обращаться как к словарю:56print('To: %s' % headers['to'])57print('From: %s' % headers['from'])58print('Subject: %s' % headers['subject'])59```6061Вот пример отправки MIME-сообщения, содержащего много семейных фотографий, которые могут находиться в каталоге:6263```python64# Импорт smtplib для функции отправки65import smtplib6667# Вот модули пакета email, которые нам понадобятся68from email.mime.image import MIMEImage69from email.mime.multipart import MIMEMultipart7071COMMASPACE = ', '7273# Создать контейнер (внешнее) email-сообщение.74msg = MIMEMultipart()75msg['Subject'] = 'Our family reunion'76# me == адрес электронной почты отправителя77# family = список адресов электронной почты всех получателей78msg['From'] = me79msg['To'] = COMMASPACE.join(family)80msg.preamble = 'Our family reunion'8182# Предположим, что все файлы изображений в формате PNG.83for file in pngfiles:84    # Открыть файлы в двоичном режиме. Пусть класс MIMEImage автоматически85    # определяет конкретный тип изображения.86    fp = open(file, 'rb')87    img = MIMEImage(fp.read())88    fp.close()89    msg.attach(img)9091# Отправляем email через собственный SMTP-сервер.92s = smtplib.SMTP('localhost')93s.send_message(msg)94s.quit()95```9697Вот пример отправки всего содержимого каталога в виде email- сообщения: [\[1\]](https://python-all.ru/3.2/library/email-examples.html#id4)9899```python100#!/usr/bin/env python3101102"""Отправляем содержимое каталога как MIME-сообщение."""103104import os105import sys106import smtplib107# Для определения типа MIME по расширению имени файла108import mimetypes109110from optparse import OptionParser111112from email import encoders113from email.message import Message114from email.mime.audio import MIMEAudio115from email.mime.base import MIMEBase116from email.mime.image import MIMEImage117from email.mime.multipart import MIMEMultipart118from email.mime.text import MIMEText119120COMMASPACE = ', '121122def main():123    parser = OptionParser(usage="""\124Send the contents of a directory as a MIME message.125126Usage: %prog [options]127128Unless the -o option is given, the email is sent by forwarding to your local129SMTP server, which then does the normal delivery process.  Your local machine130must be running an SMTP server.131""")132    parser.add_option('-d', '--directory',133                      type='string', action='store',134                      help="""Mail the contents of the specified directory,135                      otherwise use the current directory.  Only the regular136                      files in the directory are sent, and we don't recurse to137                      subdirectories.""")138    parser.add_option('-o', '--output',139                      type='string', action='store', metavar='FILE',140                      help="""Print the composed message to FILE instead of141                      sending the message to the SMTP server.""")142    parser.add_option('-s', '--sender',143                      type='string', action='store', metavar='SENDER',144                      help='The value of the From: header (required)')145    parser.add_option('-r', '--recipient',146                      type='string', action='append', metavar='RECIPIENT',147                      default=[], dest='recipients',148                      help='A To: header value (at least one required)')149    opts, args = parser.parse_args()150    if not opts.sender or not opts.recipients:151        parser.print_help()152        sys.exit(1)153    directory = opts.directory154    if not directory:155        directory = '.'156    # Создать внешнее (оборачивающее) сообщение.157    outer = MIMEMultipart()158    outer['Subject'] = 'Contents of directory %s' % os.path.abspath(directory)159    outer['To'] = COMMASPACE.join(opts.recipients)160    outer['From'] = opts.sender161    outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'162163    for filename in os.listdir(directory):164        path = os.path.join(directory, filename)165        if not os.path.isfile(path):166            continue167        # Определяем тип содержимого по расширению файла. Кодировка168        # будет проигнорирована, хотя стоит проверять простые вещи, такие как169        # gzip-файлы или сжатые файлы.170        ctype, encoding = mimetypes.guess_type(path)171        if ctype is None or encoding is not None:172            # Не удалось определить тип, или файл закодирован (сжат), поэтому173            # используем общий тип 'набор битов'.174            ctype = 'application/octet-stream'175        maintype, subtype = ctype.split('/', 1)176        if maintype == 'text':177            fp = open(path)178            # Примечание: нужно обработать вычисление кодировки.179            msg = MIMEText(fp.read(), _subtype=subtype)180            fp.close()181        elif maintype == 'image':182            fp = open(path, 'rb')183            msg = MIMEImage(fp.read(), _subtype=subtype)184            fp.close()185        elif maintype == 'audio':186            fp = open(path, 'rb')187            msg = MIMEAudio(fp.read(), _subtype=subtype)188            fp.close()189        else:190            fp = open(path, 'rb')191            msg = MIMEBase(maintype, subtype)192            msg.set_payload(fp.read())193            fp.close()194            # Закодировать полезную нагрузку с помощью Base64.195            encoders.encode_base64(msg)196        # Установить параметр filename.197        msg.add_header('Content-Disposition', 'attachment', filename=filename)198        outer.attach(msg)199    # Теперь отправляем или сохраняем сообщение200    composed = outer.as_string()201    if opts.output:202        fp = open(opts.output, 'w')203        fp.write(composed)204        fp.close()205    else:206        s = smtplib.SMTP('localhost')207        s.sendmail(opts.sender, opts.recipients, composed)208        s.quit()209210if __name__ == '__main__':211    main()212```213214Вот пример распаковки MIME-сообщения вроде показанного выше в каталог с файлами:215216```python217#!/usr/bin/env python3218219"""Распаковываем MIME-сообщение в каталог файлов."""220221import os222import sys223import email224import errno225import mimetypes226227from optparse import OptionParser228229def main():230    parser = OptionParser(usage="""\231Unpack a MIME message into a directory of files.232233Usage: %prog [options] msgfile234""")235    parser.add_option('-d', '--directory',236                      type='string', action='store',237                      help="""Unpack the MIME message into the named238                      directory, which will be created if it doesn't already239                      exist.""")240    opts, args = parser.parse_args()241    if not opts.directory:242        parser.print_help()243        sys.exit(1)244245    try:246        msgfile = args[0]247    except IndexError:248        parser.print_help()249        sys.exit(1)250251    try:252        os.mkdir(opts.directory)253    except OSError as e:254        # Игнорировать ошибку существования каталога255        if e.errno != errno.EEXIST:256            raise257258    fp = open(msgfile)259    msg = email.message_from_file(fp)260    fp.close()261262    counter = 1263    for part in msg.walk():264        # multipart/* – это просто контейнеры265        if part.get_content_maintype() == 'multipart':266            continue267        # Приложениям следует тщательно проверять имя файла, чтобы268        # email-сообщение не могло перезаписать важные файлы269        filename = part.get_filename()270        if not filename:271            ext = mimetypes.guess_extension(part.get_content_type())272            if not ext:273                # Использовать универсальное расширение для набора битов.274                ext = '.bin'275            filename = 'part-%03d%s' % (counter, ext)276        counter += 1277        fp = open(os.path.join(opts.directory, filename), 'wb')278        fp.write(part.get_payload(decode=True))279        fp.close()280281if __name__ == '__main__':282    main()283```284285Here’s an example of how to create an HTML message with an alternative plain text version: [\[2\]](https://python-all.ru/3.2/library/email-examples.html#id5)286287```python288#!/usr/bin/env python3289290import smtplib291292from email.mime.multipart import MIMEMultipart293from email.mime.text import MIMEText294295# me == мой адрес электронной почты.296# you == адрес электронной почты получателя.297me = "my@email.com"298you = "your@email.com"299300# Создать контейнер сообщения – правильный тип MIME – multipart/alternative.301msg = MIMEMultipart('alternative')302msg['Subject'] = "Link"303msg['From'] = me304msg['To'] = you305306# Создать тело сообщения (версии в виде простого текста и HTML).307text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org"308html = """\309<html>310  <head></head>311  <body>312    <p>Hi!<br>313       How are you?<br>314       Here is the <a href="http://www.python.org">link</a> you wanted.315    </p>316  </body>317</html>318"""319320# Записать MIME-типы обеих частей – text/plain и text/html.321part1 = MIMEText(text, 'plain')322part2 = MIMEText(html, 'html')323324# Прикрепить части к контейнеру сообщения.325# Согласно RFC 2046, последняя часть многокомпонентного сообщения, в данном случае326# HTML-сообщение, является наилучшим и предпочтительным.327msg.attach(part1)328msg.attach(part2)329330# Отправка сообщения через локальный SMTP-сервер.331s = smtplib.SMTP('localhost')332# Функция sendmail принимает 3 аргумента: адрес отправителя, адрес получателя333# и сообщение для отправки – здесь оно отправляется в виде одной строки.334s.sendmail(me, you, msg.as_string())335s.quit()336```337338Сноски339340| [\[1\]](https://python-all.ru/3.2/library/email-examples.html#id2) | Спасибо Matthew Dixon Cowles за оригинальную идею и примеры. |341| --- | --- |342343| [\[2\]](https://python-all.ru/3.2/library/email-examples.html#id3) | Автор: Martin Matejek. |344| --- | --- |345