Опубликован: 22.12.2005 | Доступ: свободный | Студентов: 16667 / 511 | Оценка: 4.18 / 3.71 | Длительность: 16:16:00
ISBN: 978-5-9556-0109-0
Лекция 9:

Сетевые приложения на Python

Модуль smtplib

Сообщения электронной почты в Интернете передаются от клиента к серверу и между серверами в основном по протоколу SMTP ( S imple M ail T ransfer P rotocol, простой протокол передачи почты). Протокол SMTP и ESMTP (расширенный вариант SMTP) описаны в RFC 821 и RFC 1869. Для работы с SMTP в стандартной библиотеке модулей имеется модуль smtplib. Для того чтобы начать SMTP-соединение с сервером электронной почты, необходимо в начале создать объект для управления SMTP-сессией с помощью конструктора класса SMTP:

smtplib.SMTP([host[, port]])

Параметры host и port задают адрес и порт SMTP-сервера, через который будет отправляться почта. По умолчанию, port=25. Если host задан, конструктор сам установит соединение, иначе придется отдельно вызывать метод connect(). Экземпляры класса SMTP имеют методы для всех распространенных команд SMTP-протокола, но для отправки почты достаточно вызова конструктора и методов sendmail() и quit():

# -*- coding: cp1251 -*-
from smtplib import SMTP
fromaddr = "student@mail.ru"     # От кого
toaddr = "rnd@onego.ru"          # Кому
message = """From: Student <%(fromaddr)s>
To: Lecturer <%(toaddr)s>
Subject: From Python course student
MIME-Version: 1.0
Content-Type: text/plain; charset=Windows-1251
Content-Transfer-Encoding: 8bit

Здравствуйте! Я изучаю курс по языку Python и 
отправляю письмо его автору.
"""
connect = SMTP('mail.onego.ru')
connect.set_debuglevel(1)
connect.sendmail(fromaddr, toaddr, message % vars())
connect.quit()

Следует заметить, что toaddr в сообщении (в поле To ) и при отправке могут не совпадать. Дело в том, что получатель и отправитель в ходе SMTP-сессии передается командами SMTP-протокола. При запуске указанного выше примера на экране появится отладочная информация (ведь уровень отладки задан равным 1):

send: 'ehlo rnd.onego.ru\r\n'
reply: '250-mail.onego.ru Hello as3-042.dialup.onego.ru [195.161.147.4], pleased to meet you\r\n'
send: 'mail FROM:<student@mail.ru> size=270\r\n'
reply: '250 2.1.0 <student@mail.ru>... Sender ok\r\n'
send: 'rcpt TO:<rnd@onego.ru>\r\n'
reply: '250 2.1.5 <rnd@onego.ru>... Recipient ok\r\n'
send: 'data\r\n'
reply: '354 Enter mail, end with "." on a line by itself\r\n'
send: 'From: Student <student@mail.ru>\r\n . . . '
reply: '250 2.0.0 iBPFgQ7q028433 Message accepted for delivery\r\n'
send: 'quit\r\n'
reply: '221 2.0.0 mail.onego.ru closing connection\r\n'

Из этой (несколько сокращенной) отладочной информации можно увидеть, что клиент отправляет (send) команды SMTP-серверу (EHLO, MAIL FROM, RCPT TO, DATA, QUIT), а тот выполняет команды и отвечает (reply), возвращая код возврата.

В ходе одной SMTP-сессии можно отправить сразу несколько писем подряд, если не вызывать quit().

В принципе, команды SMTP можно подавать и отдельно: для этого у объекта-соединения есть методы ( helo(), ehlo(), expn(), help(), mail(), rcpt(), vrfy(), send(), noop(), data() ), соответствующие одноименным командам SMTP-протокола.

Можно задать и произвольную команду SMTP-серверу с помощью метода docmd(). В следующем примере показан простейший сценарий, который могут использовать те, кто время от времени принимает почту на свой сервер по протоколу SMTP от почтового сервера, на котором хранится очередь сообщений для некоторого домена:

from smtplib import SMTP
connect = SMTP('mx.abcde.ru')
connect.set_debuglevel(1)
connect.docmd("ETRN rnd.abcde.ru")
connect.quit()

Этот простенький сценарий предлагает серверу mx.abcde.ru попытаться связаться с основным почтовым сервером домена rnd.abcde.ru и переслать всю накопившуюся для него почту.

При работе с классом smtplib.SMTP могут возбуждаться различные исключения. Назначение некоторых из них приведено ниже:

smtplib.SMTPException

Базовый класс для всех исключений модуля.

smtplib.SMTPServerDisconnected

Сервер неожиданно прервал связь (или связь с сервером не была установлена).

smtplib.SMTPResponseException

Базовый класс для всех исключений, которые имеют код ответа SMTP-сервера.

smtplib.SMTPSenderRefused

Отправитель отвергнут

smtplib.SMTPRecipientsRefused

Все получатели отвергнуты сервером.

smtplib.SMTPDataError

Сервер ответил неизвестным кодом на данные сообщения.

smtplib.SMTPConnectError

Ошибка установления соединения.

smtplib.SMTPHeloError

Сервер не ответил правильно на команду HELO или отверг ее.

Андрей Егоров
Андрей Егоров

def bin(n):

"""Цифры двоичного представления натурального числа """

if n == 0:

   return []

n, d = divmod(n, 2)

return bin(n) + [d]

print bin(69)

Что значит здесь return[] ? Возвращает список? Непонятно какой список? Откуда он? 

 

 

Асмик Гаряка
Асмик Гаряка

Почему при вычислении рейтинга не учитывается уровень, как описано? Для всех курсов У=1, хотя для Специалист должно быть 2.

Александр Воронцов
Александр Воронцов
Украина