Python - 详情介绍Zmail发送邮件
为了满足在python项目中收发邮件给其他人,可利用自己的邮箱账号结合Zmail来完成。Zmail 使得在python3中发送和接受邮件变得更简单。你不需要手动添加服务器地址、端口以及适合的协议。Zmail 仅支持python3,不需要任何外部依赖. 不支持python2.
功能特点:
- 自动寻找服务器地址以及端口
- 自动使用可靠的链接协议
- 自动将一个python字典映射成MIME对象(带有附件的)
- 自动添加头文件以及localhostname来避免服务器拒收你的邮件
- 轻松自定义你的头文件
- 支持使用HTML作为邮件内容
- 仅需python>=3.5,你可以将其嵌入你的项目而无需其他的依赖
使用之前:
- 确保项目是Python3
- 开启对应邮箱的POP3和SMTP功能(163、qq、gmail都需要设置应用专用密码,并保存记录下来)
- 如果其他邮箱不在下列中,请不要担心,目前尚未发现不支持的邮箱
服务商地址 | 发送邮件 | 取回邮件 | 备注 |
---|---|---|---|
@163.com | ✓ | ✓ | 需要应用专用密码 |
@qq.com | ✓ | ✓ | 需要应用专用密码 |
@126.com | ✓ | ✓ | |
@yeah.net | ✓ | ✓ | |
@gmail.com | ✓ | ✓ | 需要应用专用密码 |
@sina.com | ✓ | ✓ | |
@outlook | ✓ | ✓ | 需要应用专用密码 |
支持的企业邮箱:
名称 | 使用示例 |
---|---|
腾讯企业邮箱 | zmail.server(‘username’,‘psw’,config=‘qq’) |
阿里企业邮箱 | zmail.server(‘username’,‘psw’,config=‘ali’) |
网易企业邮箱 | zmail.server(‘username’,‘psw’,config=‘163’) |
谷歌企业邮箱 | zmail.server(‘username’,‘psw’,config=‘google’) |
一、开启POP3和SMTP功能:
在邮箱设置中设置该功能,举例说明163、QQ和gmail,记得保存开启后的应用密码!
163:
QQ:
gmail(全程搭梯子,不然进不去页面):
谷歌邮箱的应用密码,需要在谷歌浏览器中的管理您的谷歌Google账号中去设置二步验证先,然后点击链接去创建应用密码,把密码保存下来。后续发送邮件操作,记得按时看下gmail邮箱中的警告邮件,确定该操作属于本人操作。
1.开启POP和IMAP:
2.点击谷歌浏览器右上角,选择管理您的Google账号(下列步骤,移动端谷歌浏览器也能操作):
3.开启二步验证:
4.点击跳转应用密码页面,创建谷歌应用密码:
二、检测POP3和SMTP功能:
import zmail
server = zmail.server('[email protected]', 'xxxxxxxxxxxx') # 邮箱账号和应用专用密码
if server.smtp_able():
print(True)
# SMTP function.
if server.pop_able():
print(True)
# POP function.
三、发送邮件:
import zmail
mail = {
'subject': 'Python - Zmail!', # 邮件标题
'content_text': 'This message from zmail!', # 邮件内容
'attachments': [], # 本地文件的绝对路径
}
server = zmail.server('[email protected]', 'xxxxxxxxxxxx')
server.send_mail('[email protected]', mail)
- 给列表中的收件人发件:
server.send_mail(['[email protected]','[email protected]'], mail)
还可为收件人定义别名(元组,第一参数是别名,第二参数是邮箱地址)
server.send_mail([('同事-老王','[email protected]'),('老板','[email protected]')], mail)
- 发送HTML作为邮件内容(content_html):
mail = {
'subject': 'Python - Zmail!', # 邮件标题
'content_html': ['HTML CONTENT'], # 邮件内容
'attachments': [], # 本地文件的绝对路径
}
server.send_mail('[email protected]', mail)
或者读取html文件内容
with open('C:/Users/Shinelon/Desktop/font/demo.html','r') as f:
content_html = f.read()
mail = {
'subject': 'Python - Zmail!', # 邮件标题
'content_html': content_html, # 邮件内容
'attachments': [], # 本地文件的绝对路径
}
server.send_mail('[email protected]', mail)
- 使用抄送功能:
server.send_mail(['[email protected]','[email protected]'], mail,cc=['[email protected]'])
还可为收件人定义别名(元组,第一参数是别名,第二参数是邮箱地址)
server.send_mail(['[email protected]','[email protected]'], mail, cc=[('同事-小美','[email protected]')])
- 自定义你的server配置:
server = zmail.server('username', 'password', smtp_host='smtp.163.com', smtp_port=994, smtp_ssl=True, pop_host='pop.163.com', pop_port=995, pop_tls=True)
四、取回邮件:
- 获取最新的邮件:
mail = server.get_latest()
print(mail)
- 依据id取回邮件:
mail = server.get_mail(3)
print(mail)
- 依据指定范围取回邮件(标题,开始结束时间,开始结束下标,发送人):
mail = server.get_mails(subject='Zmail',start_time='2024-1-1',end_time='2024-8-12',start_index=1,end_index=10,sender='[email protected]')
- 得到邮箱的信息:
mailbox_info = server.stat() 返回元组: (邮件的数量, 邮箱的大小)
五、解析邮件:
- 通过访问python字典的形式来访问邮件信息:
mail = server.get_mail(2)
subject = mail['subject'] # 标题
print(subject)
- 打印获取的邮件,使用 zmail.show():
mail = server.get_mail(2)
zmail.show(mail)
- 查看邮件的所有内容:
mail = server.get_mail(2)
for k,v in mail.items():
print(k,v)
六、相关API介绍:
zmail.server(username,password,smtp_host,smtp_port,smtp_ssl,smtp_tls,pop_host,pop_port,pop_ssl,pop_tls,config,timeout=60, debug=False, log=None,auto_add_from=True, auto_add_to=True)
返回 MailServer 实例, 它实现了所有SMTP和POP的功能
参数名 | 类型 | 描述 |
---|---|---|
username | str | 邮箱地址 |
password | str | 应用专用密码 |
smtp_host | str | SMTP主机 |
smtp_port | int | SMTP端口 |
smtp_ssl | SMTP SSL加密方式 | |
smtp_tls | SMTP TLS加密方式 | |
pop_host | str | POP主机 |
pop_port | int | POP端口 |
pop_ssl | POP SSL加密方式 | |
pop_tls | POP TLS加密方式 | |
config | 使用企业邮箱的便捷方法,如果被指定,企业邮箱的配置将会取代所有自动生成的配置 | |
timeout | int、float | 指定了最长的等待时长(秒) |
debug | bool | 如果为True,server将会打开调试模式,并且显示调试信息 |
log | None、logging.logger的实例 | 如果为None,将会使用zmail默认的日志记录器,你可以通过logging.getLogger(‘zmail’)来访问默认的日志记录器 |
auto_add_to | bool | 如果为True,当键’to’(不区分大小写)不在发送的邮件中时,默认的’to’将会自动添加到邮件中 |
auto_add_from | bool | 如果为True,当键’from’(不区分大小写)不在发送的邮件中时,默认的’from’将会自动添加到邮件中 |
MailServer.send_mail(recipients, mail, timeout=None,auto_add_from=False, auto_add_to=False)
成功发送时返回True
参数名 | 类型 | 描述 |
---|---|---|
recipients | str、list | 收件邮箱 |
dict、CaseInsensitiveDict(通常是接收到的邮件) | ||
timeout | int、float | 如果不为None,它将会取代server的超时时间 |
auto_add_from | bool | 如果不为None,它将会取代server的auto_add_from |
auto_add_to | bool | 如果不为None,它将会取代server的auto_add_to |
MailServer.stat()
获取邮箱状态. 返回值是两个整型组成的元组: (邮件数量, 邮件大小).
MailServer.get_mail(which)
返回 Mail,同样将邮件设置为已读
参数名 | 类型 | 描述 |
---|---|---|
which | int | 代表了邮件在邮箱中的位置。必须位于1至邮件数量(从MailServer.stat()返回)的范围内 |
MailServer.get_mails(subject=None,start_time=None,end_time=None,sender=None,start_index=None,end_index=None)
返回 一个由Mail组成的列表,同时会将所有取出的邮件置为已读
参数名 | 类型 | 描述 |
---|---|---|
subject | None、int | 如果不为None,每个邮件的subject都必须包含subject |
start_time | None、str、datetime对象 | 如果为字符串,它的结构为"年-月-日 时:分:秒"(例如 “2018-1-1 10:10:20”) ,如果不为None,每个邮件的时间必须大于start_time |
end_time | None、str、datetime对象 | |
sender | None、str | 如果不为None,每个邮件的’from’头部必须包含sender |
start_index | None、int | 如果为None或者小于1,将会被置为1。如果大于邮件数量(从MailServer.stat()返回),将会被置为邮件数量。 |
end_index | None、int | 选择的邮件范围将会被设置为start_index到end_index之间 |
MailServer.get_latest()
返回最新的邮件。等同于MailServer.get_mail(message_count)。message_count从MailServer.stat()中可得到,同时会将邮件置为已读。
MailServer.get_headers(start_index=None,end_index=None)
返回一个由邮件头部组成的列表(一个CaseInsensitiveDict组成的列表),取回邮件头的范围将会被限制在start_index至end_index。和它们在MailServer.get_mails()中的表现形式相同
MailServer.delete(which)
which 表明了那封邮件应该被删除
MailServer.smtp_able()
返回True如果SMTP工作正常否则返回False
MailServer.pop_able()
返回True如果POP工作正常否则返回False
zmail.show(mails)
你可以是用这个函数来打印一个或多个邮件
zmail.save_attachment(mail,target_path=None,overwrite=False)
将邮件的附件存储到target_path。如果不指定,target_path将会是当前目录。如果overwrite为True,写入过程将会覆盖可能存在的同名文件
zmail.save(mail,name=None,target_path=None,overwrite=False)
保存邮件
zmail.read(file_path,SEP=b’\r\n’)
读取邮件
七、Mail 结构
Mail (用于发送),可为dict或者CaseInsensitiveDict(一般从get_mail or get_mails获得)
字段名 | 描述 |
---|---|
subject | 邮件的标题 |
from | 'from’头部,表明了邮件的来源 |
to (不在使用) | 你可以使用一个元组(name,address)来指定接收人的名字,适用于抄送和发送。 |
content_text | 邮件的文本内容,可为字符串或者一个由字符串组成的列表 |
content_html | 邮件的HTML内容,可为字符串或者一个由字符串组成的列表 |
attachments | 包含了所有附件。可为 字符串 或者 一个由字符串组成的列表 或者 一个由元组组成的列表。 |
headers | 如果你想要为邮件添加额外的头文件,你可以在这指定。必须为dict。 |
Mail(从 get_mail 或 get_mails获得)
字段名 | 描述 |
---|---|
subject | 邮件的标题 |
from | 'from’头部,表明了邮件的来源 |
to | 'to’头部,表明了邮件的目的地 |
content_text | 邮件的文本内容,可为字符串或者一个由字符串组成的列表 |
content_html | 邮件的HTML内容,可为字符串或者一个由字符串组成的列表 |
attachments | 包含了所有附件。(例如[‘1.txt’,b’…']) |
raw_headers | 包含了所有原生头部键值对 |
headers | 包含了所有解析过的头部(为大小写不敏感字典) |
charsets | 包含了所有编码类型 |
date | 邮件时间 |
id | 邮件的id。用于定位在邮箱中位置 |
raw | 原始的邮件信息。由bytes组成的列表 |
八、问题反馈:
- 发送或者接受失败:
- 检查是否开启了SMTP和POP3功能
- 根据服务器SMTP或者POP3地址的端口填写server(没有填写的将会为默认值)
- SMTP:server = zmail.server(‘user’,‘psw’,smtp_host = ‘xxx’,smtp_port = ‘yyyyy’,smtp_ssl=True)
- POP3:server = zmail.server(‘user’,‘psw’,pop_host = ‘xxx’,pop_port = ‘yyyyy’,pop_ssl=True)
- 应用专用密码错误或者忘记:
- 重新关闭POP3和SMTP功能,再开启,或删除已有密码再重新创建
- 如果出现连接主机超时返回错误:
- 特别是gmail邮箱,感觉还是需要搭梯子或者设置代理,不然国内网络无法访问外网