一封电子邮件的旅程是:

  • MUA:Mail User Agent——邮件用户代理。(即类似Outlook的电子邮件软件)
  • MTA:Mail Transfer Agent——邮件传输代理,就是那些Email服务提供商,比如网易、新浪等等。
  • MDA:Mail Delivery Agent——邮件投递代理。Email服务提供商的某个服务器

发件人 -> MUA -> MTA -> MTA -> 若干个MTA -> MDA <- MUA <- 收件人

要编写程序来发送和接收邮件,本质上就是:

  1. 编写MUA把邮件发到MTA;
  2. 编写MUA从MDA上收邮件。

发邮件时,MUA和MTA使用的协议就是SMTP:Simple Mail Transfer Protocol,后面的MTA到另一个MTA也是用SMTP协议。

收邮件时,MUA和MDA使用的协议有两种:POP:Post Office Protocol,目前版本是3,俗称POP3;IMAP:Internet Message Access Protocol,目前版本是4,优点是不但能取邮件,还可以直接操作MDA上存储的邮件,比如从收件箱移到垃圾箱,等等。

一、SMTP(Simple Mail Transfer Protocol)

即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。

python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。

Python对SMTP支持有smtplibemail两个模块,email负责构造邮件,smtplib负责发送邮件。

1、构造邮件:email.mime类型

构造一个邮件对象就是一个Messag对象,如果构造一个MIMEText对象,就表示一个文本邮件对象,如果构造一个MIMEImage对象,就表示一个作为附件的图片,要把多个对象组合起来,就用MIMEMultipart对象,而MIMEBase可以表示任何对象。它们的继承关系如下:

  1. Message
  2. +- MIMEBase
  3. +- MIMEMultipart
  4. +- MIMENonMultipart
  5. +- MIMEMessage
  6. +- MIMEText
  7. +- MIMEImage

首先,我们来构造一个最简单的纯文本邮件,然后,通过SMTP发出去。

  1. from email.mime.text import MIMEText
  2. msg = MIMEText('hello, send by Python...', 'plain', 'utf-8')

注意到构造MIMEText对象时,第一个参数就是邮件正文,第二个参数是MIME的subtype,传入'plain',最终的MIME就是'text/plain',最后一定要用utf-8编码保证多语言兼容性。

2、创建 SMTP 对象

语法如下:

  1. import smtplib
  2. smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )

参数说明:

  • host: SMTP 服务器主机。 你可以指定主机的ip地址或者域名如: runoob.com,这个是可选参数。

  • port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下 SMTP 端口号为25。
  • local_hostname: 如果 SMTP 在你的本机上,你只需要指定服务器地址为 localhost 即可。

3、Python SMTP 对象使用 sendmail 方法发送邮件

语法如下:

  1. SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])

参数说明:

  • from_addr: 邮件发送者地址。

  • to_addrs: 字符串列表,邮件发送地址。
  • msg: 发送消息

这里要注意一下第三个参数,msg 是字符串,表示邮件。我们知道邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意 msg 的格式。这个格式就是 smtp 协议中定义的格式。

二、实例

2:本机已安装支持 SMTP 的服务

以下执行实例需要你本机已安装了支持 SMTP 的服务。

sendmail()方法就是发邮件,由于可以一次发给多个人,所以传入一个list,邮件正文是一个stras_string()MIMEText对象变成str

经过Header对象编码的文本,包含utf-8编码信息和Base64编码的文本。

以下是一个使用 Python 发送邮件简单的实例:

  1. import smtplib
  2. from email.mime.text import MIMEText
  3. from email.header import Header
  4.  
  5. sender = 'from@runoob.com'
  6. receivers = ['429240967@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
  7.  
  8. # 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
  9. message = MIMEText('Python 邮件发送测试内容...', 'plain', 'utf-8')
  10. message['From'] = Header("菜鸟教程", 'utf-8') # 发送者
  11. message['To'] = Header("测试", 'utf-8') # 接收者
  12. message['Subject'] = Header('Python SMTP 邮件测试主题', 'utf-8')
  13.  
  14. try:
  15. smtpObj = smtplib.SMTP('localhost')
  16. smtpObj.sendmail(sender, receivers, message.as_string())
  17. print "邮件发送成功"
  18. except smtplib.SMTPException:
  19. print "Error: 无法发送邮件"

2、使用第三方 SMTP 服务

如果我们本机没有 sendmail 访问,也可以使用其他邮件服务商的 SMTP 访问(QQ、网易、Google等)。

login()方法用来登录SMTP服务器

发收件件人的名字没有显示为友好的名字,比如Mr Green <green@example.com>

使用 formataddr方法来格式化一个邮件地址。如果包含中文,需要通过Header对象进行编码。

msg['To']接收的是字符串而不是list,如果有多个邮件地址,用,分隔即可。

  1. import smtplib
  2. from email.mime.text import MIMEText
  3. from email.utils import formataddr
  4.  
  5. # 第三方 SMTP 服务
  6. mail_host = "mail.sss.com" # 设置服务器
  7. mail_user = "it_system@sss.com" # 用户名
  8. mail_pass = "Ssss201709#" # 口令
  9.  
  10. sender = 'it_system@tcl.com'
  11. receivers = 'sss.yang@tcsssl.com' # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
  12.  
  13. message = MIMEText('Python 邮件内容测试...', 'plain', 'utf-8')
  14. message['From'] = formataddr(('SCBC-啊iT', sender))
  15. message['To'] = formataddr(('杨生', receivers))
  16. message['Subject'] = 'Python SMTP 邮件测试'
  17.  
  18. try:
  19. smtpObj = smtplib.SMTP()
  20. smtpObj.connect(mail_host, 25) # 25 为 SMTP 端口号
  21. smtpObj.login(mail_user, mail_pass)
  22. smtpObj.sendmail(sender, receivers, message.as_string())
  23. print("邮件发送成功")
  24. except smtplib.SMTPException:
  25. print("Error: 无法发送邮件")

3、使用Python发送HTML格式的邮件

Python在构造MIMEText对象时,把HTML字符串传进去,再把第二个参数由plain变为html就可以了:

具体代码如下:

  1. mail_msg = """
  2. <p>Python 邮件内容测试...</p>
  3. <p><a href="http://www.baidu.com">这是一个链接</a></p>
  4. """
  5. message = MIMEText(mail_msg, 'html', 'utf-8')

4、Python 发送带附件的邮件

带附件的邮件可以看做包含若干部分的邮件:文本和各个附件本身,所以,可以构造一个MIMEMultipart对象代表邮件本身,然后往里面加上一个MIMEText作为邮件正文,再继续往里面加上表示附件的MIMEBase对象即可。

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

  1. from email.mime.multipart import MIMEMultipart
  2.  
  3. # 创建一个带附件的实例
  4. message = MIMEMultipart()
  5.  
  6. message['From'] = formataddr(('SCBC-啊iT', sender))
  7. message['To'] = formataddr(('杨生', receivers))
  8. message['Subject'] = 'Python SMTP 邮件测试'
  9.  
  10. mail_msg = """
  11. <p>Python 邮件内容测试...</p>
  12. <p><a href="http://www.baidu.com">这是一个链接</a></p>
  13. """
  14. # 邮件正文内容
  15. message.attach(MIMEText(mail_msg, 'html', 'utf-8'))
  16.  
  17. # 构造附件1,传送当前目录下的 test.txt 文件
  18. att = MIMEText(open('32.txt', 'rb').read(), 'base64', 'utf-8')
  19. att["Content-Type"] = 'application/octet-stream'
  20. # 这里的filename可以任意写,写什么名字,邮件中显示什么名字
  21. att["Content-Disposition"] = 'attachment; filename="32.txt"'
  22. message.attach(att)

5、在 HTML 文本中添加图片

要把图片嵌入到邮件正文中,我们只需按照发送附件的方式,先把邮件作为附件添加进去,然后,在HTML中通过引用src="cid:0"就可以把附件作为图片嵌入了。如果有多个图片,给它们依次编号,然后引用不同的cid:x即可。

邮件的 HTML 文本中一般邮件服务商添加外链是无效的,正确添加图片的实例如下所示:

  1. from email.mime.multipart import MIMEMultipart
  2. from email.mime.image import MIMEImage
  3.  
  4. # 创建一个带附件的实例
  5. message = MIMEMultipart()
  6.  
  7. message['From'] = formataddr(('SCBC-啊iT', sender))
  8. message['To'] = formataddr(('杨生', receivers))
  9. message['Subject'] = 'Python SMTP 邮件测试'
  10.  
  11. mail_msg = """
  12. <p>Python 邮件内容测试...</p>
  13. <p><a href="http://www.baidu.com">这是一个链接</a></p>
  14. <p>图片演示:</p>
  15. <p><img src="cid:image1"></p>
  16. """
  17. # 邮件正文内容
  18. message.attach(MIMEText(mail_msg, 'html', 'utf-8'))
  19.  
  20. # 指定图片为当前目录
  21. with open('a.jpg', 'rb') as fp:
  22. msgImage = MIMEImage(fp.read())
  23.  
  24. # 定义图片 ID,在 HTML 文本中引用
  25. msgImage.add_header('Content-ID', '<image1>')
  26. message.attach(msgImage)

或者通过MIMEBase来添加图片

  1. # 指定图片为当前目录
  2. with open('a.jpg', 'rb') as fp:
  3. # 设置附件的MIME和文件名,这里是png类型:
  4. mime = MIMEBase('image', 'jpg', filename='a.jpg')
  5. # 加上必要的头信息:
  6. mime.add_header('Content-Disposition', 'attachment', filename='附件显示名称.jpg')
  7. mime.add_header('Content-ID', '<image1>') # 如果有多个文件需要使用.format(index)
  8. mime.add_header('X-Attachment-Id', '0') # 如果有多个文件需要使用.format(index)
  9. # 把附件的内容读进来:
  10. mime.set_payload(fp.read())
  11. # 用Base64编码:
  12. encoders.encode_base64(mime)
  13. # 添加到MIMEMultipart:
  14. message.attach(mime)

6、同时支持HTML和Plain格式

如果我们发送HTML邮件,收件人通过浏览器或者Outlook之类的软件是可以正常浏览邮件内容的,但是,如果收件人使用的设备太古老,查看不了HTML邮件怎么办?

办法是在发送HTML的同时再附加一个纯文本,如果收件人无法查看HTML格式的邮件,就可以自动降级查看纯文本邮件。

利用MIMEMultipart就可以组合一个HTML和Plain,要注意指定subtype是alternative

  1. msg = MIMEMultipart('alternative')
  2. msg['From'] = ...
  3. msg['To'] = ...
  4. msg['Subject'] = ...
  5.  
  6. msg.attach(MIMEText('hello', 'plain', 'utf-8'))
  7. msg.attach(MIMEText('<html><body><h1>Hello</h1></body></html>', 'html', 'utf-8'))
  8. # 正常发送msg对象...

7、加密SMTP

使用标准的25端口连接SMTP服务器时,使用的是明文传输,发送邮件的整个过程可能会被窃听。要更安全地发送邮件,可以加密SMTP会话,实际上就是先创建SSL安全连接,然后再使用SMTP协议发送邮件。

某些邮件服务商,例如Gmail,提供的SMTP服务必须要加密传输。我们来看看如何通过Gmail提供的安全SMTP发送邮件。

只需要在创建SMTP对象后,立刻调用starttls()方法,就创建了安全连接。后面的代码和前面的发送邮件代码完全一样。

必须知道,Gmail的SMTP端口是587,因此,修改代码如下:

  1. smtp_server = 'smtp.gmail.com'
  2. smtp_port = 587
  3. server = smtplib.SMTP(smtp_server, smtp_port)
  4. server.starttls()
  5. # 剩下的代码和前面的一模一样:
  6. server.set_debuglevel(1)

三、使用poplib接收邮件

收取邮件就是编写一个MUA作为客户端,从MDA把邮件获取到用户的电脑或者手机上。收取邮件最常用的协议是POP协议,目前版本号是3,俗称POP3

Python内置一个poplib模块,实现了POP3协议,可以直接用来收邮件。

POP3 的命令和响应数据都是基于 ASCII 文本的,并以 CR 和 LF(/r/n) 作为行结束符,响应数据包括一个表示返回状态的符号(+/)和描述信息。

请求和响应的标准格式如下:

请求标准格式:命令 [参数] CRLF
响应标准格式:+OK /[-ERR] description CRLF

POP3 协议客户端的命令和服务器端对应的响应数据如下:

  • user name:向 POP 服务器发送登录的用户名。

  • pass string:向 POP 服务器发送登录的密码。
  • quit:退出 POP 服务器。
  • stat:统计邮件服务器状态,包括邮件数和总大小。
  • list [msg_no]:列出全部邮件或指定邮件。返回邮件编号和对应大小。
  • retr msg_no:获取指定邮件的内容(根据邮件编号来获取,编号从 1 开始)。
  • dele msg_no:删除指定邮件(根据邮件编号来删除,编号从 1 开始)。
  • noop:空操作。仅用于与服务器保持连接。
  • rset:用于撤销 dele 命令。

poplib 模块完全模拟了上面命令,poplib.POP3 或 poplib.POP3_SSL 为上面命令提供了相应的方法,开发者只要依次使用上面命令即可从服务器端下载对应的邮件

注意到POP3协议收取的不是一个已经可以阅读的邮件本身,而是邮件的原始文本,这和SMTP协议很像,SMTP发送的也是经过编码后的一大段文本。

要把POP3收取的文本变成可以阅读的邮件,还需要用email模块提供的各种类来解析原始文本,变成可阅读的邮件对象。

所以,收取邮件分两步:

第一步:使用poplib.POP3 或 poplib.POP3_SSL 按 POP3 协议把邮件的原始文本下载到本地;

用POP3获取邮件其实很简单,要获取所有邮件,只需要循环使用retr()把每一封邮件内容拿到即可。真正麻烦的是把邮件的原始内容解析为可以阅读的邮件对象。

  1. import poplib
  2. from email.parser import Parser
  3. # email.parser 解析电子邮件,返回这个对象的email.message.Message实例
  4. from email.header import decode_header
  5. from email.utils import parseaddr
  6.  
  7. # 服务器及用户信息
  8. host = 'mail.tcl.com'
  9. username = 'bobin.yang@tcl.com'
  10. password = 'Ybb7654321'
  11.  
  12. # 连接到POP3服务器
  13. conn = poplib.POP3_SSL(host)
  14. # 注意qq邮箱使用SSL连接
  15. # 设置调试模式,可以看到与服务器的交互信息
  16. conn.set_debuglevel(1)
  17.  
  18. # 打印POP3服务器的欢迎文字
  19. print(conn.getwelcome().decode("utf-8"))
  20.  
  21. # 身份认证
  22. conn.user(username)
  23. conn.pass_(password)
  24.  
  25. # 获取服务器上信件信息,返回一个列表,第一项是一共有多少封邮件,第二项是共有多少字节
  26. # stat()返回邮件数量和占用空间
  27. mail_total, total_size = conn.stat()
  28. print('message: %s.Size:%s' % (mail_total, total_size))
  29.  
  30. # list()返回(response, ['mesg_num octets', ...], octets),第二项是编号
  31. resp, mails, octets = conn.list()
  32. print(mails)
  33. # 返回的列表类似[b'1 82923', b'2 2184', ...]
  34.  
  35. # 获取最新一封邮件,注意索引号从1开始
  36. # POP3.retr(which) 检索序号which的这个邮件,然后设置他的出现标志 返回(response, ['line', ...], octets)这个三元组
  37. resp, lines, ocetes = conn.retr(len(mails))
  38. print('lines:', len(lines))
  39. # lines 存储了邮件的原始文本的每一行
  40. # 可以获得整个邮件的原始文本
  41. print("-------------------")

第二部:使用 email.parser.Parser或BytesParser 解析邮件内容为消息对象,然后,用适当的形式把邮件内容展示给用户即可。

解析邮件的过程和上一节构造邮件正好相反。

程序在创建 BytesParser(解析字节串格式的邮件数据)或 Parser(解析字符串格式的邮件数据)时,必须指定 policy=default;否则,BytesParse 或 Parser 解析邮件数据得到的就是过时的 Message 对象,,不是新的 EmailMessage,处理起来非常不方便。

1、使用 email.parser.Parser解析邮件内容为 email.message.Message(过时,不推荐)

  1. msg = b'\r\n'.join(lines).decode('utf-8')
  2. # 解析出邮件
  3. msg = Parser().parsestr(msg)
  4.  
  5. # email.Parser.parsestr(text, headersonly=False)
  6. # 与parser()方法类似,不同的是他接受一个字符串对象而不是一个类似文件的对象
  7. # 可选的headersonly表示是否在解析玩标题后停止解析,默认为否
  8. # 返回根消息对象
  9.  
  10. # 编码处理,文本邮件的内容也是str,还需要检测编码,否则,非UTF-8编码的邮件都无法正常显示
  11. def guess_charset(msg):
  12. charset = msg.get_charset() # 从msg对象获取编码
  13. if charset is None:
  14. content_type = msg.get('Content-Type', '').lower() # 如果获取不到,再从content—type字段获取
  15. if 'charset' in content_type:
  16. charset = content_type.split('charset=')[1].strip()
  17. return charset
  18. return charset
  19.  
  20. # 数据解码,邮件的Subject或者Email中包含的名字都是经过编码后的str,要正常显示,就必须decode
  21. def decode_str(s):
  22. value, charset = decode_header(s)[0] # 数据,数据编码方式,from email.header import decode_header
  23. # decode_header()返回一个list,因为像Cc、Bcc这样的字段可能包含多个邮件地址,所以解析出来的会有多个元素。上面的代码我们偷了个懒,只取了第一个元素。
  24. if charset:
  25. value = value.decode(charset)
  26. return value
  27.  
  28. # print_ingo函数:解析邮件与构造邮件的步骤正好相反
  29. def print_info(msg, indent=0): # indent用于缩进显示
  30. if indent == 0:
  31. for header in ['From', 'To', 'Subject']: # 邮件的from、to、subject存在于根对象上
  32. value = msg.get(header, '')
  33. if value:
  34. if header == 'Subject':
  35. value = decode_str(value) # 需要解码subject字符串
  36. else:
  37. # 解码mail地址
  38. hdr, addr = parseaddr(value)
  39. name = decode_str(hdr)
  40. value = '%s' % addr
  41. print('%s: %s %s' % (header, value, name))
  42. print('-*-' * 20)
  43. if msg.is_multipart():
  44. # 如果邮件对象是一个is_multipart,get_payload()返回一个list,包含所有子对象
  45. parts = msg.get_payload() # 循环获得列表项
  46. for n, part in enumerate(parts):
  47. # print('%spart %s' % (' ' * indent, n))
  48. # print('%s------------' % (' ' * indent))
  49. # 递归打印没一个子对象
  50. print_info(part, indent + 1)
  51. else:
  52. # 邮件对象不是一个is_multipart,就根据content_type判断
  53. content_type = msg.get_content_type() # 数据类型
  54. if content_type == 'text/plain' or content_type == 'text/html': # 纯文本 html文本
  55. # 纯文本或html内容
  56. content = msg.get_payload(decode=True) # 获得文本对象的字符串而非对象本身
  57. charset = guess_charset(msg) # 要检测文本编码
  58. if charset: content = content.decode(charset)
  59. content = '%s' % (content)
  60. print(content) # 获取邮件文本内容,如果只有文本,打印显示的结果和邮件中看的效果一模一样
  61. else:
  62. print(content_type+'不是文本')
  63.  
  64. print_info(msg, 0)
  65.  
  66. # 退出
  67. conn.quit()

2、使用email.parser.BytesParser 解析成email.message.EmailMessage对象

如果程序要获取邮件的发件人、收件人和主题,直接通过 EmailMessage 的相应属性来获取即可,与前面为 EmailMessage 设置发件人、收件人和主题的方式是对应的。
如果程序要读取 EmailMessage 的各部分,则需要调用该对象的 walk() 方法,该方法返回一个可迭代对象,程序使用 for 循环遍历 walk() 方法的返回值,对邮件内容进行逐项处理:

  • 如果邮件某项的 maintype 是 'multipart',则说明这一项是容器,用于包含邮件内容、附件等其他项。

  • 如果邮件某项的 maintype 是 'text',则说明这一项的内容是文本,通常就是邮件正文或文本附件。对于这种文本内容,程序直接将其输出到控制台中。
  • 如果邮件某项的 maintype 是其他,则说明这一项的内容是附件,程序将附件内容保存在本地文件中。
  1. import os
    import poplib
    import mimetypes
    from email.parser import Parser, BytesParser
    from email.policy import default

  1. msg_data = b'\r\n'.join(lines)
  2. # 将字符串内容解析成邮件,此处一定要指定policy=default
  3. msg = BytesParser(policy=default).parsebytes(msg_data)
  4. print(type(msg))
  5.  
  6. print('发件人:' + msg['from'])
  7. print('收件人:' + msg['to'])
  8. print('主题:' + msg['subject'])
  9. print('第一个收件人名字:' + msg['to'].addresses[0].username)
  10. print('第一个发件人名字:' + msg['from'].addresses[0].username)
  11. for part in msg.walk():
  12. counter = 1
  13. # 如果maintype是multipart,说明是容器(用于包含正文、附件等)
  14. if part.get_content_maintype() == 'multipart':
  15. continue
  16. # 如果maintype是multipart,说明是邮件正文部分
  17. elif part.get_content_maintype() == 'text':
  18. print(part.get_content())
  19. # 处理附件
  20. else:
  21. # 获取附件的文件名
  22. filename = part.get_filename()
  23. # 如果没有文件名,程序要负责为附件生成文件名
  24. if not filename:
  25. # 根据附件的contnet_type来推测它的后缀名
  26. ext = mimetypes.guess_extension(part.get_content_type())
  27. # 如果推测不出后缀名
  28. if not ext:
  29. # 使用.bin作为后缀名
  30. ext = '.bin'
  31. # 程序为附件来生成文件名
  32. filename = 'part-%03d%s' % (counter, ext)
  33. counter += 1
  34. # 将附件写入的本地文件
  35. with open(os.path.join('.', filename), 'wb') as fp:
  36. fp.write(part.get_payload(decode=True))
  37. # 退出服务器,相当于发送POP 3的quit命令
  38. conn.quit()

python的email、smtplib、poplib模块收发邮件的更多相关文章

  1. 使用python的email、smtplib、poplib模块收发邮件

    使用python的email.smtplib.poplib模块收发邮件 一封电子邮件的旅程是: MUA:Mail User Agent——邮件用户代理.(即类似Outlook的电子邮件软件) MTA: ...

  2. python基础:用yagmail模块发邮件

    一.yagmail模块安装 网上下载的yagmail模块安装以后,在使用过程中,如果附件有中文,会显示乱码. pip install yagmail-0.10.212-py2.py3-none-any ...

  3. python之poplib模块下载并解析邮件

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python之poplib模块下载并解析邮件 #https://github.com/michaelliao ...

  4. Python模块探秘之smtplib,实现纯文本邮件的发送

    今天学到了如何使用Python的smtplib库发送邮件,中间也是遇到了各种各样的错误和困难,还好都一一的解决了.下面来谈一谈我的这段经历. 配置你的邮箱 为什么要配置邮箱呢?具体要配置什么呢? 因为 ...

  5. 利用Python imaplib和email模块 读取邮件文本内容及附件内容

    python使用imap接收邮件的过程探索 https://www.cnblogs.com/yhlx/archive/2013/03/22/2975817.html #! encoding:utf8 ...

  6. Python收发邮件

    发送邮件使用SMTP协议,接受POP3或IMAP: 创建邮件内容email模块,发送邮件smtplib模块.发送邮件比较简单,只需先创建SMTP对象,登录服务器后根据发收邮箱地址发送即可: POP3接 ...

  7. 使用python调用email模块发送邮件附件

    使用python调用email模块实现附件发送 需要模块: import datetime import time import sys import mimetypes import smtplib ...

  8. python:利用smtplib模块发送邮件

    自动化测试中,测试报告一般都需要发送给相关的人员,比较有效的一个方法是每次执行完测试用例后,将测试报告(HTML.截图.附件)通过邮件方式发送. 参考代码:send_mail.py 一.python对 ...

  9. 转--python -- 收发邮件

    官方 import smtplib from email.mime.text import MIMEText from email.header import Header # 发送邮箱服务器 smt ...

随机推荐

  1. Linux 就该这么学 CH06 存储结构与磁盘划分

    1.一切从"/"开始 linux系统中一切都是文件,而且一切文件的路径都是从根目录(/)开始的.系统中的根目录和文件名称都是严格区分大小写的,并且文件名中不能包含/符号. 绝对路径 ...

  2. LinkedHashMap源码

    TreeMap是一颗红黑树做Map.HashMap是数组+链表+红黑树.HashTable是数组+链表. LinkedHashMap底层存储结构与HashMap一样,不同的是LinkedHashMap ...

  3. python入门之数据类型及内置方法

    目录 一.题记 二.整形int 2.1 用途 2.2 定义方式 2.3 常用方法 2.3.1 进制之间的转换 2.3.2 数据类型转换 3 类型总结 三.浮点型float 3.1 用途 3.2 定义方 ...

  4. Springboot Actuator之十一:actuator transaction

    前言spring boot 的自动化配置其实就是在spring 的基础上做的封装,在我们之前对mvc,aop的自动化配置中可以发现–> 只是在spring 的基础上添加了一些特性,可以认为只是一 ...

  5. Disable foreign key checks during import

    The command SET FOREIGN_KEY_CHECKS=0; sets the value of a variable in a session scope. So it affects ...

  6. golang面对对象

  7. Qt元对象(Meta-Object)系统与反射

    反射 -在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问.检测和修改它本身状态或行为的一种能力.[1]用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为. 要注意 ...

  8. Flink基本的API

    Flink使用 DataSet 和 DataStream 代表数据集.DateSet 用于批处理,代表数据是有限的:而 DataStream 用于流数据,代表数据是无界的.数据集中的数据是不可以变的, ...

  9. Orleans 3.0 为我们带来了什么(转载)

    以下为本篇文章的 作者: 艾心 出处: https://www.cnblogs.com/edison0621/ 原文:https://devblogs.microsoft.com/dotnet/orl ...

  10. C# 实用代码段

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...