Как отправлять вложения с помощью SMTP?

Я хочу написать программу, которая отправляет электронную почту с помощью smtplib Python. Я просмотрел документ и RFC, но не смог найти ничего, связанного с вложениями. Таким образом, я уверен, что есть концепция более высокого уровня, которую я пропускаю. Может кто-нибудь подскажет мне, как приложения работают в SMTP?

6 Solutions collect form web for “Как отправлять вложения с помощью SMTP?”

Что вы хотите проверить, это модуль email . Он позволяет создавать MIME- совместимые сообщения, которые затем отправляются с помощью smtplib.

Ниже приведен пример сообщения с вложением в формате PDF, текст «тело» и отправка через Gmail.

 # Import smtplib for the actual sending function import smtplib # For guessing MIME type import mimetypes # Import the email modules we'll need import email import email.mime.application # Create a text/plain message msg = email.mime.Multipart.MIMEMultipart() msg['Subject'] = 'Greetings' msg['From'] = 'xyz@gmail.com' msg['To'] = 'abc@gmail.com' # The main body is just another attachment body = email.mime.Text.MIMEText("""Hello, how are you? I am fine. This is a rather nice letter, don't you think?""") msg.attach(body) # PDF attachment filename='simple-table.pdf' fp=open(filename,'rb') att = email.mime.application.MIMEApplication(fp.read(),_subtype="pdf") fp.close() att.add_header('Content-Disposition','attachment',filename=filename) msg.attach(att) # send via Gmail server # NOTE: my ISP, Centurylink, seems to be automatically rewriting # port 25 packets to be port 587 and it is trashing port 587 packets. # So, I use the default port 25, but I authenticate. s = smtplib.SMTP('smtp.gmail.com') s.starttls() s.login('xyz@gmail.com','xyzpassword') s.sendmail('xyz@gmail.com',['xyz@gmail.com'], msg.as_string()) s.quit() 

Вот пример, который я вырвал из рабочего приложения, которое мы сделали. Он создает HTML-письмо с вложением Excel.

  import smtplib,email,email.encoders,email.mime.text,email.mime.base smtpserver = 'localhost' to = ['email@somewhere.com'] fromAddr = 'automated@hi.com' subject = "my subject" # create html email html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ' html +='"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">' html +='<body style="font-size:12px;font-family:Verdana"><p>...</p>' html += "</body></html>" emailMsg = email.MIMEMultipart.MIMEMultipart('alternative') emailMsg['Subject'] = subject emailMsg['From'] = fromAddr emailMsg['To'] = ', '.join(to) emailMsg['Cc'] = ", ".join(cc) emailMsg.attach(email.mime.text.MIMEText(html,'html')) # now attach the file fileMsg = email.mime.base.MIMEBase('application','vnd.ms-excel') fileMsg.set_payload(file('exelFile.xls').read()) email.encoders.encode_base64(fileMsg) fileMsg.add_header('Content-Disposition','attachment;filename=anExcelFile.xls') emailMsg.attach(fileMsg) # send email server = smtplib.SMTP(smtpserver) server.sendmail(fromAddr,to,emailMsg.as_string()) server.quit() 

Ну, вложения не обрабатываются никакими специальными способами, они являются «просто» листьями дерева Message-object. Вы можете найти ответы на любые вопросы, касающиеся MESE-совместимых mesasges в этом разделе документации по электронному пакету python.

В общем, любое вложение (чтение: необработанные двоичные данные) может быть представлено с использованием base64 (или аналогичного) Content-Transfer-Encoding .

 # -*- coding: utf-8 -*- """ Mail sender """ from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText import smtplib import pystache import codecs import time import sys reload(sys) sys.setdefaultencoding('utf-8') HOST = 'smtp.exmail.qq.com' PORT = 587 USER = 'your@mail.com' PASS = 'yourpass' FROM = 'your@mail.com' SUBJECT = 'subject' HTML_NAME = 'tpl.html' CSV_NAME = 'list.txt' FAILED_LIST = [] def send(mail_receiver, mail_to): # text = mail_text html = render(mail_receiver) # msg = MIMEMultipart('alternative') msg = MIMEMultipart('mixed') msg['From'] = FROM msg['To'] = mail_to.encode() msg['Subject'] = SUBJECT.encode() # msg.attach(MIMEText(text, 'plain', 'utf-8')) msg.attach(MIMEText(html, 'html', 'utf-8')) try: _sender = smtplib.SMTP( HOST, PORT ) _sender.starttls() _sender.login(USER, PASS) _sender.sendmail(FROM, mail_to, msg.as_string()) _sender.quit() print "Success" except smtplib.SMTPException, e: print e FAILED_LIST.append(mail_receiver + ',' + mail_to) def render(name): _tpl = codecs.open( './html/' + HTML_NAME, 'r', 'utf-8' ) _html_string = _tpl.read() return pystache.render(_html_string, { 'receiver': name }) def main(): ls = open('./csv/' + CSV_NAME, 'r') mail_list = ls.read().split('\r') for _receiver in mail_list: _tmp = _receiver.split(',') print 'Mail: ' + _tmp[0] + ',' + _tmp[1] time.sleep(20) send(_tmp[0], _tmp[1]) print FAILED_LIST main() 

Вот как отправить электронные письма с вложенными файлами в zip-файле и закодированным объектом utf-8 subject + body.

Из-за отсутствия документации и образцов для этого конкретного случая было нелегко это понять.

Символы non-ascii в ответе должны быть закодированы, например, ISO-8859-1. Вероятно, существует функция, которая может это сделать.

Наконечник:
Отправьте себе электронное письмо, сохраните его и просмотрите контент, чтобы выяснить, как сделать то же самое в Python.

Вот код для Python 3:

 #!/usr/bin/env python3 # -*- coding: utf-8 -*- # vim:set ts=4 sw=4 et: from os.path import basename from smtplib import SMTP from email.mime.text import MIMEText from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart from email.header import Header from email.utils import parseaddr, formataddr from base64 import encodebytes def send_email(recipients=["somebody@somewhere.xyz"], subject="Test subject æøå", body="Test body æøå", zipfiles=[], server="smtp.somewhere.xyz", username="bob", password="password123", sender="Bob <bob@somewhere.xyz>", replyto="=?ISO-8859-1?Q?M=F8=F8=F8?= <bob@somewhere.xyz>"): #: bool """Sends an e-mail""" to = ",".join(recipients) charset = "utf-8" # Testing if body can be encoded with the charset try: body.encode(charset) except UnicodeEncodeError: print("Could not encode " + body + " as " + charset + ".") return False # Split real name (which is optional) and email address parts sender_name, sender_addr = parseaddr(sender) replyto_name, replyto_addr = parseaddr(replyto) sender_name = str(Header(sender_name, charset)) replyto_name = str(Header(replyto_name, charset)) # Create the message ('plain' stands for Content-Type: text/plain) try: msgtext = MIMEText(body.encode(charset), 'plain', charset) except TypeError: print("MIMEText fail") return False msg = MIMEMultipart() msg['From'] = formataddr((sender_name, sender_addr)) msg['To'] = to #formataddr((recipient_name, recipient_addr)) msg['Reply-to'] = formataddr((replyto_name, replyto_addr)) msg['Subject'] = Header(subject, charset) msg.attach(msgtext) for zipfile in zipfiles: part = MIMEBase('application', "zip") b = open(zipfile, "rb").read() # Convert from bytes to a base64-encoded ascii string bs = encodebytes(b).decode() # Add the ascii-string to the payload part.set_payload(bs) # Tell the e-mail client that we're using base 64 part.add_header('Content-Transfer-Encoding', 'base64') part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(zipfile)) msg.attach(part) s = SMTP() try: s.connect(server) except: print("Could not connect to smtp server: " + server) return False if username: s.login(username, password) print("Sending the e-mail") s.sendmail(sender, recipients, msg.as_string()) s.quit() return True def main(): send_email() if __name__ == "__main__": main() 
  • Новое для Python, ошибка SMTP GMail
  • отправлять почту с помощью python
  • Как отправить электронное письмо нескольким получателям, используя python smtplib?
  • Cron python скрипт не выполняется
  • Получать ответы от Gmail с помощью smtplib - Python
  • Outlook 2010 и электронная почта Python smtplib - информация в соответствующих полях
  • Настройка другого ответа на сообщение в Python email / smtplib
  • Отправка gmail с ошибкой python
  • Python - лучший язык программирования в мире.