通过smtplib发送邮件

797 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

基础操作

基础: smtp是发送邮件的协议,在python中有两个模块用来支持发送邮件,smtplib负责发送邮件,而email模块这是负责构造邮件。email可以构造纯文本文件,也可以HTML邮件和带附件的邮件。首先先从纯文本文件开始构造

from email.mime.text import MIMEText
msg = MIMEText('test python email','plain','utf-8')

导入email模块中的MIMEText类 然后构造email纯文本邮件 语法为

msg = MIMEText('要发送的文本内容','发送邮件类型','设置编码')

刚刚例子中,plain指的是纯文本,然后utf-8为邮件内容编码。使用utf-8可以保证编码的兼容性

邮件内容构造完成后,就是发送邮件,这一块是由smtplib模块负责

import smtplib
server = smtplib.SMTP(服务器地址,端口)
#可以打印出与smtp服务器的交互信息
server.set_debuglevel(1)
server.login(发件人email地址,smtp服务器授权码)
server.sendmail(发件人地址,收件人地址,构造的邮件)
server.quit

通过qq邮箱测试

接着可以使用QQ的smtp服务器来写一个发送邮件的程序

from email.mime.text import MIMEText
import smtplib
​
#构造邮件
email_information = input("邮件内容")
msg = MIMEText(email_information,'plain','utf-8')
​
#设置server和user,password
server = input("服务器:")
user = input("用户:")
password = input("授权码:")
​
#设置收发地址
send = input("发件人:")
receivers = list(input("收件人:"))
​
#发送邮件,注:QQ的smtp服务器端口为465
sm = smtplib.SMTP(server,465)
sm.set_debuglevel(1)
sm.login(user,password)
sm.sendmail(send,receivers,msg.as_string())
sm.quit()
​

发现一个尴尬的事实 我是用qq邮件测试的,就算我没写主题和发送人这些话,如果你是对方的好友也会自动显示,但如果是一个的邮箱服务器发送到另一个邮箱服务器就可以出现

一个完整的邮件,要有主题和发送人,收件人等信息,smtplib同样提供这样的功能,功能实现如下。

/usr/bin/env python
​
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr,formataddr
import smtplib
​
#格式化邮箱地址
def format_addr(s):
        name,addr = parseaddr(s)
        return formataddr((Header(name,'utf-8').encode(),addr))
​
'''
这个设置就不用多说了吧,和上次一样,都是用户,授权码,发送地址和接受地址。
'''
user = input('User:')
password = input('Password:')
send = input('Send:')
receivers = list(input('Receivers:'))
smtp_server = input('SMTP server:')
​
​
#构造邮件
msg = MIMEText('test python smtp','plain','utf-8')
#构造发件人的头部信息
msg['From'] = format_addr('python lover'%user)
#构造收件人的头部信息
msg['To']=format_addr('administrator<%s>'%receivers)
#构造邮件主题头部信息
msg['Subject'] = (Header('from smtp....','utf-8').encode())
​
#发送邮件
server = smtplib.SMTP(smtp_server,465)
server.set_debuglevel(1)
server.login(user,password)
server.sendmail(send,[receivers],msg.as_string())
server.quit

def format_addr(s)是照网上写的,作用是格式化邮件地址,没看懂parseaddr()formataddrformat_addrs函数接受到邮件地址后,使用parseaddr()方法将user和send的值,分为(name,addr)格式的元组,再将分解后的值分别赋予给name和addr两个变量,如果这个地址连接错误或者不存在,就相当于解析失败,这会返回("","")形式的一个元组信息。

formataddr()parseaddr()的方法相反,需要元组的信息,然后返回适合与smtp协议的ToCc的字符串值,所以使用这个对象的前提条件是,name和addr为元组,所以这个函数使用了parseaddr()方法,将user转换一下可以适用于formataddr()对象可以接受的值,再由formataddr()进行转换。

不能简单的传入一个name<addr@example.com>格式,因为如果包含中文,要使用Header对象。Header()对象可以进行编码,msg['To']接受的是字符串而不是list

['From']['To']['Subject']是标准邮件的三个头部信息。这是smtp协议中定义的格式。

发送格式部分与上次并无差别 这个程序的与上个程序的差别,基本就在于显示smtp标准协议中三个头部信息