如何用Python发送邮件?

答案:Python发送邮件需使用smtplib和email模块,通过SMTP服务器认证连接并构造邮件内容。首先配置发件人邮箱、授权码、收件人及服务器信息,利用MIMEText创建纯文本邮件,MIMEMultipart构建多部分邮件以添加附件或HTML内容,发送时启用TLS或SSL加密,并妥善处理异常。常见问题多为授权码错误、服务器端口配置不当或邮箱服务未开启,需逐一排查。

如何用python发送邮件?

用Python发送邮件,核心在于利用其内置的

smtplib

email

模块。

smtplib

负责连接邮件服务器并发送邮件,而

email

模块则用来构造邮件的各种内容,比如正文、附件、HTML格式等。理解这两者的协同工作,就能高效、灵活地实现邮件的自动化发送。

解决方案发送一封最基础的纯文本邮件,我们需要几个关键步骤。这通常是我开始一个新邮件自动化项目时的起点,简单直接,能快速验证连接和认证是否成功。

首先,导入必要的模块:

smtplib

用于SMTP协议交互,

email.mime.text.MIMEText

用于创建文本邮件体。

import smtplibfrom email.mime.text import MIMETextfrom email.header import Header# 邮件配置sender_email = 'your_email@example.com'  # 发件人邮箱sender_password = 'your_app_password'    # 发件人邮箱的授权码(或密码,但不推荐直接使用主密码)receiver_email = 'recipient@example.com' # 收件人邮箱smtp_server = 'smtp.example.com'         # SMTP服务器地址,例如:smtp.gmail.com, smtp.qq.comsmtp_port = 587                          # SMTP服务器端口,SSL通常是465,TLS通常是587# 邮件内容subject = 'Python发送测试邮件'body = '你好!这是一封由Python脚本发送的测试邮件。'# 构建MIMEText对象msg = MIMEText(body, 'plain', 'utf-8')msg['From'] = Header(f'发件人名称 ', 'utf-8')msg['To'] = Header(f'收件人名称 ', 'utf-8')msg['Subject'] = Header(subject, 'utf-8')try:    # 连接SMTP服务器    # 对于TLS加密,使用starttls()    server = smtplib.SMTP(smtp_server, smtp_port)    server.starttls() # 启动TLS加密    # 登录邮箱    server.login(sender_email, sender_password)    # 发送邮件    server.sendmail(sender_email, receiver_email, msg.as_string())    print('邮件发送成功!')except smtplib.SMTPException as e:    print(f'邮件发送失败: {e}')except Exception as e:    print(f'发生未知错误: {e}')finally:    if 'server' in locals() and server:        server.quit() # 关闭连接

这里需要特别注意的是

sender_password

。出于安全考虑,大多数主流邮箱服务(如Gmail、QQ邮箱、Outlook等)都推荐使用授权码而非你的账户主密码。授权码是专门为第三方应用生成的一次性或应用专用密码,即使泄露也不会直接影响你的主账户安全。获取授权码的方法通常在邮箱的“设置”->“账户”->“POP3/IMAP/SMTP服务”或“客户端授权码”部分。

Python发送带附件的邮件怎么实现?在实际应用中,纯文本邮件往往不够用,我们经常需要发送带有文件附件的邮件。这比纯文本邮件稍微复杂一点,但

email

模块提供了非常强大的工具来处理。我的经验是,一旦你掌握了

MIMEMultipart

,处理附件就变得非常直观了。

要发送带附件的邮件,我们需要使用

email.mime.multipart.MIMEMultipart

来创建一个多部分邮件体,然后将文本内容和附件作为不同的部分添加到这个邮件体中。

立即学习“Python免费学习笔记(深入)”;

import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.mime.base import MIMEBasefrom email import encodersfrom email.header import Headerimport ossender_email = 'your_email@example.com'sender_password = 'your_app_password'receiver_email = 'recipient@example.com'smtp_server = 'smtp.example.com'smtp_port = 587subject = '带附件的Python测试邮件'body = '你好!这是一封带附件的Python测试邮件。请查收附件。'attachment_path = 'path/to/your/file.pdf' # 附件的完整路径# 创建MIMEMultipart对象,用于组合邮件正文和附件msg = MIMEMultipart()msg['From'] = Header(f'发件人名称 ', 'utf-8')msg['To'] = Header(f'收件人名称 ', 'utf-8')msg['Subject'] = Header(subject, 'utf-8')# 添加邮件正文msg.attach(MIMEText(body, 'plain', 'utf-8'))# 添加附件if os.path.exists(attachment_path):    try:        with open(attachment_path, 'rb') as f:            # 创建MIMEBase对象,用于表示附件            part = MIMEBase('application', 'octet-stream')            part.set_payload(f.read())        # 对附件进行Base64编码        encoders.encode_base64(part)        # 设置附件的文件名,确保中文文件名能正确显示        file_name = os.path.basename(attachment_path)        part.add_header('Content-Disposition', 'attachment', filename=(Header(file_name, 'utf-8').encode()))        msg.attach(part)        print(f"附件 '{file_name}' 添加成功。")    except FileNotFoundError:        print(f"错误:附件文件 '{attachment_path}' 未找到。")    except Exception as e:        print(f"添加附件时发生错误: {e}")else:    print(f"警告:附件文件 '{attachment_path}' 不存在,邮件将不包含此附件。")try:    server = smtplib.SMTP(smtp_server, smtp_port)    server.starttls()    server.login(sender_email, sender_password)    server.sendmail(sender_email, receiver_email, msg.as_string())    print('带附件的邮件发送成功!')except smtplib.SMTPException as e:    print(f'邮件发送失败: {e}')except Exception as e:    print(f'发生未知错误: {e}')finally:    if 'server' in locals() and server:        server.quit()

这里需要注意

MIMEBase('application', 'octet-stream')

的使用,它是一个通用的二进制流类型。

encoders.encode_base64(part)

是邮件协议中对二进制数据进行编码的标准方式。最重要的是

Content-Disposition

头,它告诉邮件客户端这是一个附件,并且指定了附件的文件名。对于中文文件名,使用

Header(file_name, 'utf-8').encode()

可以确保其正确显示。

如何用Python发送HTML格式的邮件?现代邮件客户端对HTML格式的支持非常普遍,发送HTML邮件能让你的内容更具吸引力,可以包含图片、链接、排版等。我个人在发送报告、通知或营销邮件时,几乎总是倾向于使用HTML格式。

发送HTML邮件与发送纯文本邮件类似,只是在创建

MIMEText

对象时,需要将

_subtype

参数设置为

'html'

。如果你想提供一个纯文本的备用版本(这是一个好的实践,以防某些老旧的邮件客户端不支持HTML),你可以将纯文本和HTML版本都添加到

MIMEMultipart

中。

import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.header import Headersender_email = 'your_email@example.com'sender_password = 'your_app_password'receiver_email = 'recipient@example.com'smtp_server = 'smtp.example.com'smtp_port = 587subject = 'Python发送HTML格式邮件'# HTML邮件内容html_body = """        

你好!

这是一封由Python脚本发送的HTML格式测试邮件。

你可以点击这里访问我的网站

@@##@@

祝好!

"""# 纯文本备用内容text_body = "你好!这是一封由Python脚本发送的HTML格式测试邮件。n请访问我的网站:https://example.com"# 创建MIMEMultipart对象,用于组合纯文本和HTML版本msg = MIMEMultipart('alternative') # 'alternative'表示这些部分是同一内容的替代表示msg['From'] = Header(f'发件人名称 ', 'utf-8')msg['To'] = Header(f'收件人名称 ', 'utf-8')msg['Subject'] = Header(subject, 'utf-8')# 添加纯文本部分msg.attach(MIMEText(text_body, 'plain', 'utf-8'))# 添加HTML部分msg.attach(MIMEText(html_body, 'html', 'utf-8'))try: server = smtplib.SMTP(smtp_server, smtp_port) server.starttls() server.login(sender_email, sender_password) server.sendmail(sender_email, receiver_email, msg.as_string()) print('HTML格式邮件发送成功!')except smtplib.SMTPException as e: print(f'邮件发送失败: {e}')except Exception as e: print(f'发生未知错误: {e}')finally: if 'server' in locals() and server: server.quit()

这里关键是

MIMEMultipart('alternative')

,它告诉邮件客户端,这些附件(纯文本和HTML)是同一个内容的替代版本,客户端会选择它最能理解的版本来显示。通常,邮件客户端会优先显示HTML版本。在HTML邮件中嵌入图片,如果图片是外部链接,直接在

@@##@@

标签中引用即可;如果是本地图片,则需要将其作为附件嵌入,并在HTML中通过

cid:

(Content-ID)引用,这会稍微复杂一些,涉及到

email.mime.image.MIMEImage

Content-ID

头的设置。

Python发送邮件,遇到身份验证失败怎么办?身份验证失败是我在自动化邮件脚本开发中最常遇到的问题之一。它往往不是代码逻辑错误,而是配置或安全策略上的问题。遇到这类问题,首先不要慌,一步步排查通常都能解决。

检查用户名和密码(授权码):这是最基本也最容易出错的地方。确保

sender_email

sender_password

完全正确。对于主流邮箱,几乎总是需要使用授权码,而不是你的账户主密码。很多新手会直接填主密码,导致认证失败。例如,Gmail的授权码需要在Google账户安全设置中生成,QQ邮箱和163邮箱也有类似设置。SMTP服务器地址和端口

smtp_server

smtp_port

必须与你的邮箱服务商提供的完全一致。常见的组合是:Gmail:

smtp.gmail.com

, 端口587 (TLS) 或 465 (SSL)QQ邮箱:

smtp.qq.com

, 端口465 (SSL) 或 587 (TLS)Outlook/Hotmail:

smtp.office365.com

, 端口587 (TLS)163邮箱:

smtp.163.com

, 端口465 (SSL) 或 994 (SSL)确保你的代码中

server = smtplib.SMTP(smtp_server, smtp_port)

smtplib.SMTP_SSL(smtp_server, smtp_port)

与端口和加密方式匹配。加密方式:如果端口是587,通常需要调用

server.starttls()

来启动TLS加密。如果端口是465,则应该使用

smtplib.SMTP_SSL()

来建立连接,它默认使用SSL加密,无需再调用

starttls()

。混淆这两种方式会导致连接或认证失败。邮箱账户设置:有些邮箱服务默认关闭了SMTP/POP3/IMAP服务,或者有“客户端授权”之类的选项需要手动开启。例如,Gmail账户可能需要开启“允许不够安全的应用访问”或生成应用专用密码。QQ邮箱需要开启IMAP/SMTP服务并生成授权码。网络或防火墙:极少数情况下,公司的网络策略或个人防火墙可能会阻止对SMTP端口的访问。可以尝试在其他网络环境下测试,或者检查防火墙设置。错误信息:仔细阅读Python抛出的

smtplib.SMTPAuthenticationError

smtplib.SMTPException

的详细信息。它通常会告诉你失败的具体原因,比如“Authentication failed”或“535 Authentication failed”。这些信息是排查问题的关键线索。

我的建议是,遇到认证问题,先去你的邮箱服务商官网查找其SMTP配置文档,然后对照你的代码和账户设置逐一检查。通常,问题都出在授权码或SMTP服务器/端口的配置上。

Placeholder Image如何用Python发送邮件?

以上就是如何用Python发送邮件?的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1369918.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
如何对字典列表进行排序?
上一篇 2025年12月14日 10:04:45
如何使用Python操作数据库(SQLite/MySQL/PostgreSQL)?
下一篇 2025年12月14日 10:05:05

相关推荐

  • 如何掌握Golang接口断言_Golang类型断言语法说明

    Go接口断言核心是运行时确认接口值的具体类型并安全取出,语法为x.(T),推荐用value, ok := x.(T)避免panic;常用于JSON解析、缓存取值、错误分类等场景,多类型用type switch处理。 掌握 Go 接口断言,核心是理解“接口存值、断言取值”这个逻辑。它不是类型转换,而是…

    2026年5月10日
    000
  • HTML如何设置全屏控制样式?fullscreen-controls伪类的作用是什么?

    要实现全屏控制样式,最有效的方法是放弃原生控件并创建自定义ui,具体步骤为:1. 使用javascript的fullscreen api(如element.requestfullscreen()和document.exitfullscreen())控制全屏状态;2. 隐藏原生控件,例如通过设置vid…

    2026年5月10日
    000
  • Service Worker架构:高效令牌处理与网络请求同步实现

    本文探讨了在Service Worker中高效管理认证令牌的策略,特别是如何处理令牌的周期性更新以及确保所有网络请求都能同步获取并使用最新令牌。核心方案是利用JavaScript Promise的特性,通过替换Promise对象而非修改其状态,实现请求的等待与令牌的动态更新,并提供了健壮的错误处理机…

    2026年5月10日
    000
  • 深入理解Python sys.argv:命令行参数处理与常见错误解析

    本文详细解析python中`sys.argv`模块在处理命令行参数时的核心机制,特别是其长度计算和索引规则。我们将通过示例代码阐明`sys.argv[0]`代表脚本名称,而后续元素才是用户提供的参数,从而纠正常见的参数数量判断错误。同时,提供实用的调试技巧和更专业的参数解析方案,帮助开发者有效管理p…

    2026年5月10日
    000
  • PHP字符串关键字高亮与多重匹配策略

    本教程旨在解决在php中对字符串中的多个关键字进行高亮显示时遇到的常见问题,特别是当关键字存在重叠或包含关系时。文章将详细介绍如何利用`preg_replace`结合正则表达式、`preg_quote`进行关键字转义,并通过对关键字列表进行长度排序来确保所有目标关键字(包括包含关系的长短关键字)都能…

    2026年5月10日
    000
  • 组件化开发:用C++20 Modules重构百万行代码库

    组件化开发:用C++20 Modules重构百万行代码库组件化开发:用C++20 Modules重构百万行代码库组件化开发:用C++20 Modules重构百万行代码库组件化开发:用C++20 Modules重构百万行代码库

    使用c++++20 modules重构百万行代码库的目标是提升代码清晰度、编译速度和维护效率。1. c++20 modules解决了传统头文件的编译慢、命名冲突和宏污染问题,通过“引用”方式智能处理依赖。2. 模块划分应遵循高内聚、低耦合、职责单一和可复用原则,按业务功能拆分如网络通信、数据处理等模…

    2026年5月10日 用户投稿
    000
  • 理解元类创建的类的类型

    本文旨在阐明使用元类创建类时,类类型为何是 type 而非元类本身。通过分析元类的 __new__ 方法,解释了直接调用 type 和使用 super() 的区别,并提供示例代码帮助读者深入理解元类的运作机制。 当使用元类创建类时,一个常见的疑问是:为什么创建出来的类的类型是 type 而不是元类本…

    2026年5月10日
    000
  • JavaScript DOM操作:解决null错误与实现动态显示隐藏效果

    本文旨在解决JavaScript在尝试操作尚未加载的DOM元素时出现的null错误,并详细阐述如何正确地实现基于鼠标悬停的元素显示/隐藏效果。核心内容包括理解脚本加载时机的重要性、script标签的放置策略,以及如何使用事件监听器和CSS类来动态控制元素可见性,同时提供处理多个相似元素的通用方法。 …

    2026年5月10日
    000
  • HTML表格数据动态过滤教程

    本文详细介绍了如何使用javascript和jquery实现html表格的客户端动态过滤功能。通过识别并纠正常见的html结构错误,特别是`tbody`和`table`元素的id应用,文章提供了一个高效且易于理解的过滤脚本。教程涵盖了事件监听、输入值获取、行遍历与显示/隐藏逻辑,并强调了`slice…

    2026年5月10日
    000
  • python中def是什么意思 python函数定义关键字解析

    def在python中用于定义函数。1)它标志着函数定义的开始,允许创建可重复使用的代码块。2)函数名应有意义,参数可设默认值,返回值可选。3)使用文档字符串描述函数。4)保持函数简洁,专注单一功能,提高可维护性。 在Python中,def是一个关键字,用于定义函数。让我们深入探讨一下def的含义和…

    2026年5月10日
    000
  • Golang使用os.FileInfo获取文件属性实践

    答案:os.FileInfo接口用于获取文件元信息,通过os.Stat()获取文件属性,结合os.ReadDir()可高效遍历目录,利用Mode()可判断权限与文件类型,适用于文件管理等场景。 在Go语言中,os.FileInfo 是一个接口,用于描述文件的元信息,比如文件名、大小、权限、修改时间等…

    2026年5月10日
    000
  • xml如何实现条件查询功能 在xml中实现高级条件查询的技巧

    在xml中实现条件查询可通过多种方法完成。1. 使用xpath实现基本条件查询,通过类似//book[@category=’fiction’]的表达式筛选满足特定属性值的节点;2. 结合编程语言如python的lxml库,解析xml后遍历节点并进行复杂条件判断,例如检查文本内…

    2026年5月10日
    000
  • HTML5怎么制作日历组件_HTML5日历功能完整实现

    答案:该HTML5日历组件通过HTML结构搭建、CSS美化样式、JavaScript实现月份切换与日期渲染,支持高亮当前日期并可扩展事件标记等功能。 制作一个HTML5日历组件,核心是结合HTML、CSS和JavaScript来实现日期展示、交互与样式美化。下面是一个完整的日历功能实现方法,包含基础…

    2026年5月10日
    000
  • React组件命名规范:确保组件正确渲染的关键

    在react开发中,组件命名规范至关重要。本文将深入探讨为何react组件必须以大写字母开头(pascalcase),以及这一规范如何影响组件的识别与渲染。通过具体的代码示例,我们将展示不规范命名导致的问题,并提供正确的实践方法,帮助开发者避免常见错误,确保react应用中的组件能够被正确解析和显示…

    2026年5月10日
    000
  • JavaScript:根据属性值查找并修改HTML元素的类名

    本文详细介绍了如何使用javascript动态查找html元素并修改其css类。通过document.queryselector结合属性选择器,开发者可以精准定位具有特定属性值的元素,再利用classlist api高效地添加、移除或切换类名,从而实现页面交互和ui状态的灵活控制。 在现代Web开发…

    2026年5月10日
    000
  • 现代并发编程:Actor模型、STM与自动并行化

    并发编程一直是软件开发中的难点,传统的共享内存并发模型容易导致死锁和资源竞争等问题。本文将探讨Actor模型、软件事务内存(STM)和自动并行化这三种简化并发编程的方案,并分析它们在Scala等现代语言中的应用及其优缺点,帮助开发者更好地理解和选择合适的并发模型。 并发编程是现代软件开发中不可或缺的…

    2026年5月10日
    000
  • JavaScript 实现图片上传预览功能:从本地文件到页面展示

    @@##@@注意事项: 安全性: Data URL 可能会比较长,如果直接存储到数据库中,可能会影响性能。建议将图片上传到服务器,存储图片的 URL。兼容性: FileReader 对象在现代浏览器中都支持,但在一些老版本浏览器中可能不支持。需要进行兼容性处理。错误处理: 可以添加错误处理机制,例如…

    2026年5月10日
    000
  • SIMD指令集优化:手写循环速度提升15倍实测

    SIMD指令集优化:手写循环速度提升15倍实测SIMD指令集优化:手写循环速度提升15倍实测SIMD指令集优化:手写循环速度提升15倍实测SIMD指令集优化:手写循环速度提升15倍实测

    simd指令集优化适合处理大规模并行计算任务,通过单指令多数据的方式实现性能提升。1. 确认代码中存在大量可并行操作的同类型计算,如图像或音频处理;2. 选择与目标平台和编译器兼容的指令集,如sse、avx或neon;3. 确保数据内存对齐以避免性能下降或崩溃;4. 使用intrinsic函数或手写…

    2026年5月10日 用户投稿
    000
  • Go语言中new()与复合字面量&T{}内存分配机制解析

    在Go语言中,new(T)和&T{}两种方式在分配结构体内存并返回指向零值实例的指针时,其最终效果是相同的。然而,new()在为基本类型(如整数或布尔值)分配内存并返回指针方面具有独特优势,而&T{}则更常用于结构体的字面量初始化。本文将深入探讨这两种内存分配方式的异同及其适用场景。…

    2026年5月10日
    100
  • PHP格式化数据库查询结果的技巧有哪些_PHP格式化数据库查询结果的实用方法分享

    使用print_r、json_encode、自定义表格、var_dump封装及错误控制符可有效格式化PHP数据库查询结果,提升调试效率与可读性。 当您从数据库中获取查询结果时,原始数据往往不够直观或难以阅读。为了提高调试效率和开发体验,对查询结果进行格式化是必要的。以下是几种实用的PHP技巧来格式化…

    2026年5月10日
    100

发表回复

登录后才能评论
关注微信