smtplib

python发送邮件失败时的解决思路

2020-10-26  本文已影响0人  SyKay

背景

之前在某银行分行进行RPA项目开发,使用到了一个发邮件的功能。

因为客户的机子上自带有outlook软件,使用设计器组件可以直接进行调用,于是发邮件模块就使用了outlook组件进行实现。

但是实际在使用了一段时间该组件后,发现outlook软件经常罢工,于是决定弃用该组件,该用代码来实现发邮件功能。


邮箱代码

代码如下(代码在廖雪峰老师网站上找的):

from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
import smtplib

'''
    带附件的邮件可以看做包含若干部分的邮件:文本和各个附件本身,
    所以,可以构造一个MIMEMultipart对象代表邮件本身,
    然后往里面加上一个MIMEText作为邮件正文,
    再继续往里面加上表示附件的MIMEBase对象即可:
'''


def _format_addr(s):
    # 格式化一个邮件地址,注意不能简单地传入name <addr@example.com>,因为如果包含中文,需要通过Header对象进行编码。
    name, addr = parseaddr(s)
    return formataddr((Header(name, 'utf-8').encode(), addr))


from_addr = "user@xx.com"  # 发件地址
password = "password"  # 密码
to_addr = "receiver@xx.com"  # 输入收件人地址,接收的是字符串而不是list,如果有多个邮件地址,用,分隔即可。 
smtp_server = "domain.com" # 设置邮箱服务器

msg = MIMEMultipart()  # 邮件对象:
msg['From'] = _format_addr("Python爱好者<%s>" % from_addr)
msg['To'] = _format_addr("管理员<%s>" % to_addr)
msg['Subject'] = Header('来着SMTP的问候', 'utf-8').encode()

# 邮件正文是MIMEText:
msg.attach(MIMEText('Hello, send by Python..', 'plain', 'utf-8'))

# 连接服务器、登录、发送邮件
server = smtplib.SMTP(smtp_server, 25)
server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()


常规解决问题思路

  1. 猜测是不是客户的邮箱服务器有开启了SSL安全协议,以上我将连接服务器的代码做了以下修改
    server = smtplib.SMTP_SSL(smtp_server, 465)
    再进行调试后:控制台又提示了以下错误
    [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1108)
    也是登录不上去,但是看这日志基本上也可以排除掉SSL协议问题了
  1. 再猜测是不是客户提供的密码有错误,毕竟密码输错对很多人来说是经常的事情,只是这可能性比较小。
    于是我找个客户核对了下,客户提供了他们网页版邮箱地址,我测试登录了下,确认了密码没问题。
  1. 推测客户的企业邮箱可能是用第三方授权码才能登录(QQ邮箱、网易邮箱在第三方登录时也是用授权码)
    于是乎再找客户了解了下他们使用第三方邮箱软件的登录方式,得到的反馈是,电脑上的foxmail和手机上网易邮箱软件,都是可以直接邮箱+密码登录。因此,排查此问题。

  2. 看着授权失败的日志发呆了会,我灵光一闪,想到会不会是邮箱还需要设置开启这种smap协议,如下图(QQ邮箱SMTP服务需要开启才能用) SMTP.png

    于是我又登录上了企业邮箱的网页版,将邮箱的所有设置检查了一遍,并没有发现类似这SMTP服务的开关设置。又又又排除掉了一种可能。

  1. 后来死马当活马医,命令行telnet下邮箱服务器地址和端口,看看能否正常打通
    telnet请求回应成功,端口可以正常打通。说明地址没问题。于是乎我开始懵了。。。。


问题处理


问题总结

现在大公司都有自家的邮箱服务,邮箱的标准协议功能大家也都是一样的,如邮箱登录、收发件等。如果大家实施过程中,自己写了这类邮箱操作的代码,测试在自己环境可以正常运行,而在客户环境运行不了。可以先排查掉一些低级错误,如邮箱服务器端口能否正常telnet通、邮箱是否有打开相关服务协议等。如果这类低级错误问题排查后还是无法解决。最好还是咨询下该公司的邮箱运维同事,看看他们邮箱的使用,是不是有什么特殊的规则,调用时有没有需要注意的事项等。

排除了不可能,剩下的就是真相 。------ 柯南道尔

【高手过招】第 2 期:实施 RPA 项目中,你遇到了哪些棘手的问题?

上一篇下一篇

猜你喜欢

热点阅读