一、 用python实现邮件发送
用程序实现邮件收发的三个角色:
MUA (mail user agent, 邮件用户代理)
MTA (mail transfer agent, 邮件传输代理)
MDA (mail delivery agent, 邮件投递代理)
发邮件:MUA → MTA【使用SMTP协议】
收邮件:MUA ← MDA 【使用POP3/IMAP4协议】
(一)用到的模块
【1. email】
(1) email.mime:
email.mime.(_text, _subtype=‘plain’, _charset=None, *, policy=compat32)
类MIMEText用来生成一个主要类型为text的MIME对象。
(2) email.u(address)
email.u((name_encoded_by_Header, address))
写邮件的时候,Email的地址可以有两种写法。一种写法是:xxx@qq.com,另一种写法是:name<xxx@qq.com>。用前者写法,在邮箱中就会显示为xxx<xxx@qq.com>;用后者,就会显示为name<xxx@qq.com>,更为清晰、专业。
有的时候,用前者写法也会显示name,是因为对方邮箱中保存了这个地址,类似于对方手机中保存了手机号和姓名而parseaddr函数就是将str “name<xxx@qq.com>”转换成一个tuple。
In[48]: a = parseaddr('name<xxx@126.com>') In[49]: a Out[49]: ('name', 'xxx@126.com') In[50]: type(a) Out[50]: tuple In[53]: name, addr = parseaddr('boy<xxx@126.com>') In[54]: name Out[54]: 'boy' In[55]: addr Out[55]: 'xxx@126.com'
解析出name和address后,需要用formataddr()函数将其变为标准的email地址。
注意:formataddr()接收的name需要经Header()进行编码处理后才行。【注1】
from email.header import Header In[67]: name, addr = parseaddr('boy<xxx@126.com>') In[68]: a = formataddr((name, addr)) # 将name直接传入 In[69]: b = formataddr((Header(name, 'utf-8').encode(), addr)) # 将name用Header()编码处理后传入 In[70]: a Out[70]: 'boy <xxx@126.com>' In[71]: b Out[71]: '=?utf-8?q?boy?= <xxx@126.com>' #下文msg[’From‘]和msg['To']只识别这种格式 12345678
构建邮件正文:
from email.mime.text import MIMEText from email.header import Header from email.utils import parseaddr, formataddr # 编写一个进行地址解析、生成标准地址格式的函数 def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr)) # 设置邮件内容 msg = MIMEText('This is an email for testing.', 'plain', 'utf-8') # 设置邮件收发件人名称、主题等 ''' 收发件人名称、主题,不是通过SMTP发送给MTA的,而是包含在发送给MTA的文本中(msg)。 ''' msg['From'] = _format_addr('发件人名 <%s>' % '发件人邮箱' msg['To'] = _format_addr('收件人名 <%s>' % '收件人邮箱' #msg['From']和msg['To']直接使用formataddr后的字符串,如果有多个这样的字符串地址,用逗号(,)分开。 msg['Subject'] = Header('TEST', 'utf-8').encode() # 此处,主题也经过了Header的编码处理
【2. smtplib】
在使用email构建好邮件正文后,用smtplib来发送邮件。
()函数,设置服务器地址和端口号
(host='', port=0, local_hostname=None, [timeout, ]source_address=None)
常用邮箱的服务器(SMTP/POP3)地址和端口总结
163.com:
POP3服务器地址:pop.163.com(端口:110)
SMTP服务器地址:smtp.163.com(端口:25)
126邮箱:
POP3服务器地址:pop.126.com(端口:110)
SMTP服务器地址:smtp.126.com(端口:25)
139邮箱:
POP3服务器地址:POP.139.com(端口:110)
SMTP服务器地址:SMTP.139.com(端口:25)
QQ邮箱:
POP3服务器地址:(端口:110)
SMTP服务器地址: (端口:25)
QQ企业邮箱 :
POP3服务器地址: (SSL启用 端口:995)
SMTP服务器地址:(SSL启用 端口:587/465)
gmail) :
POP3服务器地址:pop.gmail.com(SSL启用 端口:995)
SMTP服务器地址:smtp.gmail.com(SSL启用 端口:587)
Foxmail:
POP3服务器地址:POP.foxmail.com(端口:110)
SMTP服务器地址:SMTP.foxmail.com(端口:25)
:
POP3服务器地址:pop3..cn(端口:110)
SMTP服务器地址:smtp..cn(端口:25)
设置发送参数:
from_addr = 'xxx@126.com' password = 'GJZDZMUF' # 密码或邮箱授权码 to_addr = 'xxx@; smtp_server = '; server = (smtp_server, 25) # 设置服务器和端口号 (1) # 打印出和SMTP服务器交互的所有信息,如果没有这一语句,将不打印任何信息 (from_addr, password) # 进行登录 (from_addr, [to_addr], m()) # 1. m()把MIMEText对象变成str(包含utf-8编码信息和Base64编码) # 2. [to_addr]表示可以有多个收件人。多个收件人,传入list。当然,也可以在前面to_addr处直接用list进行赋值,那么此处就不是传入[to_addr],而是传入to_addr了 ()1234567891011
二、定时
待续。
三、遇到的错误
【注1】实际操作时,如果传入未被Header编码处理的name,发送邮件时暂未发现报错(英文与中文皆是)。因此此处待进一步验证。