python最全发送和接收邮件 官方文档
python发送和接收邮件 官方文档
关于电子邮件
大学之前,基本不用邮箱,所以基本感觉不到它的存在,也不知道有什么用;然而大学之后,随着认识的人越来越多,知识越来越广泛,邮箱已然成为很重要的通讯工具,大学一些课程作业需要有邮箱发给老师,注册网站需要邮箱,找工作也需要邮箱;那么电子邮箱是什么原理呢?
发送邮件
SMTP协议
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。通过SMTP协议所指定的服务器,就可以把E-mail寄到收信人的服务器上了,只要几分钟。
python中的SMTP模块
使用SMTP的基本步骤
- 连接服务器
- 登录
- 发送服务请求
- 退出
import smtplib
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
def send_email(from_addr, to_addr, subject, password):
msg = MIMEText("邮件正文",'html','utf-8')
msg['From'] = u'<%s>' % from_addr
msg['To'] = u'<%s>' % to_addr
msg['Subject'] = subject
smtp = smtplib.SMTP_SSL('smtp.163.com', 465)
smtp.set_debuglevel(1)
smtp.ehlo("smtp.163.com")
smtp.login(from_addr, password)
smtp.sendmail(from_addr, [to_addr], msg.as_string())
if __name__ == "__main__":
# 这里的密码是开启smtp服务时输入的客户端登录授权码,并不是邮箱密码
# 现在很多邮箱都需要先开启smtp才能这样发送邮件
send_email(u"from_addr",u"to_addr",u"主题",u"password")
上面演示了用smtplib来发送邮件,并且使用了SSL加密,这样相对安全,使用了email来构造邮件的内容,这里发送的是纯文本的内容,我觉得最应该注意的就是这里邮箱的密码。另外各个公司的邮件服务器和端口都可能不同,使用前可以先查一下
这里列几个常用的:
邮箱 | SMTP服务器 | SSL协议端口 | 非SSL协议端口 |
---|---|---|---|
163 | smtp.163.com | 465或者994 | 25 |
smtp.11.com | 465或587 | 25 |
接收邮件
POP3和IMAP
POP是指邮局协议,目的是让用户可以访问邮箱服务器中的邮件,允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收电子邮件的。
后来又出现了IMAP协议(Interactive Mail Access Protocol),即交互式邮件访问协议,与POP3的不同在于:开启了IMAP后,在电子邮件客户端收取的邮件仍然保留在服务器上,同时在客户端上的操作都会反馈到服务器上,如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作。
使用POP3
python的poplib模块支持POP3,基本步骤:
- 连接到服务器
- 登录
- 发出服务请求
- 退出
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() | 登出,保存修改,解锁邮箱,结束连接,退出 |
例子
from poplib import POP3
p = POP3('pop.163.com')
p.user('xxxxxxx@163.com')
p.pass_('xxxxxxxx')
p.stat()
...
p.quit()
使用IMAP
python中的imaplib包支持IMAP4
常用方法:
方法 | 描述 |
---|---|
IMAP4(server) | 与IMAP服务器建立连接 |
login(user, pass) | 用户密码登录 |
list() | 查看所有的文件夹(IMAP可以支持创建文件夹) |
select() | 选择文件夹默认是"INBOX" |
search() | 三个参数,第一的是CHARSET,通常为None(ASCII),第二个参数不知到是干什么官方没解释 |
例子
import getpass, imaplib
M = imaplib.IMAP4()
M.login(getpass.getuser(), getpass.getpass())
M.select()
typ, data = M.search(None, 'ALL')
for num in data[0].split():
typ, data = M.fetch(num, '(RFC822)')
print 'Message %s\n%s\n' % (num, data[0][1])
M.close()
M.logout()
更详细的内容可以看官方文档:
使用linux的sendEmail来自动发送邮件,但是阿里云上,禁止使用25端口发送邮件,必须使用加密协议,如587端口,sendEmail的软件最后一版是2009年,试了下,很难兼容CentOS7,所以就想到用python来实现。自己网上搜罗了下稍加修改,再加上自己加了批量发送多个目标邮件地址的功能,代码如下:
#C:\Python27# -*- coding: utf-8 -*-
import os,re
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr,formataddr
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
import smtplib
from_user = 'opm@xxx.cn'
password = 'dfffE9xVDtPkdz'
smtp_server = 'smtp.exmail.qq.com'
smtp_port = 587
maindir = '/home/appadm/open***-2.4.4/user'
confdir = '/home/appadm/open***-2.4.4/'
file1 = os.path.join(maindir,'open***-install-2.4.4-I601.exe') #附件1,一个安装程序,路径/home/appadm/open***-2.4.4/user/open***-install-2.4.4-I601.exe
file2 = os.path.join(maindir,'open***-readme.docx') #附件2,安装操作手册,路径'/home/appadm/open***-2.4.4/open***-readme.docx
mail_list = [] 目标邮件组初始为空,该mail_list为变量,与下面的‘mail_list’不同
flist = open('mail_list','r') 本地目录下有一个mail_list的文件,收件人全部写进去,每行一个收件人
for line in flist.readlines():
mail_list.append(line.strip())
def sendmail():
###以下到邮件正文前的代码可以忽略,由于我的附件3要取邮箱的前缀作为用户名,举例,xwz@qq.com,我的附件3是xwz.tar.gz,另外要到psw-file这个文件中账号xwz以及对应的密码
for to_user in mail_list:
suser = to_user.strip().split("@")[0]
fpath = os.path.join(maindir,suser)
ftar = suser + '.tar.gz'
file3 = os.path.join(fpath,ftar)
userm = suser + '.+'
os.chdir(confdir)
os.chdir('config')
sd = os.getcwd()
f = open('psw-file','r')
for line in f.readlines():
m = re.search(userm,line)
if m is not None:
userinfo = m.group()
f.close()
useracc = userinfo.split()[0]
userpass = userinfo.split()[1]
#############以下为邮件正文######
mail_content = '''Hello,your open*** account is: %s,
and your password is: %s''' % (useracc,userpass)
###############
msg = MIMEMultipart() 带附件的邮件
msg['From'] = from_user 发件人
msg['To'] = to_user 收件人
msg['Subject'] = Header(u"测试环境: %s\'s open*** imformation" % suser).encode() 标题
mail_text = MIMEText(mail_content,'plain','utf-8') 内容格式
msg.attach(mail_text) 正文内容
exepart = MIMEApplication(open(file1, 'rb').read()) 附件1
exepart.add_header('Content-Disposition', 'attachment', filename='open***-install-2.4.4-I601.exe')
msg.attach(exepart)
docpart = MIMEApplication(open(file2, 'rb').read()) 附件2
docpart.add_header('Content-Disposition', 'attachment', filename='open***-readme.docx')
msg.attach(docpart)
tarpart = MIMEApplication(open(file3, 'rb').read()) 附件3
tarpart.add_header('Content-Disposition', 'attachment', filename=ftar)
msg.attach(tarpart)
server = smtplib.SMTP(smtp_server,smtp_port) smtp服务器以及端口
server.starttls()
#server.set_debuglevel(1)
server.login(from_user,password) 发件人账号密码
server.sendmail(from_user,to_user,msg.as_string()) 发送格式
server.quit()
if __name__ == '__main__':
print "Mail sending......."
sendmail()
print "Mail processed Over"
Python发送邮件(最全)
简单邮件传输协议(SMTP)是一种协议,用于在邮件服务器之间发送电子邮件和路由电子邮件。
Python提供smtplib
模块,该模块定义了一个SMTP客户端会话对象,可用于使用SMTP或ESMTP侦听器守护程序向任何互联网机器发送邮件。
这是一个简单的语法,用来创建一个SMTP对象,稍后将演示如何用它来发送电子邮件 -
import smtplib smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
这里是上面语法的参数细节 -
-
host - 这是运行SMTP服务器的主机。可以指定主机的IP地址或类似
yiibai.com
的域名。这是一个可选参数。 -
port - 如果提供主机参数,则需要指定SMTP服务器正在侦听的端口。通常这个端口默认值是:
25
。 -
local_hostname - 如果SMTP服务器在本地计算机上运行,那么可以只指定
localhost
选项。
SMTP对象有一个sendmail
的实例方法,该方法通常用于执行邮件发送的工作。它需要三个参数 -
-
sender - 具有发件人地址的字符串。
-
receivers - 字符串列表,每个收件人一个。
-
message - 作为格式如在各种RFC中指定的字符串。
1.使用Python发送纯文本电子邮件
示例
以下是使用Python脚本发送一封电子邮件的简单方法 -
#!/usr/bin/python3import smtplib sender = 'from@fromdomain.com'receivers = ['to@todomain.com'] message = """From: From Person <from@fromdomain.com> To: To Person <to@todomain.com> Subject: SMTP e-mail test This is a test e-mail message. """try: smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, receivers, message) print "Successfully sent email"except SMTPException: print "Error: unable to send email"
在这里,已经发送了一封基本的电子邮件,使用三重引号,请注意正确格式化标题。一封电子邮件需要一个From
,To
和一个Subject
标题,与电子邮件的正文与空白行分开。
要发送邮件,使用smtpObj
连接到本地机器上的SMTP服务器。 然后使用sendmail
方法以及消息,从地址和目标地址作为参数(即使来自和地址在电子邮件本身内,这些并不总是用于路由邮件)。
如果没有在本地计算机上运行SMTP服务器,则可以使用smtplib
客户端与远程SMTP服务器进行通信。除非您使用网络邮件服务(如gmail或Yahoo! Mail),否则您的电子邮件提供商必须向您提供可以提供的邮件服务器详细信息。以腾讯QQ邮箱为例,具体如下:
mail = smtplib.SMTP('smtp.qq.com', 587) # 端口465或587
2.使用Python发送HTML电子邮件
当使用Python发送邮件信息时,所有内容都被视为简单文本。 即使在短信中包含HTML标签,它也将显示为简单的文本,HTML标签将不会根据HTML语法进行格式化。 但是,Python提供了将HTML消息作为HTML消息发送的选项。
发送电子邮件时,可以指定一个Mime版本,内容类型和发送HTML电子邮件的字符集。
以下是将HTML内容作为电子邮件发送的示例 -
#!/usr/bin/python3import smtplib message = """From: From Person <from@fromdomain.com> To: To Person <to@todomain.com> MIME-Version: 1.0 Content-type: text/html Subject: SMTP HTML e-mail test This is an e-mail message to be sent in HTML format <b>This is HTML message.</b> <h1>This is headline.</h1> """try: smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, receivers, message) print "Successfully sent email"except SMTPException: print "Error: unable to send email"
3.发送附件作为电子邮件
要发送具有混合内容的电子邮件,需要将Content-type标题设置为multipart / mixed。 然后,可以在边界内指定文本和附件部分。
一个边界以两个连字符开始,后跟一个唯一的编号,不能出现在电子邮件的消息部分。 表示电子邮件最终部分的最后一个边界也必须以两个连字符结尾。
所附的文件应该用包(“m”)功能编码,以便在传输之前具有基本的64编码。
4.发送示例
首先我们要知道用python代理登录qq邮箱发邮件,是需要更改自己qq邮箱设置的。在这里大家需要做两件事情:邮箱开启SMTP功能 、获得授权码。之后我们来看看如何更改模板代码,实现使用Python登录QQ邮箱发送QQ邮件。
注意:也可以使用其他服务商的 SMTP 访问(QQ、网易、Gmail等)。
使用QQ邮件发送邮件之前如何设置授权码,参考:
http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256
4.1.发送一纯文本邮件到指定邮件
#! /usr/bin/env python#coding=utf-8from email.mime.text import MIMETextfrom email.header import Headerfrom smtplib import SMTP_SSL#qq邮箱smtp服务器host_server = 'smtp.qq.com'#sender_qq为发件人的qq号码sender_qq = '7697****@qq.com'#pwd为qq邮箱的授权码pwd = '****kenbb***' ## xh**********bdc#发件人的邮箱sender_qq_mail = '7697****@qq.com'#收件人邮箱receiver = 'yiibai.com@gmail.com'#邮件的正文内容mail_content = '你好,这是使用python登录qq邮箱发邮件的测试'#邮件标题mail_title = 'Maxsu的邮件'#ssl登录smtp = SMTP_SSL(host_server)#set_debuglevel()是用来调试的。参数值为1表示开启调试模式,参数值为0关闭调试模式smtp.set_debuglevel(1) smtp.ehlo(host_server) smtp.login(sender_qq, pwd) msg = MIMEText(mail_content, "plain", 'utf-8') msg["Subject"] = Header(mail_title, 'utf-8') msg["From"] = sender_qq_mail msg["To"] = receiver smtp.sendmail(sender_qq_mail, receiver, msg.as_string()) smtp.quit()
执行上面代码后,登录接收邮件的邮件帐。。。