目录
在实际开发工作中,发送和收取邮件是很常见的需求。Python 标准库自带了丰富的邮件处理模块,这里介绍邮件发送使用 smtplib
和 email
,邮件收取使用 imaplib
和 email
。
一、邮件发送(SMTP协议)
1. 环境准备
无需第三方依赖,Python3 标准库自带。
建议使用邮箱的授权码代替明文密码,并确保已经在邮箱设置中开启了SMTP服务。
2. 发送文本邮件的简单示例
以QQ邮箱为例:
Python
import smtplib
from email.mime.text import MIMEText
# 你的信息
smtp_server = 'smtp.qq.com'
smtp_port = 465
user = '你的QQ邮箱地址' # 如 123456789@qq.com
password = '你的授权码' # 不是QQ密码,是“设置”-“账户”-“生成授权码”
# 收件人
receiver = '收件人邮箱'
# 构造邮件内容
msg = MIMEText('你好,这是一封用Python发送的邮件!', 'plain', 'utf-8')
msg['From'] = user
msg['To'] = receiver
msg['Subject'] = 'Python 邮件发送测试'
# 发送邮件
server = smtplib.SMTP_SSL(smtp_server, smtp_port)
server.login(user, password)
server.sendmail(user, [receiver], msg.as_string())
server.quit()
print("邮件发送成功!")
说明
- 如果有多个收件人,把
[receiver]
换成收件人列表即可。 - 必须用授权码登录,否则会报错。
3. 发送带附件或HTML内容的邮件(高级用法)
Python
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
smtp_server = 'smtp.qq.com'
smtp_port = 465
user = '你的QQ邮箱'
password = '你的授权码'
receiver = '收件人邮箱'
msg = MIMEMultipart()
msg['From'] = user
msg['To'] = receiver
msg['Subject'] = 'Python带附件的邮件'
# 邮件正文,HTML格式
html = '''<h2>邮件测试</h2><p>这是一封带附件的测试邮件。</p>'''
msg.attach(MIMEText(html, 'html', 'utf-8'))
# 添加附件
with open('test.txt', 'rb') as f:
part = MIMEApplication(f.read())
part.add_header('Content-Disposition', 'attachment', filename='test.txt')
msg.attach(part)
server = smtplib.SMTP_SSL(smtp_server, smtp_port)
server.login(user, password)
server.sendmail(user, [receiver], msg.as_string())
server.quit()
print("带附件的邮件发送成功!")
二、邮件收取(IMAP协议)
1. 开启IMAP
确保邮箱开启IMAP(QQ邮箱“设置”——“账户”——“开启IMAP/SMTP服务”)
2. 获取收件箱中最近一封邮件内容
Python
import imaplib
import email
from email.header import decode_header
imap_host = 'imap.qq.com'
user = '你的QQ邮箱'
password = '你的授权码'
# 登录邮箱
mail = imaplib.IMAP4_SSL(imap_host)
mail.login(user, password)
# 选择收件箱(只读模式)
mail.select('INBOX', readonly=True)
# 搜索邮件,获取所有邮件的编号
status, data = mail.search(None, 'ALL')
mail_ids = data[0].split()
print(f"总共{len(mail_ids)}封邮件.")
# 获取最新一封邮件的ID
latest_id = mail_ids[-1]
# 获取最新一封邮件的数据
status, data = mail.fetch(latest_id, '(RFC822)')
raw_email = data[0][1]
msg = email.message_from_bytes(raw_email)
# 解析邮件主题
subject, encoding = decode_header(msg['Subject'])[0]
if isinstance(subject, bytes):
if encoding:
subject = subject.decode(encoding)
else:
subject = subject.decode('utf-8')
print('主题:', subject)
# 解析发件人
from_, encoding = decode_header(msg.get('From'))[0]
if isinstance(from_, bytes):
if encoding:
from_ = from_.decode(encoding)
else:
from_ = from_.decode('utf-8')
print('发件人:', from_)
# 提取正文内容
def get_email_content(msg):
if msg.is_multipart():
for part in msg.walk():
content_type = part.get_content_type()
content_disposition = str(part.get('Content-Disposition'))
if content_type == 'text/plain' and 'attachment' not in content_disposition:
charset = part.get_content_charset()
content = part.get_payload(decode=True)
try:
if charset:
content = content.decode(charset)
else:
content = content.decode()
except:
content = content.decode('utf-8', errors='ignore')
return content
else:
charset = msg.get_content_charset()
content = msg.get_payload(decode=True)
if charset:
content = content.decode(charset)
else:
content = content.decode()
return content
body = get_email_content(msg)
print('正文内容:\n', body)
# 退出
mail.logout()
三、总结与注意事项
- 授权码:发送和收取通常都要求使用邮箱“授权码”,不是登录密码。
- IMAP/SMTP需开启:需去邮箱设置中开启相应功能。
- 收件箱容量:通过
mail_ids
可遍历所有邮件,循环获取更多邮件内容。 - 邮件解析:邮件内容分为text/html/附件等多种格式,需注意解析区分。
- 异常处理:实际开发中注意添加异常捕获处理。
四、完整流程小结
- 邮件发送:
smtplib
+email
- 邮件接收:
imaplib
+email
- 需在邮箱中开启相关服务并获取授权码。