Skip to content

发送邮件、发送短信

更新: 2025/2/24 字数: 0 字 时长: 0 分钟

通过邮件将生成好的文档发送给指定的收件人,然后用短信告知对方我们发出了邮件。这些事情利用Python程序也可以轻松愉快的解决。

发送邮件

在即时通信软件如此发达的今天,电子邮件仍然是互联网上使用最为广泛的应用之一,公司向应聘者发出录用通知、网站向用户发送一个激活账号的链接、银行向客户推广它们的理财产品等几乎都是通过电子邮件来完成的,而这些任务应该都是由程序自动完成的。我们可以用HTTP(超文本传输协议)来访问网站资源,HTTP是一个应用级协议,它建立在TCP(传输控制协议)之上,TCP为很多应用级协议提供了可靠的数据传输服务。如果要发送电子邮件,需要使用SMTP(简单邮件传输协议),它也是建立在TCP之上的应用级协议,规定了邮件的发送者如何跟邮件服务器进行通信的细节。

邮件端口

25端口(SMTP):**是非加密发件端口,为SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)服务所开放的。**如今绝大多数邮件服务器都使用该协议。当你给别人发送邮件时,你的机器的某个动态端口(大于1024)就会与邮件服务器的25端口建立一个连接,你发送的邮件就会通过这个连接传送到邮件服务器上,保存起来。

465端口(SMTP_SSL/SMTPS):是加密发件端口,为SMTP_SSL(SMTP-over-SSL)协议服务开放的。这是SMTP协议基于SSL安全协议之上的一种变种协议,它继承了SSL安全协议的非对称加密的高度安全可靠性,可防止邮件泄露。SMTPS和SMTP协议一样,也是用来发送邮件的,只是更安全些,防止邮件被黑客截取泄露,还可实现邮件发送者抗抵赖功能。防止发送者发送之后删除已发邮件,拒不承认发送过这样一份邮件。

587端口(SMTP-MSA):**是加密发件端口,为SMTP-MSA(Message submission agent) 协议服务开放的,几乎类似于标准SMTP端口,还支持TLS,这意味着可以安全的提交邮件,也是现在最新的标准,现在例如Apple Mail 及 Outlook都预设默认使用587端口。**当前默认都选这个就好了,除非被运营商所拦截。

109端口(POP2):是非加密收件端口,为POP2(Post Office Protocol Version 2,邮局协议2)服务开放的。

110端口(POP3):**是非加密收件端口,为POP3(Post Office Protocol Version 3,邮局协议3)服务开放的。**部分邮箱服务提供商简写为不加3的pop(如126邮箱的 pop.126.com)。

143端口(IMAP):是非加密收件端口,为IMAP(INTERNET MESSAGE ACCESS PROTOCOL,消息访问协议)服务开放的。

993端口(IMAP_SSL/IMAPS):是加密的收件端口,为IMAP_SSL(IMAP-over-SSL)协议服务开放的。这是IMAP协议基于SSL安全协议之上的一种变种协议,它继承了SSL安全协议的非对称加密的高度安全可靠性,可防止邮件泄露。IMAPS和IMAP协议一样,也是用来接收邮件的,只是更安全些,防止邮件被黑客截取泄露,还可实现邮件接收方抗抵赖功能。防止收件者收件之后删除已收邮件,拒不承认收到过这样一封邮件。

995端口(POP3_SSL/POP3S):是加密的收件端口,为POP3_SSL(POP3-over-SSL)协议服务开放的。这是POP3协议基于SSL安全协议之上的一种变种协议,它继承了SSL安全协议的非对称加密的高度安全可靠性,可防止邮件泄露。POP3S和POP3协议一样,也是用来接收邮件的,只是更安全些,防止邮件被黑客截取泄露,还可实现邮件接收方抗抵赖功能。防止收件者收件之后删除已收邮件,拒不承认收到过这样一封邮件。

协议区别

在邮件服务器的设置中,一般都会提供两种服务POP3/SMTP和IMAP/SMTP,如下所示:

QQ截图20230301115222

**两种服务收件使用的都是SMTP(Simple Mail Transfer Protocol,简单邮件传输协议),不同的是一种服务发件使用的是POP3(Post Office Protocol Version 3,邮局协议3),另一种服务发件使用的是IMAP(INTERNET MESSAGE ACCESS PROTOCOL,消息访问协议)。**协议的区别在于:

  • POP3协议允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮件、标记已读等),不会反馈到服务器上。比如通过客户端收取了邮箱中的3封邮件并移动到其他文件夹,邮箱服务器上的这些邮件是没有同时被移动的 。
  • IMAP协议提供webmail与电子邮件客户端之间的双向通信,客户端的操作都会反馈到服务器上,对邮件进行的操作,服务器上的邮件也会做相应的动作。同时,IMAP像POP3那样提供了方便的邮件下载服务,让用户能进行离线阅读。IMAP提供的摘要浏览功能可以让你在阅读完所有的邮件到达时间、主题、发件人、大小等信息后才作出是否下载的决定。此外,IMAP更好地支持了从多个不同设备中随时访问新邮件。

总之,POP3更易丢失邮件或多次下载相同的邮件,而IMAP整体上为用户带来更为便捷和可靠的体验,而且IMAP通过邮件客户端与webmail之间的双向同步功能很好地避免了这些问题。

5091690-77c7e8778e01f7df

开启SMTP

**发送邮件需要接入邮件服务器,我们首先登录我们的邮件账户,在设置中选择POP3/SMTP服务开启,通过发送短信的方式来获取授权码,短信发送成功后,点击“我已发送”就可以获得授权码,授权码需要妥善保管,因为一旦泄露就会被其他人冒用你的身份来发送邮件,完成以上操作就相当于获得了邮件服务器。**具体的操作如下所示:

v2-d83d7c223567c12b2de008f5e2ca7f0c_720w

v2-ac7bc5f42f50bc70a7118c7bcd2d5af8_720w

发送邮件

**在Python中通过名为 smtplib 的内置模块将这些操作简化成了 SMTP_SSL 对象,通过该对象的 loginsend_mail 方法,就能够完成发送邮件的操作。**下面的代码例举了邮件的三种形式:

  • 包含普通文本的正文内容邮件(普通文字的邮件,不包含任何格式);
  • 包含HTML格式的正文内容邮件(文字内容包HTML标签);
  • 包含附件的邮件(附件的内容需要处理成BASE64编码,那么它就和普通的文本内容几乎没有什么区别。BASE64是一种基于64个可打印字符来表示二进制数据的表示方法,常用于某些需要表示、传输、存储二进制数据的场合,电子邮件就是其中之一。
python
import smtplib
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from urllib.parse import quote

'''
邮件配置
'''
# 邮件服务器域名(自行修改)
EMAIL_HOST = 'smtp.qq.com'
# 邮件服务端口(通常是465)
EMAIL_PORT = 465
# 登录邮件服务器的账号(自行修改)
EMAIL_USER = '...@qq.com'
# 开通SMTP服务的授权码(自行修改)
EMAIL_AUTH = '...'
# 发件人(自行修改)
FROM_SUER = '...@qq.com'
# 收件人(列表中可以添加多个收件人)
TO_USER = ['...@qq.com', '...@qq.com']

'''
邮件主体
'''
# 创建邮件主体对象
email = MIMEMultipart()
# 设置邮件显示的发件人
email['From'] = FROM_SUER
# 设置邮件显示的收件人
email['To'] = ';'.join(TO_USER)
# 设置邮件显示的主题
email['Subject'] = Header('实时新闻', 'utf-8')

'''
包含普通文本的正文内容邮件
'''
# 添加邮件显示的正文
content = """据德国媒体报道,当地时间9日,德国火车司机工会成员进行了投票,将于当地时间10日起进行全国范围内的客运和铁路基础设施48小时罢工。"""
email.attach(MIMEText(content))

'''
包含HTML格式的正文内容邮件
'''
content = """<h1>德国火车司机罢工</h1>
<p>据德国媒体报道,当地时间9日,德国火车司机工会成员进行了投票。</p>
<p>将于当地时间10日起进行全国范围内的客运和铁路基础设施48小时的罢工。</p>
<p>来源新闻社</p>"""
email.attach(MIMEText(content, 'html', 'utf-8'))

'''
包含附件的邮件
'''
# 以二进制的方式读取作为附件的文件
with open('德国火车司机罢工.docx', 'rb') as file:
    file_con = file.read()
# 将附件内容处理成BASE64编码
attachment = MIMEText(file_con, 'base64', 'utf-8')
# 指定内容类型
attachment['content-type'] = 'application/octet-stream'
# 将邮件名称中的中文文件名处理成百分号编码
filename = quote('德国火车司机罢工.docx')
# 指定如何处置内容
attachment['content-disposition'] = f'attachment; filename="{filename}"'
# 添加邮件的附件内容
email.attach(attachment)

'''
发送邮件
'''
# 创建SMTP_SSL对象,通过465端口连接邮件服务器
smtp_obj = smtplib.SMTP_SSL(EMAIL_HOST, EMAIL_PORT)
# 通过用户名和授权码登录邮件服务器
smtp_obj.login(EMAIL_USER, EMAIL_AUTH)
# 发送邮件(发件人、收件人、邮件内容)
smtp_obj.sendmail(FROM_SUER, TO_USER, email.as_string())

一封包含正文内容的邮件,效果如下图:

QQ截图20230302103349

一封包含HTML正文内容和附件的邮件,效果如下图:

QQ截图20230302112409

结合邮件

Loguru 可以和强大的邮件通知模块 notifiers 库结合使用,以在程序意外失败时接收电子邮件,或发送许多其他类型的通知。

python
import notifiers
from notifiers.logging import NotificationHandler

params = {
    "username": "you@gmail.com",
    "password": "abc123",
    "to": "dest@gmail.com"
}

# 初始化时发送一封邮件
notifier = notifiers.get_notifier("gmail")
notifier.notify(message="The application is running!", **params)
# 发生Error时,发邮件进行告警
handler = NotificationHandler("gmail", defaults=params)

发送短信

发送短信也是项目中常见的功能,网站的注册码、验证码、营销信息基本上都是通过短信来发送给用户的。

购买服务

发送短信需要三方平台的支持,下面我们以螺丝帽平台为例,注册账号和购买短信服务的细节我们不在这里进行赘述,大家可以咨询平台的客服。

v2-12f1e5e43971436fb4c0d5539708c78a_720w

IP白名单

**一般情况下,平台为了防范短信被盗用,还会要求设置“IP白名单”,也就是说向短信网关发起请求的主机IP必须在“IP白名单”上,否则的话即使KEY没问题,请求也不会成功。**不清楚如何配置的可以咨询平台客服。

设置签名

目前,大多数短信平台都会要求短信内容必须附上签名,有些涉及到敏感内容的短信,还需要提前配置短信模板,有兴趣的读者可以自行研究。下图是我在螺丝帽平台配置的短信签名“【Python小课】”。

v2-5181c83b4f1584c8e174477160b79fe9_720w

发送短信

**接下来为大家介绍如何用Python程序发送短信,首先我们通过 requests 库向平台提供的短信网关发起一个HTTP请求,通过将接收短信的手机号和短信内容作为参数,就可以发送短信。**代码如下所示:

python
import requests

# 信息主体
tel = '接受者的手机号码'
message = '您的短信验证码是【123456】,打死也不能告诉别人哟!【Python小课】'
data = {'mobile': tel, 'message': message}
# 发送短信(调用螺丝帽短信网关)
url = 'http://sms-api.luosimao.com/v1/send.json'
auth = ('api', 'key-注册成功后平台分配的KEY')
resp = requests.post(url=url, auth=auth, data=data, timeout=10, verify=False)
# 输出返回结果
print(resp.json())

如果上面的代码返回的是 {'error': 0, 'msg': 'OK'} 就说明短信已经发送成功了,如果 error 的值不是 0,可以通过查看官方的开发文档了解到底哪个环节出了问题。螺丝帽平台常见的错误类型如下图所示:

v2-4f239f2fad9d45bcabccc0829e499ce2_720w

当然国内的短信平台很多,读者可以根据自己的需要进行选择(通常会考虑费用预算、短信达到率、使用的难易程度等指标),如果需要在商业项目中使用短信服务,建议购买短信平台提供的套餐服务比较靠谱。