1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > python利用STMP发送gmail QQ邮件错误及笔记总结

python利用STMP发送gmail QQ邮件错误及笔记总结

时间:2024-06-23 19:19:48

相关推荐

python利用STMP发送gmail QQ邮件错误及笔记总结

引言

本篇博文是一个我之前没有想要去关注,但就是这样看似轻松的事情,却出现了很多的bug,我尝试用了163,、QQ以及谷歌邮箱去发送邮件,中间遇到了很多波折,其中一根谷歌的小号邮箱也被封了,所以想在这里总结下我的一些错误与笔记。

STMP协议介绍

对于Python来说,需要编写脚本调用邮件服务器来发送邮件,使用的协议是SMTP。接收邮件,使用的协议是POP3和IMAP。这三种的区别与用处后面再提,其实在上述三种邮箱的使用中,差别并不是很大,比如说QQ邮箱的STMP / IMAP是共用一个授权码,而谷歌邮箱则是按照端口划分。

在python中,提供收发邮件的库为smtplib、poplib和imaplib,而我们常用的为smtplib,下面为stmplib的一些常规方法介绍:

以上表格转自/lizhenliang/1875330,那么我们就可以写一个范例如下:

#!/usr/bin/python# -*- coding: UTF-8 -*-import smtplibfrom email.mime.text import MIMETextfrom email.utils import formataddrmy_sender='1004995307@' # 发件人邮箱账号my_pass = 'xxxxxxxxxx' # 发件人邮箱密码my_user='1004995307@'# 收件人邮箱账号,我这边发送给自己def mail():ret=Truetry:msg=MIMEText('successful!','plain','utf-8')msg['From']=formataddr(["FromRunoob",my_sender]) # 括号里的对应发件人邮箱昵称、发件人邮箱账号msg['To']=formataddr(["FK",my_user]) # 括号里的对应收件人邮箱昵称、收件人邮箱账号msg['Subject']="放假通知"# 邮件的主题,也可以说是标题server=smtplib.SMTP_SSL("", 465) # 发件人邮箱中的SMTP服务器,端口是25server.login(my_sender, my_pass) # 括号中对应的是发件人邮箱账号、邮箱密码server.sendmail(my_sender,[my_user,],msg.as_string()) # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件server.quit() # 关闭连接except Exception: # 如果 try 中的语句没有执行,则会执行下面的 ret=Falseret=Falsereturn retret=mail()if ret:print("邮件发送成功")else:print("邮件发送失败")

将其保存为py文件,然后运行就能去邮箱内查看到当前邮件了,但自己发给自己并不能说明是遵循STMP协议才发送或收到,所以我们需要将其放入一个固定任务中,将收件人当成我们要传的参数,然后检测是否能收到邮件才算是验证成功,这里的这种定时任务,可以简单的使用django和celery达到想要的效果,并且django中也有提供内置的mail模块,但没有stmplib好用,感觉bug有点多省略很多东西,所以还是以stmplib来构造函数:

# settings.py文件中:EMAIL_USE_TLS = FalseEMAIL_USE_SSL = FalseEMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'EMAIL_HOST = ''#MAIL_USE_DEBUG = True#MAIL_USE_TLS = True# EMAIL_HOST = ''EMAIL_PORT = 25# 发送邮件的邮箱EMAIL_HOST_USER = 'a1004995307@'# 在邮箱中设置的客户端授权密码EMAIL_HOST_PASSWORD = 'xxxx'# 收件人看到的发件人# EMAIL_FROM = 'postmaster@'EMAIL_FROM = 'xxx<a1004995307@>'

然后创建一个celery的模块包,里面的task.py文件写下发邮件的脚本:

#from django.core.mail import send_mailfrom celery.main import appfrom django.conf import settingsimport randomimport smtplibfrom email.mime.text import MIMETextfrom email.header import Header@app.task(name='send_verify_mail', bing=True)def send_verify_mail(to_email, code):sender = settings.EMAIL_HOST_USERreceiver = [to_email]subject = '放假通知'username = settings.EMAIL_HOST_USERpassword = settings.EMAIL_HOST_PASSWORDmsg = MIMEText('hello code %s' % code,_charset='utf-8') #中文需参数‘utf-8',单字节字符不需要msg['Subject'] = Header(subject, 'utf-8')msg['From'] = settings.EMAIL_FROMmsg['To'] = to_emailsmtp = smtplib.SMTP_SSL()smtp.connect(settings.EMAIL_HOST)smtp.login(username, password)smtp.sendmail(sender, receiver, msg.as_string())smtp.quit()

然后后面如果要发送邮件,只要调用这个函数,并启动celery就行了,但这里就出现了非常多的坑是各种邮箱完全不相同的验证,另外还有相关的HOST和PORT,这里将关于POP3/STMP/IMAP三种对应端口的情况列成一张表格为:

表中列举到的,除了谷歌邮箱,其它都是用的国内的邮箱账号,我们主要是看STMP协议这一项,如果不做设置,可能会出现如下的情况:

这里就需要我们去开启自己邮箱里的相关设置,这里我详细说的是QQ和谷歌,因为这两个也是我试验得最久的两个了。

QQ邮箱设置

进入邮箱,点击设置-账户

在账户栏目下,往下拉,找到POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务所在位置

然后将上述两个服务开启,一般会提示要验证绑定邮箱的一些东西,比如说向某个号码发短信,或者是密保令牌获取验证码,完成这其中的一步操作后才能看到QQ邮箱为每个账号设置的QQ授权码,然后如果是作为发信息,那么有用的为第二个,那么代码中可以修改为:

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'EMAIL_HOST = ''MAIL_USE_DEBUG = TrueMAIL_USE_TLS = True# EMAIL_HOST = ''EMAIL_PORT = 465# 发送邮件的邮箱EMAIL_HOST_USER = '1004995307@'# 在邮箱中设置的客户端授权密码EMAIL_HOST_PASSWORD = 'xxx'# 收件人看到的发件人EMAIL_FROM = 'Tim<1004995307@>'

一般如果照上面这么写基本上是没啥问题的,可能Email_port改成25也能发送邮件,那表示是未加密的网关,可能就会自动判别为垃圾邮件了,如果是465的话更保险些。QQ邮箱还是没有啥太大的坑,最多全部都是退信,但Gmail的套路就可能是一环接一环了。

谷歌邮箱设置

上述国内邮箱的设置还能用Foxmail软件直接设置,QQ邮箱中就有一个很详细的说明:Foxmail常用邮件客户端软件设置

gmail邮箱是没有授权码的,应该说国外的邮箱好像很少要授权码,都是直接拿密码当成授权码用,但这个里面的坑就多了。

其实我写这篇文章的原因也是我在gmail邮箱上试了很长一段时间,原因是这个坑有点深,也可能我的搜索方式不对。当我直接用密码房授权码时,发送邮件的时候会报错为:

b"5.7.8 username or password not accept,那么也能说明这个密码是无效的。在此之前,还遇到的bug是newwork is unreachable,即是网络达不到要求,那个是因为之前用的阿里云国内服务器,然后用的25网关,但找了半天,发现好像不适用,阿里云的STMP服务地址为:

所以在这里提一下,因为当时我是拿我自己服务器测试,发现谷歌连接不上了。但项目是在国外服务器上,所以我直接在国外服务器上把邮箱替换成谷歌邮箱,然后回到这个错误:b"5.7.8 username or password not accept

然后翻遍了Stack Overflow还有一些国外怎么设置谷歌邮箱的帖子,发现了三步:

将【安全性较低的应用程式存储权限】设为【启用】

我们可以进入/lesssecureapps界面将设置开起来,最好是用gmail浏览器已经进行过登录,那么就能跳过一些繁琐的登录。

开启后,重新以STMP协议发送邮件,然后这个时候可能就会报错为:b"5.7.7,图没有截了,大致意思应该说是验证密码错误,也就是说开了这个后不能登录上去,如果没用,那么就下一步。

解除人机验证锁定

进入/b/0/DisplayUnlockCaptcha 页面中,Google 可能會在您透過新的裝置或應用程式登入時,要求您完成這項額外步驟。如要授權存取,請按下方的 [繼續] 按鈕。然后我们就进入到了授权码的选择界面,

一路选是就OK了,之后可以再次尝试,如果还是不成功,这里报啥错忘了,如果还是不成功,那么就最后一步。

开启两步验证

第三步也是最后一步,如果还是不行,那只能采用这种冒险的方式,为啥说冒险呢,如果真的要做这步,就很有可能被封号几天,我当时是啥也不懂,看到有人这样搞,然后我也去搞了一波,但结果就不太好了。

这一步需要我们进入网址:/signinoptions/two-step-verification/enroll-welcome?utm_source=google-account&utm_medium=web,然后手动去获取一个授权码,并将密码设置为授权码的方式。

中间过程我就不再说了,当时配置的时候没有截图,这里默认有五种可以选,有windows、mac、Android、iPhone还有其它,这里选择其它直接确定,就能拿到授权码,然后把密码改完后感觉挺好的,但第二天就被封号了,可能我一次申请的有点多,也可能是其它各种原因,所以奉劝看到这里的朋友,别轻易尝试这种,如果上述两步没用,那么就可以考虑换邮箱了,下面是我的惨痛教训:

然后是申请复查,天地良心,我还没开始搞啥破坏呢。。。

中间还有b"5.7.14b"5.7.4b"5.7.7,我记得其中分别是认证密码错误,stmp连接错误等,如果走完上面两步还出现这类问题,第一是看拼写有没有问题,如果和我上面写的QQ格式基本一致,端口是587或者465没用,那可以尝试重新走一遍上述步骤,可能中间哪里没有开起来,或者按第三步来,但我实验是被封了两天。

总结

后来还尝试了雅虎还有网易企业邮箱,我都不知道我为什么要试这么多种邮箱,因为最近一个项目是海外项目,老板搞了各种邮箱,但一直想换,那没办法咯,我就只能陪着他换。企业邮箱的话就是要做域名解析,如果是阿里云服务器的话,这里就不再说了,直接后台改就完事了。感觉这篇文章算一个科普性质的,科普我从错误里的经验,还有就是邮箱咋设置,我感觉现在啥邮箱都能搞一搞了。。。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。