首页 / Python3 入门教程 / 邮件与 XML/JSON 处理

Python3 入门教程

邮件与 XML/JSON 处理

本教程共 70 篇 · 第 59 篇 · 更新于 2026-07-22 · 约 5 分钟阅读

PythonPython3 入门教程SMTPJSONXML

59. 邮件与 XML/JSON 处理

本节目标:学会用 Python 发送邮件,掌握 XML 和 JSON 的解析与生成方法,理解什么时候该用哪种格式。

程序之间交换数据,光会 socket 还不够。邮件是最古老也最可靠的异步通信方式,XML 和 JSON 则是两种主流的数据序列化格式。这节把这三件事一次讲清楚。

SMTP 发送邮件

SMTP(Simple Mail Transfer Protocol)是发邮件的标准协议。Python 内置 smtplibemail 模块,不需要额外安装。

下面是一段发送纯文本邮件的完整示例,以 QQ 邮箱为例:

from smtplib import SMTP_SSL
from email.mime.text import MIMEText
from email.header import Header

smtp_server = 'smtp.qq.com'
port = 465
sender = 'your_qq@qq.com'
password = '你的授权码'  # 不是邮箱密码,是 SMTP 授权码
receiver = 'friend@example.com'

msg = MIMEText('这是一封来自 Python 的测试邮件。', 'plain', 'utf-8')
msg['From'] = Header('Python机器人', 'utf-8')
msg['To'] = Header('朋友', 'utf-8')
msg['Subject'] = Header('测试邮件', 'utf-8')

with SMTP_SSL(smtp_server, port) as server:
    server.login(sender, password)
    server.sendmail(sender, [receiver], msg.as_string())
    print("邮件已发送")

关键点:

  • QQ 邮箱、网易邮箱等主流服务商都强制要求 SSL/TLS 加密,端口一般是 465 或 587。
  • login() 需要的不是网页登录密码,而是专门的授权码。去邮箱设置里开启 SMTP 服务就能拿到。
  • MIMEText 构造邮件正文,plain 表示纯文本,html 表示 HTML 格式。

如果要发送带附件的邮件,需要改用 MIMEMultipart

from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = receiver
msg['Subject'] = '带附件的邮件'

msg.attach(MIMEText('请查收附件。', 'plain', 'utf-8'))

with open('report.pdf', 'rb') as f:
    mime = MIMEBase('application', 'octet-stream')
    mime.set_payload(f.read())
    encoders.encode_base64(mime)
    mime.add_header('Content-Disposition', 'attachment; filename="report.pdf"')
    msg.attach(mime)
Warning

不要把授权码硬编码在代码里。实际项目中应从环境变量或配置文件读取,避免泄露。

POP3 收取邮件

POP3(Post Office Protocol v3)用于从邮件服务器下载邮件。如果只是读取自己的邮箱,IMAP 更灵活;POP3 的特点是简单、下载后通常从服务器删除。

from poplib import POP3_SSL
from email.parser import BytesParser

server = POP3_SSL('pop.qq.com', 995)
server.user('your_qq@qq.com')
server.pass_('授权码')

msg_count, msg_size = server.stat()
print(f"共有 {msg_count} 封邮件,总大小 {msg_size} 字节")

if msg_count > 0:
    resp, lines, octets = server.retr(1)
    msg_content = b'\r\n'.join(lines)
    msg = BytesParser().parsebytes(msg_content)
    print(f"主题: {msg['Subject']}")
    print(f"发件人: {msg['From']}")

server.quit()
Tip

现在新项目中收邮件更推荐用 imaplib(IMAP 协议),支持文件夹管理和已读标记同步。POP3 更适合简单的「下载并清空」场景。

JSON:程序世界的通用语

JSON(JavaScript Object Notation)是现代 API 的事实标准,读写都极其简单。

Python 对象转 JSON 字符串:

import json

data = {
    'name': 'Alice',
    'age': 30,
    'skills': ['Python', 'SQL']
}

json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)

JSON 字符串转 Python 对象:

obj = json.loads(json_str)
print(obj['name'])

直接读写文件:

with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open('data.json', 'r', encoding='utf-8') as f:
    loaded = json.load(f)
Note

JSON 只支持字符串、数字、布尔、null、数组和对象。Python 的 datetimeset、自定义类不能直接序列化,需要先转成字符串或列表。

XML:老一辈的格式

XML(eXtensible Markup Language)曾经称霸数据交换领域,现在逐渐被 JSON 取代。但配置文件、Office 文档底层、企业接口中仍大量存在,有必要会读会写。

Python 内置 xml.etree.ElementTree 模块处理 XML:

import xml.etree.ElementTree as ET

xml_str = '''<root>
    <person id="1">
        <name>Alice</name>
        <age>30</age>
    </person>
</root>'''

root = ET.fromstring(xml_str)

# 遍历
for person in root.findall('person'):
    name = person.find('name').text
    age = int(person.find('age').text)
    pid = person.get('id')
    print(f"ID={pid}, 名字={name}, 年龄={age}")

生成 XML:

root = ET.Element('catalog')
book = ET.SubElement(root, 'book', {'id': 'bk001'})
ET.SubElement(book, 'title').text = 'Python 教程'
ET.SubElement(book, 'price').text = '59.00'

tree = ET.ElementTree(root)
tree.write('catalog.xml', encoding='utf-8', xml_declaration=True)
Tip

如果 XML 结构复杂或需要验证 Schema,第三方库 lxml 比标准库更快更强大,支持 XPath、XSLT 等高级功能。

JSON vs XML 怎么选

维度JSONXML
可读性简洁标签冗余
解析速度较慢
数据类型有限全靠字符串
注释不支持支持
Schema 验证JSON SchemaDTD/XSD
适用场景Web API、配置复杂文档、遗留系统

新项目优先 JSON,遇到老系统或需要严格验证的场合再请 XML 出场。

小结

  • smtplib + email 模块可以发送纯文本、HTML、带附件的邮件。
  • json 模块让 Python 对象和 JSON 字符串之间无缝转换。
  • xml.etree.ElementTree 足以应对大部分 XML 解析和生成需求。
  • 数据交换优先 JSON,配置或遗留接口再考虑 XML。

来源:参考了 runoob「Python3 SMTP发送邮件/JSON/XML解析」、liaoxuefeng「20. 电子邮件/16.11. XML」等,改写后所得。