先展示smtp的最小系统代码,然后再解释一下代码
import smtplib from email.mime.text import MIMEText from email.header import Header sender = '发件人邮箱地址' smtpserver = '邮箱smtp服务器地址' # 例如smtp.gmail.com username = sender password = '密码' port = 587 receiver = '收件人邮箱地址' subject = '标题' msg = MIMEText( "正文", 'plain', 'utf-8' ) msg['Subject'] = Header( subject, 'utf-8' ) msg['From'] = sender msg['To'] = receiver smtp = smtplib.SMTP( smtpserver, port=port ) smtp.ehlo() smtp.starttls() smtp.login( username, password ) smtp.sendmail( sender, receiver, msg.as_string() )
smtp.quit() print("发送成功")
文中表红色的部分需要根据实际情况自行填写,smtp服务器地址和端口号一般可以在邮箱设置里面查看到,此外,需要在邮箱设置里面打开smtp服务,否则将无法使用
如果是谷歌邮箱,即gmail,则使用的是 tls,需要添加 橙色斜体的一行,否则会报错说无法验证,然后在发送邮件前,需要点击以下两个链接并同意
https://myaccount.google.com/lesssecureapps
https://accounts.google.com/b/0/DisplayUnlockCaptcha
在第一次运行程序之后,gmail会拦截你,并发一封邮件给你,表明需要确实是本人行为,点击确认后会显示之后会减少拦截,然后再次发送,一般都可以成功,若不成功,可以再打开上述两个链接查看是否同意
国外的邮箱还有微软的outlook,但是官网速度之慢,以及经常莫名其妙的拦截,笔者非常反感,所以在尝试后不再推荐,国内笔者使用的是阿里云邮箱,因此也尝试了一下,但是阿里云邮箱会主动拦截你发出的邮件,认为你是垃圾邮件,而不是交由对方邮箱判断,因此直接不考虑
之后尝试了网易163邮箱,目前版本需要在设置里开启smtp服务并发短信开启单独的应用密码,如果直接使用邮箱密码是无法通过验证的,在修改了smtp服务器地址和端口后(服务器上基本是不可能使用25普通端口的,本地测试可以,服务器不用考虑直接上ssl端口,有两个ssl端口的需要都试一下),需要替换一行内容为
smtp = smtplib.SMTP_SSL( smtpserver, port=port )
网易邮箱需要使用 ssl 非 tls ,虽然这两个本质上差不多,但是奈何对不上就是不给通过啊(摊手),同时不需要添加橙色斜体部分
至此,理论上国内国外都有smtp邮箱服务可以使用了,如果是其他邮箱,一般都可以尝试上面 tls / ssl 两种方案和邮箱的两个 ssl 端口组合,如果程序运行后卡住,基本可以认为是无法通过验证,因为发送邮件会出现大段的 log ,当然也可以搜索一下对应邮箱的smtp demo,不过很多都是不可行的(
下面附上笔者的实际代码格式
config.py
import Privacy class DevelopmentConfig(Config): sender = Privacy.EmailSenderWindows password = Privacy.EmailPasswordWindows smtpserver = Privacy.smtpServerWindows port = Privacy.smtpPortWindows class ProductionConfig(Config): sender = Privacy.EmailSenderCentOS password = Privacy.EmailPasswordCentOS smtpserver = Privacy.smtpServerCentOS port = Privacy.smtpPortCentOS config = { 'development': DevelopmentConfig, 'production': ProductionConfig, 'default': DevelopmentConfig }
ModuleEmail.py
import smtplib from email.mime.text import MIMEText from email.header import Header class EmailManager(object): def __init__(self, parm): self.sender = parm.sender self.smtpserver = parm.smtpserver self.port = parm.port self.password = parm.password def SendEmail(self, receiver, subject, context): try: msg = MIMEText(context, 'plain', 'utf-8') msg['Subject'] = Header(subject, 'utf-8') msg['From'] = self.sender msg['To'] = receiver smtp = smtplib.SMTP(self.smtpserver, port=self.port) smtp.set_debuglevel(1) smtp.ehlo() smtp.starttls() smtp.login(self.sender, self.password) smtp.sendmail(self.sender, receiver, msg.as_string()) smtp.quit() print("发送成功") return True except Exception as err: print("发送失败") print(err) return False
main.py
import platform if platform.system() == "Windows": myEmail = ModuleEmail.EmailManager(config["development"]) else: myEmail = ModuleEmail.EmailManager(config["production"]) myEmail.SendEmail(EmailAddress, EmailSubject, EmailContext)