Алла Тамбовцева, НИУ ВШЭ
Сегодня мы посмотрим, как можно рассылать электронные письма средствами Python.
Импортируем библиотеку smtplib
для доступа к gmail.com
и библиотеку email
для создания текста письма (а именно, функцию MIMEText
).
import smtplib
from email.mime.text import MIMEText
Укажем название хоста и порт для безопасного доступа к gmail.
host = 'smtp.gmail.com'
port = 465
Теперь можем ввести свои логин и пароль:
user = 'allatambov@gmail.com'
password = '1234' # your password here
При работе с ящиком gmail в связи с настройками безопасности можно столкнуться с проблемой: Gmail не позволит подключиться к ящику через Python, поскольку посчитает его сторонним подозрительным приложением. Чтобы избежать этого, давайте заранее изменим настройки безопасности (после работы в Python очень рекомендуется вернуть всё на место). Зайдем на почту, кликнем на фотографию, выберем Аккаунт Google, затем Безопасность, и включим доступ в разделе Ненадежные приложения, у которых есть доступ к аккаунту.
Теперь сообщим Python, с какого адреса и кому мы будем отправлять сообщение. Пока я отправлю письмо самой себе, но создам при этом список адресатов to
, который можно расширять:
from_user = user
to = ['allatambov@gmail.com']
Сохраним строку с текстом письма в text
, а затем превратим его в объект сообщение:
text = 'I did it!'
msg = MIMEText(text)
Посмотрим, что внутри:
print(msg)
Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit I did it!
Теперь добавим тему письма, укажем отправителя и получателя:
msg['Subject'] = 'Python'
msg['From'] = from_user
msg['To'] = ', '.join(to) # склеим всех адресатов в списке (подойдет для рассылки)
Снова посмотрим на сообщение:
print(msg)
Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Python From: allatambov@gmail.com To: allatambov@gmail.com I did it!
Письмо готово! Осталось его отправить. Подключимся к серверу, введём логин и пароль:
server = smtplib.SMTP_SSL(host, port)
server.login(user, password)
(235, b'2.7.0 Accepted')
Если вы получили ошибку SMTPAuthenticationError
, а адрес почты и пароль указаны верно, проверьте, что вы изменили настройки безопасности.
Отправляем письмо:
server.sendmail(from_user, to, msg.as_string())
{}
Если после исполнения кода был возвращён пустой словарь, то всё хорошо, письмо отправилось (проверьте почту).
Теперь давайте сделаем что-нибудь поинтереснее: прикрепим к письму приложение-картинку (ссылка).
Для этого нам понадобится функция MIMEMultipart()
для создания письма из нескольким частей и функция MIMEImage()
для добавления изображения.
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
Так как изображение будем брать с компьютера, импортируем ещё модуль os
(от operation system).
import os
Создадим сообщение из нескольких частей (типа Multipart
), добавим тему письма, отправителя и получателя:
msg2 = MIMEMultipart()
msg2['Subject'] = 'Hello from Python'
msg2['From'] = from_user
msg2['To'] = ', '.join(to)
Прикрепим текст письма:
text = "Python is missing you."
text_part = MIMEText(text)
msg2.attach(text_part)
Выберем изображение, которое мы хотим прикрепить и откроем его:
filepath = '/Users/allat/Desktop/python.png'
with open(filepath, 'rb') as f:
img = MIMEImage(f.read())
Прикрепим изображение к сообщению msg2
, предварительно добавив ему название (совпадает с названием файла, как обычно):
img.add_header('Content-Disposition',
'attachment',
filename=os.path.basename(filepath))
msg2.attach(img)
Осталось отправить письмо:
server.sendmail(from_user, to, msg2.as_string())
{}
Готово! Теперь посмотрим, как можно организовать рассылку на основе имён и адресов, сохранённых в таблице. И заодно закидаем питонами тех, кто не пришёл на пары :)
Импортируем библиотеку pandas
и функцию sleep
для добавления задержки по времени после каждого письма:
import pandas as pd
from time import sleep
Создадим датафрейм из вложенного списка:
students = [['Alla', 'allatambov@gmail.com'],
['Not alla', 'matstat.polit@gmail.com']]
df = pd.DataFrame(students)
df.columns = ['name', 'mail']
df
name | ||
---|---|---|
0 | Alla | allatambov@gmail.com |
1 | Not alla | matstat.polit@gmail.com |
Загрузим картинку (ту же, что и в первый раз):
filepath = '/Users/allat/Desktop/python.png'
with open(filepath, 'rb') as f:
img = MIMEImage(f.read())
img.add_header('Content-Disposition',
'attachment',
filename=os.path.basename(filepath))
Напишем цикл для пары имя-адрес в датафрейме df
и включим в него шаблон текста письма, в который будет подставляться имя адресата:
for name, mail in zip(df.name, df.mail):
text = f"""Dear {name}, \n
Why are you absent? Python is missing you. \n
We are learning to send emails from Python now, never mind. """
msg = MIMEMultipart()
text_part = MIMEText(text)
msg.attach(text_part)
msg['Subject'] = 'Hello from Python'
msg['From'] = from_user
msg['To'] = mail
msg.attach(img)
server.sendmail(from_user, mail, msg.as_string())
Done!