email-examples.md
1> **Источник:** https://python-all.ru/2.7/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/2.7/library/email.html#module-email): Примеры89Вот несколько примеров использования пакета [`email`](https://python-all.ru/2.7/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-сервер, но не включать34# заголовок конверта.35s = smtplib.SMTP('localhost')36s.sendmail(me, [you], msg.as_string())37s.quit()38```3940Разбор заголовков RFC822 легко выполняется с помощью методов parse(filename) или parsestr(message\_as\_string) класса Parser():4142```python43# Импортируются необходимые модули email.44from email.parser import Parser4546# Если заголовки электронного письма находятся в файле, раскомментируйте эту строку:47#headers = Parser().parse(open(messagefile, 'r'))4849# Или для разбора заголовков из строки используйте:50headers = Parser().parsestr('From: <user@example.com>\n'51 'To: <someone_else@example.com>\n'52 'Subject: Test message\n'53 '\n'54 'Body would go here\n')5556# Теперь к элементам заголовков можно обращаться как к словарю:57print 'To: %s' % headers['to']58print 'From: %s' % headers['from']59print 'Subject: %s' % headers['subject']60```6162Вот пример отправки MIME-сообщения, содержащего много семейных фотографий, которые могут находиться в каталоге:6364```python65# Импорт smtplib для функции отправки66import smtplib6768# Вот модули пакета email, которые нам понадобятся69from email.mime.image import MIMEImage70from email.mime.multipart import MIMEMultipart7172COMMASPACE = ', '7374# Создать контейнер (внешнее) email-сообщение.75msg = MIMEMultipart()76msg['Subject'] = 'Our family reunion'77# me == адрес электронной почты отправителя78# family = список адресов электронной почты всех получателей79msg['From'] = me80msg['To'] = COMMASPACE.join(family)81msg.preamble = 'Our family reunion'8283# Предположим, что все файлы изображений в формате PNG.84for file in pngfiles:85 # Открыть файлы в двоичном режиме. Пусть класс MIMEImage автоматически86 # определяет конкретный тип изображения.87 fp = open(file, 'rb')88 img = MIMEImage(fp.read())89 fp.close()90 msg.attach(img)9192# Отправляем email через собственный SMTP-сервер.93s = smtplib.SMTP('localhost')94s.sendmail(me, family, msg.as_string())95s.quit()96```9798Вот пример отправки всего содержимого каталога в виде email- сообщения: [1](https://python-all.ru/2.7/library/email-examples.html#id4)99100```python101#!/usr/bin/env python102103"""Отправляем содержимое каталога как MIME-сообщение."""104105import os106import sys107import smtplib108# Для определения типа MIME по расширению имени файла109import mimetypes110111from optparse import OptionParser112113from email import encoders114from email.message import Message115from email.mime.audio import MIMEAudio116from email.mime.base import MIMEBase117from email.mime.image import MIMEImage118from email.mime.multipart import MIMEMultipart119from email.mime.text import MIMEText120121COMMASPACE = ', '122123def main():124 parser = OptionParser(usage="""\125Send the contents of a directory as a MIME message.126127Usage: %prog [options]128129Unless the -o option is given, the email is sent by forwarding to your local130SMTP server, which then does the normal delivery process. Your local machine131must be running an SMTP server.132""")133 parser.add_option('-d', '--directory',134 type='string', action='store',135 help="""Mail the contents of the specified directory,136 otherwise use the current directory. Only the regular137 files in the directory are sent, and we don't recurse to138 subdirectories.""")139 parser.add_option('-o', '--output',140 type='string', action='store', metavar='FILE',141 help="""Print the composed message to FILE instead of142 sending the message to the SMTP server.""")143 parser.add_option('-s', '--sender',144 type='string', action='store', metavar='SENDER',145 help='The value of the From: header (required)')146 parser.add_option('-r', '--recipient',147 type='string', action='append', metavar='RECIPIENT',148 default=[], dest='recipients',149 help='A To: header value (at least one required)')150 opts, args = parser.parse_args()151 if not opts.sender or not opts.recipients:152 parser.print_help()153 sys.exit(1)154 directory = opts.directory155 if not directory:156 directory = '.'157 # Создать внешнее (оборачивающее) сообщение.158 outer = MIMEMultipart()159 outer['Subject'] = 'Contents of directory %s' % os.path.abspath(directory)160 outer['To'] = COMMASPACE.join(opts.recipients)161 outer['From'] = opts.sender162 outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'163164 for filename in os.listdir(directory):165 path = os.path.join(directory, filename)166 if not os.path.isfile(path):167 continue168 # Определяем тип содержимого по расширению файла. Кодировка169 # будет проигнорирована, хотя стоит проверять простые вещи, такие как170 # gzip-файлы или сжатые файлы.171 ctype, encoding = mimetypes.guess_type(path)172 if ctype is None or encoding is not None:173 # Не удалось определить тип, или файл закодирован (сжат), поэтому174 # используем общий тип 'набор битов'.175 ctype = 'application/octet-stream'176 maintype, subtype = ctype.split('/', 1)177 if maintype == 'text':178 fp = open(path)179 # Примечание: нужно обработать вычисление кодировки.180 msg = MIMEText(fp.read(), _subtype=subtype)181 fp.close()182 elif maintype == 'image':183 fp = open(path, 'rb')184 msg = MIMEImage(fp.read(), _subtype=subtype)185 fp.close()186 elif maintype == 'audio':187 fp = open(path, 'rb')188 msg = MIMEAudio(fp.read(), _subtype=subtype)189 fp.close()190 else:191 fp = open(path, 'rb')192 msg = MIMEBase(maintype, subtype)193 msg.set_payload(fp.read())194 fp.close()195 # Закодировать полезную нагрузку с помощью Base64.196 encoders.encode_base64(msg)197 # Установить параметр filename.198 msg.add_header('Content-Disposition', 'attachment', filename=filename)199 outer.attach(msg)200 # Теперь отправляем или сохраняем сообщение201 composed = outer.as_string()202 if opts.output:203 fp = open(opts.output, 'w')204 fp.write(composed)205 fp.close()206 else:207 s = smtplib.SMTP('localhost')208 s.sendmail(opts.sender, opts.recipients, composed)209 s.quit()210211if __name__ == '__main__':212 main()213```214215Вот пример распаковки MIME-сообщения вроде показанного выше в каталог с файлами:216217```python218#!/usr/bin/env python219220"""Распаковываем MIME-сообщение в каталог файлов."""221222import os223import sys224import email225import errno226import mimetypes227228from optparse import OptionParser229230def main():231 parser = OptionParser(usage="""\232Unpack a MIME message into a directory of files.233234Usage: %prog [options] msgfile235""")236 parser.add_option('-d', '--directory',237 type='string', action='store',238 help="""Unpack the MIME message into the named239 directory, which will be created if it doesn't already240 exist.""")241 opts, args = parser.parse_args()242 if not opts.directory:243 parser.print_help()244 sys.exit(1)245246 try:247 msgfile = args[0]248 except IndexError:249 parser.print_help()250 sys.exit(1)251252 try:253 os.mkdir(opts.directory)254 except OSError as e:255 # Игнорировать ошибку существования каталога256 if e.errno != errno.EEXIST:257 raise258259 fp = open(msgfile)260 msg = email.message_from_file(fp)261 fp.close()262263 counter = 1264 for part in msg.walk():265 # multipart/* – это просто контейнеры266 if part.get_content_maintype() == 'multipart':267 continue268 # Приложениям следует тщательно проверять имя файла, чтобы269 # email-сообщение не могло перезаписать важные файлы270 filename = part.get_filename()271 if not filename:272 ext = mimetypes.guess_extension(part.get_content_type())273 if not ext:274 # Использовать универсальное расширение для набора битов.275 ext = '.bin'276 filename = 'part-%03d%s' % (counter, ext)277 counter += 1278 fp = open(os.path.join(opts.directory, filename), 'wb')279 fp.write(part.get_payload(decode=True))280 fp.close()281282if __name__ == '__main__':283 main()284```285286Here’s an example of how to create an HTML message with an alternative plain text version: [2](https://python-all.ru/2.7/library/email-examples.html#id5)287288```python289#!/usr/bin/env python290291import smtplib292293from email.mime.multipart import MIMEMultipart294from email.mime.text import MIMEText295296# me == мой адрес электронной почты.297# you == адрес электронной почты получателя.298me = "my@email.com"299you = "your@email.com"300301# Создать контейнер сообщения – правильный тип MIME – multipart/alternative.302msg = MIMEMultipart('alternative')303msg['Subject'] = "Link"304msg['From'] = me305msg['To'] = you306307# Создать тело сообщения (версии в виде простого текста и HTML).308text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttps://www.python.org"309html = """\310<html>311 <head></head>312 <body>313 <p>Hi!<br>314 How are you?<br>315 Here is the <a href="https://www.python.org">link</a> you wanted.316 </p>317 </body>318</html>319"""320321# Записать MIME-типы обеих частей – text/plain и text/html.322part1 = MIMEText(text, 'plain')323part2 = MIMEText(html, 'html')324325# Прикрепить части к контейнеру сообщения.326# Согласно RFC 2046, последняя часть многокомпонентного сообщения, в данном случае327# HTML-сообщение, является наилучшим и предпочтительным.328msg.attach(part1)329msg.attach(part2)330331# Отправка сообщения через локальный SMTP-сервер.332s = smtplib.SMTP('localhost')333# Функция sendmail принимает 3 аргумента: адрес отправителя, адрес получателя334# и сообщение для отправки – здесь оно отправляется в виде одной строки.335s.sendmail(me, you, msg.as_string())336s.quit()337```338339Сноски340341**[1](https://python-all.ru/2.7/library/email-examples.html#id2)**342343Спасибо Matthew Dixon Cowles за оригинальную идею и примеры.344345**[2](https://python-all.ru/2.7/library/email-examples.html#id3)**346347Автор: Martin Matejek.348