python已知邮箱和密码,如何自动发送邮件
在 Python 中,可以使用内置的 smtplib
库来发送邮件。已知邮箱和密码时,以下是实现自动发送邮件的完整步骤:
代码实现
示例代码:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
def send_email(sender_email, sender_password, recipient_email, subject, body):
try:
# SMTP服务器配置 (以Gmail为例,可替换为其他服务)
smtp_server = "smtp.gmail.com"
smtp_port = 587 # 使用 TLS 的端口
# 创建邮件对象
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = recipient_email
message["Subject"] = subject
# 添加邮件正文
message.attach(MIMEText(body, "plain")) # 纯文本邮件正文
# 连接到SMTP服务器并登录
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls() # 启用 TLS 加密
server.login(sender_email, sender_password) # 登录邮箱
server.sendmail(sender_email, recipient_email, message.as_string()) # 发送邮件
print("Email sent successfully!")
except Exception as e:
print(f"Failed to send email: {e}")
# 示例调用
if __name__ == "__main__":
sender_email = "your_email@example.com"
sender_password = "your_password"
recipient_email = "recipient@example.com"
subject = "Test Email"
body = "This is a test email sent from Python."
send_email(sender_email, sender_password, recipient_email, subject, body)
配置说明
1. 替换邮箱服务配置
- Gmail 配置:
- SMTP 服务器:
smtp.gmail.com
- 端口:587(TLS)或 465(SSL)
- SMTP 服务器:
- Outlook 配置:
- SMTP 服务器:
smtp.office365.com
- 端口:587
- SMTP 服务器:
- QQ 邮箱:
- SMTP 服务器:
smtp.qq.com
- 端口:465(SSL)
- SMTP 服务器:
根据你的邮箱服务提供商,替换 smtp_server
和 smtp_port
。
2. 邮箱设置
- Gmail:
- 确保启用了“允许不太安全的应用”或使用应用专用密码。
- QQ 邮箱:
- 需要开启 SMTP 服务,并获取授权码(授权码代替密码)。
- Outlook:
- 默认支持 SMTP,只需邮箱密码。
重要注意事项
-
安全性
- 不要将明文密码保存在代码中。
- 使用环境变量或配置文件存储敏感信息。
示例:使用环境变量
import os sender_password = os.getenv("EMAIL_PASSWORD")
-
调试日志
- 如果发送失败,可启用调试模式:
server.set_debuglevel(1)
- 如果发送失败,可启用调试模式:
-
权限问题
- 如果出现登录失败,检查是否需要启用 SMTP 或生成授权码。
-
HTML 邮件
- 如果需要发送 HTML 格式的邮件:
message.attach(MIMEText("<h1>This is a test email</h1>", "html"))
- 如果需要发送 HTML 格式的邮件:
测试发送邮件
测试前,确保:
- 邮箱服务已启用 SMTP 协议。
- 邮箱密码正确,或使用授权码(如 QQ 邮箱、Gmail)。
总结
- 使用
smtplib
和email
模块,可以快速实现邮件发送。 - 确保正确配置 SMTP 服务器和端口。
- 密码安全性是重点,建议使用授权码或环境变量管理。
如果需要进一步帮助,请告知具体问题或使用的邮箱服务!
如果需要发送带附件的邮件,可以在邮件中使用 email.mime.base.MIMEBase
和 email.encoders
模块来添加附件。以下是具体实现代码:
代码实现:发送带附件的邮件
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
def send_email_with_attachment(sender_email, sender_password, recipient_email, subject, body, attachment_path):
try:
# SMTP服务器配置(这里以Gmail为例)
smtp_server = "smtp.gmail.com"
smtp_port = 587 # 使用 TLS 的端口
# 创建邮件对象
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = recipient_email
message["Subject"] = subject
# 添加邮件正文
message.attach(MIMEText(body, "plain"))
# 添加附件
with open(attachment_path, "rb") as attachment:
part = MIMEBase("application", "octet-stream")
part.set_payload(attachment.read())
# 编码附件为base64
encoders.encode_base64(part)
part.add_header(
"Content-Disposition",
f"attachment; filename={attachment_path.split('/')[-1]}", # 使用文件名
)
message.attach(part) # 将附件添加到邮件中
# 连接到SMTP服务器并发送邮件
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls() # 启用 TLS 加密
server.login(sender_email, sender_password) # 登录邮箱
server.sendmail(sender_email, recipient_email, message.as_string()) # 发送邮件
print("Email with attachment sent successfully!")
except Exception as e:
print(f"Failed to send email: {e}")
# 示例调用
if __name__ == "__main__":
sender_email = "your_email@example.com"
sender_password = "your_password"
recipient_email = "recipient@example.com"
subject = "Test Email with Attachment"
body = "This is a test email with an attachment."
attachment_path = "/path/to/your/file.txt" # 替换为实际的附件路径
send_email_with_attachment(sender_email, sender_password, recipient_email, subject, body, attachment_path)
代码说明
-
添加附件部分
MIMEBase
用于处理附件,指定附件的 MIME 类型(如application/octet-stream
)。encoders.encode_base64(part)
对附件进行 Base64 编码。- 设置附件的
Content-Disposition
,包括文件名。
-
附件文件路径
attachment_path
指定本地文件路径。
-
多个附件
如果需要发送多个附件,可以多次调用message.attach()
:for file_path in attachment_paths: # attachment_paths 是附件路径列表 with open(file_path, "rb") as attachment: part = MIMEBase("application", "octet-stream") part.set_payload(attachment.read()) encoders.encode_base64(part) part.add_header( "Content-Disposition", f"attachment; filename={file_path.split('/')[-1]}", ) message.attach(part)
注意事项
-
文件路径
确保附件文件路径正确,并且有权限读取文件。 -
大附件
- 邮件服务器可能对附件大小有限制,通常为 25MB。
- 如果附件过大,建议使用云存储服务提供下载链接代替。
-
HTML 邮件正文
如果需要发送 HTML 格式正文,可以用以下代码替换MIMEText
部分:message.attach(MIMEText("<h1>This is a test email</h1>", "html"))
运行测试
- 替换示例代码中的邮箱账号、密码、收件人地址和附件路径。
- 确保发件邮箱已启用 SMTP 服务。
- 运行代码后,检查收件箱是否收到邮件以及附件。
总结
通过 MIMEMultipart
添加正文和附件,可以轻松实现带附件的邮件发送功能。代码扩展性强,可以支持多个附件或复杂邮件内容。如果有更复杂需求,请进一步说明,我会提供更具体的解决方案!
如果发送的附件显示为二进制文件而不是原始的 PDF 文件,通常是由于以下原因之一:
1. MIME 类型未正确设置
当附加文件时,需要正确设置文件的 MIME 类型。如果未指定 MIME 类型,附件可能被处理为普通二进制文件。
解决方法:
- 为 PDF 文件指定 MIME 类型为
application/pdf
。
修改代码
from email.mime.base import MIMEBase
from email.mime.application import MIMEApplication
with open(attachment_path, "rb") as attachment:
part = MIMEApplication(attachment.read(), Name=attachment_path.split("/")[-1])
part.add_header(
"Content-Disposition",
f"attachment; filename={attachment_path.split('/')[-1]}"
)
message.attach(part)
2. 未正确编码附件
为了确保附件在传输中不会被破坏,必须对附件内容进行 Base64 编码。
确保编码步骤正确
from email import encoders
with open(attachment_path, "rb") as attachment:
part = MIMEBase("application", "pdf")
part.set_payload(attachment.read())
# 对附件进行 Base64 编码
encoders.encode_base64(part)
part.add_header(
"Content-Disposition",
f"attachment; filename={attachment_path.split('/')[-1]}"
)
message.attach(part)
3. 附件文件本身的问题
附件文件是否是一个有效的 PDF 文件。如果源文件已损坏或格式不正确,收件人可能无法正确解析。
解决方法:
- 检查本地文件是否能正常打开。
- 确保附件路径正确并且可以被程序读取。
4. 邮件客户端的问题
某些邮件客户端可能无法正确解析附件的 MIME 类型,即使发送代码无误。
解决方法:
- 尝试使用不同的邮件客户端查看附件。
- 在邮件头中明确声明 MIME 类型和文件名。
示例代码:完整解决方案
以下是发送 PDF 文件的完整代码:
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
def send_email_with_pdf(sender_email, sender_password, recipient_email, subject, body, attachment_path):
try:
# SMTP服务器配置
smtp_server = "smtp.gmail.com"
smtp_port = 587
# 创建邮件
message = MIMEMultipart()
message["From"] = sender_email
message["To"] = recipient_email
message["Subject"] = subject
# 添加正文
message.attach(MIMEText(body, "plain"))
# 添加附件
with open(attachment_path, "rb") as attachment:
part = MIMEApplication(attachment.read(), Name=attachment_path.split("/")[-1])
part.add_header(
"Content-Disposition",
f"attachment; filename={attachment_path.split('/')[-1]}"
)
message.attach(part)
# 发送邮件
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(sender_email, sender_password)
server.sendmail(sender_email, recipient_email, message.as_string())
print("Email with PDF attachment sent successfully!")
except Exception as e:
print(f"Failed to send email: {e}")
# 示例调用
if __name__ == "__main__":
send_email_with_pdf(
sender_email="your_email@example.com",
sender_password="your_password",
recipient_email="recipient@example.com",
subject="Test Email with PDF Attachment",
body="This is a test email with a PDF attachment.",
attachment_path="/path/to/your/file.pdf"
)
验证邮件内容
-
检查邮件头
- 打开邮件的原始内容(通常可以在邮件客户端中查看“原始邮件”),确保附件的 MIME 类型和文件名正确。
正确的 MIME 应该类似于:
Content-Type: application/pdf; name="file.pdf" Content-Disposition: attachment; filename="file.pdf" Content-Transfer-Encoding: base64
-
测试文件
- 确保
/path/to/your/file.pdf
是一个有效的 PDF 文件,可以在本地打开。
- 确保
总结
- 问题原因:通常是 MIME 类型未正确设置或未对附件进行 Base64 编码。
- 解决方法:
- 确保 MIME 类型为
application/pdf
。 - 使用
encoders.encode_base64
对附件进行编码。
- 确保 MIME 类型为
- 完整解决方案:参考上述示例代码。
原文地址:https://blog.csdn.net/lycwhu/article/details/145167595
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!