Python使用smtplib和email模块发送各类邮件详解

Jasper
Jasper
发布时间:2026-10-13| 5人浏览过
原创

本文详细介绍Python中利用smtplib和email模块发送邮件的方法。涵盖普通文本、HTML、带附件及图片邮件的实现代码。解析SMTP连接、登录验证及消息构造过程,提供Python 2.6环境下的完整示例,帮助开发者掌握邮件发送核心技巧。

Python内置的email模块大幅简化了邮件处理流程。本文重点梳理发送邮件的具体操作步骤,分享实践心得,并欢迎技术专家提供指导与建议。

一、相关模块介绍

发送邮件主要依赖smtplib和email两个核心模块,下文将对这两个模块进行简要概述。

1、smtplib模块

smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])

SMTP类构造函数用于建立与SMTP服务器的连接。通过该连接可向服务器发送指令,执行登录、发送邮件等操作。所有参数均为可选。

host:指定SMTP服务器的主机名。

port:指定SMTP服务的端口号,默认值为25。若在创建SMTP对象时提供了host和port参数,初始化阶段会自动调用connect方法连接服务器。

smtplib模块还包含SMTP_SSL类和LMTP类,其操作方式与SMTP类基本一致。

smtplib.SMTP提供的主要方法如下:

SMTP.set_debuglevel(level):用于设置调试模式。默认值为False(非调试模式),即不输出任何调试信息。

SMTP.connect([host[, port]]):连接指定的SMTP服务器。参数分别代表SMTP主机和端口。注意:也可以在host参数中直接指定端口号(例如:smtp.yeah.net:25),此时无需单独提供port参数。

SMTP.docmd(cmd[, argstring]):向SMTP服务器发送指令。可选参数argstring表示该指令所需的参数。

SMTP.helo([hostname]):使用“helo”指令向服务器确认身份,相当于告知SMTP服务器“我是谁”。

SMTP.has_extn(name):判断指定名称是否存在于服务器的邮件列表中。出于安全考虑,多数SMTP服务器已屏蔽此指令。

SMTP.verify(address):判断指定的邮件地址是否在服务器中存在。出于安全考虑,多数SMTP服务器已屏蔽此指令。

SMTP.login(user, password):登录到SMTP服务器。目前几乎所有SMTP服务器都要求先验证用户信息合法,之后才允许发送邮件。

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]):执行邮件发送。需注意第三个参数msg为字符串,代表邮件内容。邮件通常由标题、发件人、收件人、正文及附件等构成,发送时需确保msg符合SMTP协议定义的格式。

SMTP.quit():断开与SMTP服务器的连接,相当于发送“quit”指令。(注:许多程序中使用了smtp.close(),关于其与quit()的具体区别,经查阅资料暂未找到明确解释。)

2、email模块

email模块用于处理邮件消息,包括MIME及其他基于RFC 2822标准的消息文档。利用这些模块定义邮件内容十分简便。其包含的类有(更详细介绍可见:http://docs.python.org/library/email.mime.html):

class email.mime.base.MIMEBase(_maintype, _subtype, **_params):这是MIME的一个基类,通常无需在创建实例时手动调用。其中_maintype指内容类型(如text或image),_subtype指内容的次要类型(如plain或gif)。**_params是一个字典,直接传递给Message.add_header()。

class email.mime.multipart.MIMEMultipart([_subtype[, boundary[, _subparts[, _params]]]]):MIMEBase的一个子类,用于表示多个MIME对象的集合,_subtype默认值为mixed。boundary是MIMEMultipart的边界,默认边界为可数。

class email.mime.application.MIMEApplication(_data[, _subtype[, _encoder[, **_params]]]):MIMEMultipart的一个子类。

class email.mime.audio.MIMEAudio(_audiodata[, _subtype[, _encoder[, **_params]]]):MIME音频对象。

class email.mime.image.MIMEImage(_imagedata[, _subtype[, _encoder[, **_params]]]):MIME二进制文件对象。

class email.mime.message.MIMEMessage(_msg[, _subtype]):具体的一个message实例,使用方法如下:

msg=mail.Message.Message()  #一个实例 
msg['to']='XXX@XXX.com'   #发送到哪里 
msg['from']='YYY@YYYY.com'    #自己的邮件地址 
msg['date']='2012-3-16'      #时间日期 
msg['subject']='hello world'  #邮件主题 

class email.mime.text.MIMEText(_text[, _subtype[, _charset]]):MIME文本对象。其中_text为邮件内容,_subtype为邮件类型(可以是text/plain普通文本邮件,或html/plain HTML邮件),_charset为编码方式(如gb2312等)。

二、几种邮件的具体实现代码

1、普通文本邮件

发送普通文本邮件的关键在于将MIMEText中的_subtype设置为plain。首先需要导入smtplib和mimetext模块。创建smtplib.smtp实例,连接邮件SMTP服务器,登录成功后发送,具体代码如下:(基于Python 2.6实现)

# -*- coding: UTF-8 -*-
'''
发送txt文本邮件
'''
import smtplib 
from email.mime.text import MIMEText 
mailto_list=[YYY@YYY.com] 
mail_host="smtp.XXX.com" #设置服务器
mail_user="XXXX"  #用户名
mail_pass="XXXXXX"  #口令 
mail_postfix="XXX.com" #发件箱的后缀
 
def send_mail(to_list,sub,content): 
  me="hello"+"<"+mail_user+"@"+mail_postfix+">" 
  msg = MIMEText(content,_subtype='plain',_charset='gb2312') 
  msg['Subject'] = sub 
  msg['From'] = me 
  msg['To'] = ";".join(to_list) 
  try: 
    server = smtplib.SMTP() 
    server.connect(mail_host) 
    server.login(mail_user,mail_pass) 
    server.sendmail(me, to_list, msg.as_string()) 
    server.close() 
    return True 
  except Exception, e: 
    print str(e) 
    return False 
if __name__ == '__main__': 
  if send_mail(mailto_list,"hello","hello world!"): 
    print "发送成功" 
  else: 
    print "发送失败" 

2、html邮件的发送

与文本邮件的区别在于,将MIMEText中的_subtype设置为html。具体代码如下:(基于Python 2.6实现)

# -*- coding: utf-8 -*-
'''
发送html文本邮件
'''
import smtplib 
from email.mime.text import MIMEText 
mailto_list=["YYY@YYY.com"] 
mail_host="smtp.XXX.com" #设置服务器
mail_user="XXX"  #用户名
mail_pass="XXXX"  #口令 
mail_postfix="XXX.com" #发件箱的后缀
 
def send_mail(to_list,sub,content): #to_list:收件人;sub:主题;content:邮件内容
  me="hello"+"<"+mail_user+"@"+mail_postfix+">"  #这里的hello可以任意设置,收到信后,将按照设置显示
  msg = MIMEText(content,_subtype='html',_charset='gb2312')  #创建一个实例,这里设置为html格式邮件
  msg['Subject'] = sub  #设置主题
  msg['From'] = me 
  msg['To'] = ";".join(to_list) 
  try: 
    s = smtplib.SMTP() 
    s.connect(mail_host) #连接smtp服务器
    s.login(mail_user,mail_pass) #登陆服务器
    s.sendmail(me, to_list, msg.as_string()) #发送邮件
    s.close() 
    return True 
  except Exception, e: 
    print str(e) 
    return False 
if __name__ == '__main__': 
  if send_mail(mailto_list,"hello","<a href='http://www.cnblogs.com/xiaowuyi'>小五义</a>"): 
    print "发送成功" 
  else: 
    print "发送失败" 

3、发送带附件的邮件

发送带附件的邮件时,首先要创建MIMEMultipart()实例,然后构造附件。若有多个附件,可依次构造,最后利用smtplib.smtp进行发送。

# -*- coding: cp936 -*-
'''
发送带附件邮件
'''

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib

#创建一个带附件的实例
msg = MIMEMultipart()

#构造附件1
att1 = MIMEText(open('d:\\123.rar', 'rb').read(), 'base64', 'gb2312')
att1["Content-Type"] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="123.doc"'#这里的filename可以任意写,写什么名字,邮件中显示什么名字
msg.attach(att1)

#构造附件2
att2 = MIMEText(open('d:\\123.txt', 'rb').read(), 'base64', 'gb2312')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="123.txt"'
msg.attach(att2)

#加邮件头
msg['to'] = 'YYY@YYY.com'
msg['from'] = 'XXX@XXX.com'
msg['subject'] = 'hello world'
#发送邮件
try:
  server = smtplib.SMTP()
  server.connect('smtp.XXX.com')
  server.login('XXX','XXXXX')#XXX为用户名,XXXXX为密码
  server.sendmail(msg['from'], msg['to'],msg.as_string())
  server.quit()
  print '发送成功'
except Exception, e: 
  print str(e) 

4、利用MIMEimage发送图片

# -*- coding: cp936 -*-
import smtplib
import mimetypes
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage

def AutoSendMail():
  msg = MIMEMultipart()
  msg['From'] = "XXX@XXX.com"
  msg['To'] = "YYY@YYY.com"
  msg['Subject'] = "hello world"


  txt = MIMEText("这是中文的邮件内容哦",'plain','gb2312')   
  msg.attach(txt)
  

  file1 = "C:\\hello.jpg"
  image = MIMEImage(open(file1,'rb').read())
  image.add_header('Content-ID','<image1>')
  msg.attach(image)
  
  
  server = smtplib.SMTP()
  server.connect('smtp.XXX.com')
  server.login('XXX','XXXXXX')
  server.sendmail(msg['From'],msg['To'],msg.as_string())
  server.quit()
  
if __name__ == "__main__":
  AutoSendMail()

利用MIMEimage发送图片时,初衷是希望图片能在正文中直接显示。但代码运行后发现,图片仍以附件形式发送。此处希望有高手指点,如何实现在正文中显示图片(即图片作为附件存在,同时能在正文中展示),具体形式如下图。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。