发送邮件
smtplib模块主要负责发送邮件:是一个发送邮件的动作,连接邮箱服务器,登录邮箱,发送邮件(有发件人,收信人,邮件内容)。
email模块主要负责构造邮件:指的是邮箱页面显示的一些构造,如发件人,收件人,主题,正文,附件等。
1.smtplib模块
import smtplib smtp = smtplib.SMTP(server,port=25)
# smtp = smtplib.SMTP_SSL('smtp.qq.com',port=465) # SSL
smtp.login(username, password) # possword使用授权码
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()
sendmail(from_addr,to_addrs,msg,...):
from_addr:邮件发送者地址
to_addrs:邮件接收者地址。字符串列表['接收地址1','接收地址2','接收地址3',...]或'接收地址'
msg:发送消息:邮件内容。一般是msg.as_string():as_string()是将msg(MIMEText对象或者MIMEMultipart对象)变为str。
2.email模块
email模块下有mime包,mime英文全称为“Multipurpose Internet Mail Extensions”,即多用途互联网邮件扩展,是目前互联网电子邮件普遍遵循的邮件技术规范。
该mime包下常用的有三个模块:text,image,multpart。
from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage
构造一个邮件对象就是一个Message
对象,如果构造一个MIMEText
对象,就表示一个文本邮件对象,如果构造一个MIMEImage
对象,就表示一个作为附件的图片,要把多个对象组合起来,就用MIMEMultipart
对象,而MIMEBase
可以表示任何对象。它们的继承关系如下:
Message
+- MIMEBase
+- MIMEMultipart
+- MIMENonMultipart
+- MIMEMessage
+- MIMEText
+- MIMEImage
2.1 text说明
邮件发送程序为了防止有些邮件阅读软件不能显示处理HTML格式的数据,通常都会用两类型分别为"text/plain"和"text/html"
构造MIMEText对象时,第一个参数是邮件正文,第二个参数是MIME的subtype,最后一定要用utf-8编码保证多语言兼容性。
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.baidu.com" text_plain = MIMEText(text,'plain', 'utf-8')
2.1.2添加超文本
html = """ <html> <body> <p> Here is the <a href="http://www.baidu.com">link</a> you wanted. </p> </body> </html> """ text_html = MIMEText(html,'html', 'utf-8')
2.1.3添加附件
sendfile=open(r'D:\pythontest\1111.txt','rb').read() text_att = MIMEText(sendfile, 'base64', 'utf-8') text_att["Content-Type"] = 'application/octet-stream' text_att["Content-Disposition"] = 'attachment; filename="XXX.txt"'
2.2 image说明
添加图片:
sendimagefile=open(r'D:\xxxx.png','rb').read() image = MIMEImage(sendimagefile) image.add_header('Content-ID','<image1>')
2.3 multpart说明
常见的multipart类型有三种:multipart/alternative, multipart/related和multipart/mixed。
邮件类型为"multipart/alternative"的邮件包括纯文本正文(text/plain)和超文本正文(text/html)。
邮件类型为"multipart/related"的邮件正文中包括图片,声音等内嵌资源。
邮件类型为"multipart/mixed"的邮件包含附件。向上兼容,如果一个邮件有纯文本正文,超文本正文,内嵌资源,附件,则选择mixed类型。
msg = MIMEMultipart('mixed')
我们必须把Subject,From,To,Date添加到MIMEText对象或者MIMEMultipart对象中,邮件中才会显示主题,发件人,收件人,时间(若无时间,就默认一般为当前时间,该值一般不设置)。
msg = MIMEMultipart('mixed') msg['Subject'] = 'Python email test' msg['From'] = 'XXX@163.com <XXX@163.com>' msg['To'] = 'XXX@126.com' msg['Date']='2018-3-16'
msg.add_header(_name,_value,**_params):添加邮件头字段。
msg.as_string():是将msg(MIMEText对象或者MIMEMultipart对象)变为str,如果只有一个html超文本正文或者plain普通文本正文的话,一般msg的类型可以是MIMEText;如果是多个的话,就都添加到MIMEMultipart,msg类型就变为MIMEMultipart。
msg.attach(MIMEText对象或MIMEImage对象):将MIMEText对象或MIMEImage对象添加到MIMEMultipart对象中。MIMEMultipart对象代表邮件本身,MIMEText对象或MIMEImage对象代表邮件正文。
以上的构造的文本,超文本,附件,图片都何以添加到MIMEMultipart('mixed')中:
msg.attach(text_plain) msg.attach(text_html) msg.attach(text_att) msg.attach(image)
3.文字,html,图片,附件实现实例
#!/usr/bin/env python # -*- coding: utf-8 -*- import smtplib from email.header import Header from email.mime.text import MIMEText from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart mail_server = 'smtp.qq.com' port = 465 sender = 'xxxx@qq.com' password = 'cplqgrjuchlkbfdf' # 授权码 receiver = 'xxxx@qq.com' # 收件人为多个收件人 # receiver=['XXX@qq.com','XXX@qq.com'] subject = '这是一封测试邮件' # 通过Header对象编码的文本,包含utf-8编码信息和Base64编码信息。以下中文名测试ok # subject = '中文标题' # subject=Header(subject, 'utf-8').encode() msg = MIMEMultipart('mixed') msg['Subject'] = subject msg['From'] = sender msg['To'] = 'XXX@126.com' # 收件人为多个收件人,通过join将列表转换为以;为间隔的字符串 # msg['To'] = ";".join(receiver) # msg['Date']='2018-9-10' # 构造文字内容 text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.baidu.com" text_plain = MIMEText(text, 'plain', 'utf-8') # 构造图片链接 sendimagefile = open(r'C:\Users\Family\Desktop\89ff2281551f170896429b0b470b4aac.png', 'rb').read() image = MIMEImage(sendimagefile) image.add_header('Content-ID', '<image1>') image["Content-Disposition"] = 'attachment; filename="testimage.png"' # 构造html html = """ <html> <head></head> <body> <p>Hi!<br> How are you?<br> Here is the <a href="http://www.baidu.com">link</a> you wanted.<br> </p> </body> </html> """ text_html = MIMEText(html, 'html', 'utf-8') text_html["Content-Disposition"] = 'attachment; filename="texthtml.html"' # 构造附件 sendfile = open(r'C:\Users\Family\Desktop\89ff2281551f170896429b0b470b4aac.png', 'rb').read() text_att = MIMEText(sendfile, 'base64', 'utf-8') text_att["Content-Type"] = 'application/octet-stream' # 以下附件可以重命名成 GJ.png # text_att["Content-Disposition"] = 'attachment; filename="GJ.png "' text_att.add_header('Content-Disposition', 'attachment', filename='GJ.png') msg.attach(text_plain) msg.attach(image) msg.attach(text_html) msg.attach(text_att) smtp = smtplib.SMTP_SSL(mail_server, port=port) # ssl
# smtp = smtplib.SMTP(mail_server, port=port)
smtp.login(sender, password) smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()
QQ的邮件服务器配置
接收邮件服务器:pop.qq.com 端口:995 使用SSL
发送邮件服务器:stmp.qq.com 端口:465或587 使用SSL
发送纯文本
import smtplib from email.mime.text import MIMEText mail_server = 'smtp.qq.com' port = 465 sender = xxxx@qq.com' password = 'cplqgrjuchlkbfdf' # 授权码 receiver = 'xxxx@qq.com' mail = MIMEText('这是发用的邮件内容') # 邮件内容 mail['Subject'] = '这是邮件主题' mail['From'] = sender # 发件人 mail['To'] = receiver # 收件人 smtp = smtplib.SMTP_SSL(mail_server, port=port) smtp.login(sender, password) smtp.sendmail(sender, receiver, mail.as_string()) smtp.quit()
#!/usr/bin/env python # -*- coding: utf-8 -*- import os import base64 import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart class SendMail: def __init__(self, sender, password, receiver, title, content, file=None, ssl=False, mail_server='smtp.qq.com', port=25, ssl_port=465): self.sender = sender # 用户名 self.password = password # 密码 self.receiver = receiver # 收件人,多个要传list ['a@qq.com','b@qq.com] self.title = title # 邮件标题 self.content = content # 邮件正文 self.file = file # 附件路径,如果不在当前目录下,要写绝对路径 self.email_host = mail_server # smtp服务器地址 self.port = port # 普通端口 self.ssl = ssl # 是否安全链接 self.ssl_port = ssl_port # 安全链接端口 def send_mail(self): msg = MIMEMultipart('mixed') # 默认为mixed # 处理附件 if self.file: try: send_file = open(self.file, 'rb').read() except Exception as e: raise Exception('打开附件出错') else: text_att = MIMEText(send_file, 'base64', 'utf-8') text_att["Content-Type"] = 'application/octet-stream' file_name = os.path.split(self.file)[-1] # 取文件名 # 这里是处理文件名为中文名的,必须这么写 new_file_name = '=?utf-8?b?' + base64.b64encode(file_name.encode()).decode() + '?=' text_att["Content-Disposition"] = 'attachment; filename="{}"'.format(new_file_name) msg.attach(text_att) text_plain = MIMEText(self.content, 'plain', 'utf-8') # 邮件正文 msg.attach(text_plain) msg['Subject'] = self.title # 邮件主题 msg['From'] = self.sender # 发送者账号 msg['To'] = ','.join(self.receiver) # 接收者账号列表 if self.ssl: self.smtp = smtplib.SMTP_SSL(self.email_host, port=self.ssl_port) else: self.smtp = smtplib.SMTP(self.email_host, port=self.port) self.smtp.login(self.sender, self.password) try: self.smtp.sendmail(self.sender, self.receiver, msg.as_string()) self.smtp.quit() print('发送成功') except Exception as e: print('error:', e) if __name__ == '__main__': sender = 'xxxxx@qq.com' password = 'cplqgrjuchlkbfdf' # 授权码 receiver = ['xxxxxxxx@qq.com', ] title = '测试' content = '测试发送邮件' file = r'C:\Users\Family\Desktop\89ff2281551f170896429b0b470b4aac.png' ssl = True m = SendMail(sender=sender, password=password, receiver=receiver, title=title, content=content, file=file, ssl=ssl, ) m.send_mail()