Записочка по Python — отсылка письма через GMail

Пример отправки почты с помощью Python 3. А еще точней для Python 3.1.3.
Дело в том что в версии 3.1.1. закрался баг с перекодировкой в base64 (email.encoders.encode_base64).
Можно было бы конечно поставить патч, но я просто скачал новую версию)
С удивлением обнаружил что в питоне отсылка почты реализована довольно «многословно». В том же php это вообще одна строка. Тут же надо разобраться чуть ли не со структурой электронного письма что бы понять почему так а не иначе. В общем муторно, но интересно 🙂

Так же по теме можно почитать следующее:

А теперь сам пример:

# -*- coding: utf-8 -*-

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.audio import MIMEAudio
from email.header import Header
from base64 import encodebytes
import email
import mimetypes
import os

mail_from   = 'mail_send@gmail.com'	# отправитель
mail_to     = 'mail_to@gmail.com'	# получатель
mail_text   = 'Тестовое письмо!nПослано из python' # текст письма
mail_subj   = 'Тестовое письмо' # заголовок письма
mail_coding = 'windows-1251'
attach_file = 'C:test.txt' # прикрепляемый файл

# Параметры SMTP-сервера
smtp_server = "smtp.gmail.com"
smtp_port   = 587
smtp_user   = "mail_send@gmail.com" # пользователь smtp
smtp_pwd    = "pwt_gmail"              # пароль smtp

# формирование сообщения
multi_msg = MIMEMultipart()
multi_msg['From'] = Header(mail_from, mail_coding)
multi_msg['To'] = Header(mail_to, mail_coding)
multi_msg['Subject'] =  Header(mail_subj, mail_coding)

msg = MIMEText(mail_text.encode('cp1251'), 'plain', mail_coding)
msg.set_charset(mail_coding)
multi_msg.attach(msg)

# присоединяем атач-файл
if(os.path.exists(attach_file) and os.path.isfile(attach_file)):
    file = open(attach_file, 'rb')
    attachment = MIMEBase('application', "octet-stream")
    attachment.set_payload(file.read())
    email.encoders.encode_base64(attachment)
    file.close()
    only_name_attach = Header(os.path.basename(attach_file),mail_coding);
    attachment.add_header('Content-Disposition','attachment; filename="%s"' % only_name_attach)
    multi_msg.attach(attachment)
else:
    if(attach_file.lstrip() != ""):
        print("Файл для атача не найден - " + attach_file)

# отправка
smtp = smtplib.SMTP(smtp_server, smtp_port)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login(smtp_user, smtp_pwd)
smtp.sendmail(mail_from, mail_to, multi_msg.as_string())
smtp.quit()

Еще один пример. Не мой, а автора не известен. Взято от сих.

# Отправка писем с помощью Python.
# Базовой кодировкой на моем сервере является UTF-8, отправлять письма мы будем в cp-1251, если есть необходимость использовать другие кодировки, замените в коде на свои.
# Первым делом подкючаем нужные функции:

from email.MIMEText import MIMEText # Модуль простого текстового сообщения
from email.Utils import formatdate # Функция кодирования даты для заголовка письма
from email.Header import make_header as mkh # Функция кодирования заголовков для письма
from email.MIMEMultipart import MIMEMultipart # Модуль формирования сообщений из нескольких частей
from email.MIMEBase import MIMEBase # Модуль создания частей письма
from email.Encoders import encode_base64 # Модуль для кодирования присоединенных файлов
from email.MIMEImage import MIMEImage # Модуль для вставки картинок в письмо
from email.Utils import make_msgid as msgid # Генерация Message_ID
import sys, smtplib, os, time

# Параметры

subj = 'Тема письма'
org = 'Моя фирма ' # фирма
mailer = 'Генератор писем' # название нашего почтового модуля
sender_name = 'Иван Иванов' # имя отправителя
sender_email = 'from@me.ru' # электропочта отправителя
recipient_name = 'Петр Петров' # имя получателя
recipient_email = 'to@you.ru' # электропочта получателя

# письмо в html
message_text = """
<strong>Письмо с html-тегами</strong>

Позже покажу, как включать изображения в тело письма.
"""
file_name = 'file.zip' # файл вложения
fromdir = '/tmp' + os.sep + filename # адрес файла

# формируем письмо
msg = MIMEMultipart('related')
msg['Subject'] = mkh([(subj, 'UTF-8')])
msg['Date'] = formatdate(localtime=True)
msg['Organization'] = mkh([(org,'UTF-8')])
msg['X-Mailer'] = mkh([(mailer,'UTF-8')])
msg['Message-ID'] = msgid()
msg['From'] = mkh([(sender_name,'UTF-8'),('','us-ascii')])
msg['To'] = mkh([(recipient_name, 'UTF-8'),('','us-ascii')])

# То, чего будет не видно, если почтовая программа поддерживает MIME
msg.preamble = "This is a multi-part message in MIME format."
msg.epilogue = "End of message"

# Текстовая часть сообщения
#---------------------------------------------------------------------------------------------------
msgAlternative = MIMEMultipart('alternative')
msg.attach(msgAlternative)
msgText = MIMEText('Отправка писем с помощью Python',"","UTF-8")
msgAlternative.attach(msgText)

# присоединяем HTML
#----------------------------------------------------------------------------------------------------
to_attach = MIMEText(message_text,"html","UTF-8")
msgAlternative.attach(to_attach)

# Прикладывается файл
#---------------------------------------------------------------------------------------------------------------

fp = open(fromdir, "rb")
to_attach = MIMEBase("application", "octet-stream")
to_attach.set_payload(fp.read())
encode_base64(to_attach)

to_attach.add_header("Content-Disposition", "attachment", filename=file_name)
fp.close()
msg.attach(to_attach)

# Отправка
#---------------------------------------------------------------------------------------------------------------
s = smtplib.SMTP('localhost')
s.set_debuglevel(1) # лог SMTP
try:
s.sendmail(recipient_email, sender_email, msg.as_string()) # отправка
except (smtplib.SMTPRecipientsRefused,
smtplib.SMTPSenderRefused), ErrorMsg:
sys.stderr.write("Проблема с отправкой письма. Причина: %s" % ErrorMsg)

Записочка по Python — отсылка письма через GMail: 8 комментариев

  1. zxmd

    Собственно процесс отправки писем через gmail ни разу не отличается от отправки писем через любой другой smtp, или я что то упускаю ? В PHP то особо с командой mail не разбежишься, чуть в сторону и берешь в руки обычный SMTP и… тоже самое.

    Если хотите удобный функционал для писем то копните в сторону http://docs.djangoproject.com/en/dev/topics/email/

  2. BorisMor

    «Собственно процесс отправки писем через gmail ни разу не отличается от отправки писем через любой другой smtp»

    Совершенно правы) Порт, сервер, юзера, и пароль поменять и будет работать.
    Назвал «на автомате» запись

    «Если хотите удобный функционал для писем то копните в сторону»

    Да вообще надо за Django взятся вплотную.

  3. Константин

    Огромное спасибо. Помогло, а то я 2 часа пытался русские буковки в письме отобразить.

  4. олег

    C:\Users\олег>C:\Users\олег\Desktop\питон\email.py
    File «C:\Users\олег\Desktop\питон\email.py», line 18
    attach_file = ‘C:\Users\олег\svarka.txt’ # прикрепляемый файл
    ^
    SyntaxError: (unicode error) ‘unicodeescape’ codec can’t decode bytes in position 2
    -3: truncated \UXXXXXXXX escape

    C:\Users\олег>

  5. Александр

    Спасибо за статью, очень помогла !

    PS Для отправки писем через сторонние SMTP сервера,
    В блоке отправки изменить:
    smtp = smtplib.SMTP(smtp_server,smtp_port)
    на
    smtp = smtplib.SMTP_SSL(smtp_server,smtp_port)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *