全部产品
云市场
云游戏

收发邮件

更新时间:2020-02-28 11:10:48

应用场景

在编写RPA流程时,我们经常需要在流程中收发邮件,而最常用的收发邮件方式是使用SMTP和POP3,下面我们来说明一下如何在RPA中收发邮件。

发送邮件

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。
python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。
Python创建 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 即可。

Python SMTP 对象使用 sendmail 方法发送邮件,语法如下:

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

参数说明:

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

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

示例


使用脚本发送邮件的思路其实和客户端发送邮件一样,过程都是:登录 —> 写邮件 —> 发送
只不过通过脚本发送时我们需要考虑到整个过程的方方面面。以下为思路导图:
发送邮件流程

发送简单邮件

基本思路是:

  1. 设置好服务器端信息
  2. 邮件主体信息
  3. 登录发送

另外在发送简单文本邮件时,我们需要使用 MIMEText 类作为邮件主体。

  1. from rpa.core import *
  2. from rpa.utils import *
  3. import rpa3 as rpa # 使用V3引擎
  4. import smtplib
  5. from email.mime.text import MIMEText
  6. def start():
  7. # 设置登录及服务器信息
  8. # 邮箱服务器地址
  9. mail_host = 'smtp.xxxx.com'
  10. # 邮件用户名,这里我们推荐使用RPA的云变量(资产变量)存储敏感信息
  11. mail_user = rpa.asset.value("mail_user")
  12. # 密码(部分邮箱为授权码) ,这里我们推荐使用RPA的云变量(资产变量)存储敏感信息
  13. mail_password = rpa.asset.value("mail_password")
  14. # 邮件发送方邮箱地址
  15. sender = 'xxxx@xxxx.com'
  16. # 邮件接受方邮箱地址,注意这里是一个列表<list>,这意味着你可以写多个邮件地址群发
  17. receivers = ['xxxx@xxxx.com']
  18. # 设置email信息
  19. # 邮件内容设置
  20. message = MIMEText('使用RPA测试邮件发送','plain','utf-8')
  21. # 邮件主题
  22. message['Subject'] = '邮件测试'
  23. # 发送方信息
  24. message['From'] = sender
  25. # 接受方信息
  26. message['To'] = receivers[0]
  27. # 登录并发送邮件
  28. try:
  29. smtpObj = smtplib.SMTP_SSL()
  30. # 连接到服务器
  31. smtpObj.connect(mail_host, 465)
  32. # 登录到服务器
  33. smtpObj.login(mail_user, mail_password)
  34. # 发送
  35. smtpObj.sendmail(
  36. sender, receivers, message.as_string())
  37. # 退出
  38. smtpObj.quit()
  39. print('success')
  40. except smtplib.SMTPException as e:
  41. print('error',e) # 打印错误

一些邮箱登录比如阿里企业邮箱、QQ 邮箱需要 SSL 认证,所以 SMTP 已经不能满足要求,而需要SMTP_SSL,解决办法为:

  1. smtpObj = smtplib.SMTP()
  2. smtpObj.connect(mail_host, 25)
  3. #######替换为########
  4. smtpObj = smtplib.SMTP_SSL()
  5. smtpObj.connect(mail_host, 465) # 注意要修改端口号

常用邮箱端口说明:

邮箱 SMTP服务器 SSL协议端口 非SSL协议端口
163 smtp.163.com 465或者994 25
qq smtp.qq.com 465或587 25

发送带有附件的邮件

基本思路就是,使用MIMEMultipart来标示这个邮件是多个部分组成的,然后attach各个部分。如果是附件,则add_header加入附件的声明。
在python中,MIME的这些对象的继承关系如下。
MIMEBase
|— MIMENonMultipart
|— MIMEApplication
|— MIMEAudio
|— MIMEImage
|— MIMEMessage
|— MIMEText
|— MIMEMultipart
一般来说,不会用到MIMEBase,而是直接使用它的继承类。MIMEMultipart有attach方法,而MIMENonMultipart没有,只能被attach。MIME有很多种类型,这个略麻烦,如果附件是图片格式,我要用MIMEImage,如果是音频,要用MIMEAudio,如果遇到word、excel等我们不确定该用哪种MIME类型时,可以不管什么类型的附件,都用MIMEApplication,MIMEApplication默认子类型是application/octet-stream。
application/octet-stream表明“这是个二进制的文件,希望对端那边知道怎么处理”,然后客户端,比如阿里企业邮箱,收到这个声明后,会根据文件扩展名来猜测。

  1. from rpa.core import *
  2. from rpa.utils import *
  3. import rpa3 as rpa # 使用V3引擎
  4. import smtplib
  5. from email.mime.text import MIMEText
  6. from email.mime.multipart import MIMEMultipart
  7. from email.mime.image import MIMEImage
  8. from email.mime.application import MIMEApplication
  9. def start():
  10. # 设置登录及服务器信息
  11. # 邮箱服务器地址
  12. mail_host = 'smtp.xxxx.com'
  13. # 邮件用户名,这里我们推荐使用RPA的云变量(资产变量)存储敏感信息
  14. mail_user = rpa.asset.value("mail_user")
  15. # 密码(部分邮箱为授权码) ,这里我们推荐使用RPA的云变量(资产变量)存储敏感信息
  16. mail_password = rpa.asset.value("mail_password")
  17. # 邮件发送方邮箱地址
  18. sender = 'xxxx@xxxx.com'
  19. # 邮件接受方邮箱地址,注意这里是一个列表<list>,这意味着你可以写多个邮件地址群发
  20. receivers = ['xxxx@xxxx.com']
  21. # 设置eamil信息
  22. # 添加一个MIMEmultipart类,处理正文及附件
  23. message = MIMEMultipart()
  24. message['From'] = sender
  25. message['To'] = receivers[0]
  26. message['Subject'] = '邮件测试'
  27. # ---这是文字部分---
  28. # 推荐使用html格式的正文内容,这样比较灵活,可以附加图片地址,调整格式等
  29. with open(r'C:\temp\测试HTML.html','rb') as hf:
  30. html_content = hf.read()
  31. # 设置html格式参数
  32. html_part = MIMEText(html_content,'html','utf-8')
  33. message.attach(html_part)
  34. # ---这是附件部分---
  35. # 添加一个txt文本附件
  36. with open(r'C:\temp\测试文本.txt','rb') as tf:
  37. txt_content = tf.read()
  38. txt_part = MIMEApplication(txt_content)
  39. txt_part.add_header('Content-Disposition', 'attachment', filename="测试.txt")
  40. message.attach(txt_part)
  41. # 添加一个xlsx类型附件
  42. with open(r'C:\temp\测试Excel.xlsx','rb') as ef:
  43. excle_content = ef.read()
  44. excle_part = MIMEApplication(excle_content)
  45. excle_part.add_header('Content-Disposition', 'attachment', filename="测试Excel.xlsx")
  46. message.attach(excle_part)
  47. # 添加一个docx类型附件
  48. with open(r'C:\temp\测试word.docx','rb') as df:
  49. word_content = df.read()
  50. word_part = MIMEApplication(word_content)
  51. word_part.add_header('Content-Disposition', 'attachment', filename="测试word.docx")
  52. message.attach(word_part)
  53. # 添加一个pdf类型附件
  54. with open(r'C:\temp\测试PDF.pdf','rb') as pf:
  55. pdf_content = pf.read()
  56. pdf_part = MIMEApplication(pdf_content)
  57. pdf_part.add_header('Content-Disposition', 'attachment', filename="测试PDF.pdf")
  58. message.attach(pdf_part)
  59. # 添加一个png类型附件
  60. with open(r'C:\temp\测试图片.png','rb') as gf:
  61. png_content = gf.read()
  62. png_part = MIMEApplication(png_content)
  63. png_part.add_header('Content-Disposition', 'attachment', filename="测试图片.png")
  64. message.attach(png_part)
  65. # 登录并发送
  66. try:
  67. smtpObj = smtplib.SMTP_SSL()
  68. # 连接到服务器
  69. smtpObj.connect(mail_host, 465)
  70. # 登录到服务器
  71. smtpObj.login(mail_user, mail_password)
  72. # 发送
  73. smtpObj.sendmail(
  74. sender, receivers, message.as_string())
  75. # 退出
  76. smtpObj.quit()
  77. print('success')
  78. except smtplib.SMTPException as e:
  79. print('error',e)

接收Email

POP3和IMAP
POP是指邮局协议,目的是让用户可以访问邮箱服务器中的邮件,允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收电子邮件的。
后来又出现了IMAP协议(Interactive Mail Access Protocol),即交互式邮件访问协议,与POP3的不同在于:开启了IMAP后,在电子邮件客户端收取的邮件仍然保留在服务器上,同时在客户端上的操作都会反馈到服务器上,如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作

使用POP3

python的poplib模块支持POP3,基本步骤:

  1. 连接到服务器
  2. 登录
  3. 发出服务请求
  4. 退出

poplib的常用方法:

方法 描述
POP3(server) 实例化POP3对象,server是pop服务器地址
user(username) 发送用户名到服务器,等待服务器返回信息
pass_(password) 密码
stat() 返回邮箱的状态,返回2元祖(消息的数量,消息的总字节)
list([msgnum]) stat()的扩展,返回一个3元祖(返回信息, 消息列表, 消息的大小),如果指定msgnum,就只返回指定消息的数据
retr(msgnum) 获取详细msgnum,设置为已读,返回3元组(返回信息, 消息msgnum的所以内容, 消息的字节数),如果指定msgnum,就只返回指定消息的数据
dele(msgnum) 将指定消息标记为删除
quit() 登出,保存修改,解锁邮箱,结束连接,退出
  1. from poplib import POP3
  2. p = POP3('pop.xxxx.com')
  3. p.user('xxxx@xxxx.com')
  4. p.pass_('xxxxxxxx')
  5. p.stat()
  6. ...
  7. p.quit()

使用IMAP

python中的imaplib包支持IMAP4
常用方法:

方法 描述
IMAP4(server) 与IMAP服务器建立连接
login(user, pass) 用户密码登录
list() 查看所有的文件夹(IMAP可以支持创建文件夹)
select() 选择文件夹默认是”INBOX”
search() 三个参数,第一的是CHARSET,通常为None(ASCII),第二个参数不知到是干什么官方没解释

Example IMAOP4接收

  1. import getpass, imaplib
  2. M = imaplib.IMAP4()
  3. M.login(getpass.getuser(), getpass.getpass())
  4. M.select()
  5. typ, data = M.search(None, 'ALL')
  6. for num in data[0].split():
  7. typ, data = M.fetch(num, '(RFC822)')
  8. print('Message %s\n%s\n' % (num, data[0][1]))
  9. M.close()
  10. M.logout()

相关连接