[PY3]——发送邮件

时间:2023-03-09 13:24:44
[PY3]——发送邮件

一些概念

MUA:Mail User Agent——邮件用户代理,例如OutLook、Foxmail

MTA:Mail Transfer Agent——邮件传输代理,例如163.com、sina.com这些Email服务提供商

MDA:Mail Delivery Agent——邮件投递代理,邮件投递的最终目的地、就像一个存储有点的数据库一样

邮件收发过程

send@163.com -> MUA -> MTA -> MTA -> 若干个MTA -> MDA <- MUA <- receive@sina.com

1. 写邮件:通过MUA这样的软件完成,并由MUA负责发送

2. 传输过程:自己的电子邮件是@163.com,所以会首先被投递给网易提供的MTA,再由网易的MTA发送给新浪的MTA,中间可能还会经过别的MTA

3. 投递到最终目的地:最终新浪的MTA会把Email投递到MDA中,就相当于发送到了receive@sina.com这个电子邮箱中了,这封Email内容被放到了新浪的某个服务器(数据库)上

4. 收件人看到邮件内容:Email之所以不会直接到达对方的电脑,就因为对方电脑不一定开机,开机也不一定联网,那最终收件人提取邮件时,是通过MUA从MDA上获取的

协议

发邮件时:

  MUA通过SMTP协议将Email发送到MTA

        发邮件时需要先配置SMTP服务器,例如163提供的SMTP服务器地址:smtp.163.com

为了证明你是163.com用户,MTA需要验证SMTP服务器地址、邮箱地址、口令

收邮件时:

  MUA从MDA收邮件使用的协议有两种:POP3 / IMAP(IMAP不但能读取邮件还能直接操作MDA上存储的邮件)

为了防止你冒充他人收邮件,MDA需要验证POP3/IMAP服务器地址、邮箱地址、口令

发送普通文本邮件

from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr,formataddr
import smtplib mail_send='******@163.com'
mail_passwd='******' #这是授权口令密码,不是邮箱登录密码
mail_smtp='smtp.163.com'
main_to=['******@**.com','******@163.com'] def _format_addr(s):
name,addr=parseaddr(s)
return formataddr((Header(name,'utf-8').encode(),addr)) '''Python2应该这这么写
def _format_addr(s):
name,addr=parseaddr(s)
return formataddr(( Header(name, 'utf-8').encode(), addr.encode('utf-8') if isinstance(addr, unicode) else addr))
''' def send_mail(to_list,subject,content):
msg=MIMEText(content,'plain','utf-8')
msg['Subject']=Header(subject,'utf-8')
msg['From']=_format_addr("我是发件人 <{}>".format(mail_send)) # Python2: msg['From']=_format_addr('我是发件人 <%s>' % mail_send) #
msg['To']=",".join(to_list)
try:
server=smtplib.SMTP()
server.connect(mail_smtp)
server.login(mail_send,mail_passwd)
server.sendmail(mail_send,to_list,msg.as_string())
server.close()
except Exception:
print("Error") send_mail(main_to,"发送测试","邮件发送文本成功")

发送带附件的邮件

def send_mail_accessory(to_list,subject,content,filename):
msg=MIMEMultipart()
msg['Subject']=Header(subject,'utf-8')
msg['From']=_format_addr("我是发件人 <{}>".format(mail_send))
msg['To']=",".join(to_list)
msg.attach(MIMEText(content,'plain','utf-8')) with open(filename,mode='rb') as f:
mime=MIMEBase('excel','xlsx',filename=filename.split('/')[2])
mime.add_header('content-disposition','attachment', filename=filename.split('/')[2])
mime.add_header('Content-ID', '<0>')
mime.add_header('X-Attachment-Id', '')
mime.set_payload(f.read())
encoders.encode_base64(mime)
msg.attach(mime) server=smtplib.SMTP()
server.connect(mail_smtp)
server.login(mail_send,mail_passwd)
server.sendmail(mail_send,to_list,msg.as_string())
server.close() send_mail_accessory(mail_to,"发附件测试","给你发了一个文件","/py3/xxx.xlsx")