python 收发邮件_python发送各类邮件的主要基本方法

利用python实现基本的邮件发送。

感谢以下博客的整理,本人在学习的同时也做了一些整理

一、相关模块介绍

发送邮件主要用到了smtplib和email两个模块,这里首先就两个模块进行一下简单的介绍:

1、smtplib模块

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

SMTP类构造函数,表示与SMTP服务器之间的连接,通过这个连接可以向smtp服务器发送指令,执行相关操作(如:登陆、发送邮件)。所有参数都是可选的。

host:smtp服务器主机名

port:smtp服务的端口,默认是25;如果在创建SMTP对象的时候提供了这两个参数,在初始化的时候会自动调用connect方法去连接服务器。

smtplib模块还提供了SMTP_SSL类和LMTP类,对它们的操作与SMTP基本一致。

smtplib.SMTP提供的方法:

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

SMTP.connect([host[, port]]):连接到指定的smtp服务器。参数分别表示smpt主机和端口。注意: 也可以在host参数中指定端口号(如:smpt.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())

使用smtplib库发送邮件的基本步骤:

#连接到SMTP服务器,参数表示SMTP主机和端口,端口默认25

SMTP.connect([host[,port]]) #也可以不显式链接:SMTP(host)

#登录SMTP服务器

SMTP.login(user,password)

#发送邮件。.as_string()是字符串,表示邮件内容,to_addrs是收件人list

SMTP.sendmail(from_addr, to_addrs, msg.as_string())

#断开连接

SMTP.close() #也有用SMTP.quit()

2、email模块

Email库用来处理邮件消息。包括MIME和基于RFC2822的消息文档。

有关MIME的一些知识

RFC2822定义的邮件格式中,邮件体只是单纯的ASCII编码的字符序列,MIME扩展邮件的格式,用以支持非ASCII编码的文本、非文本附件及包含多个部分(multi-part)的邮件体。

MIME消息由消息头、消息体组成,即邮件的邮件头、邮件体。中间以空行进行分隔。

1、邮件头:包括发件人(from)、收件人(to)、邮件主题(subject)、接收日期(date)、MIME版本、邮件内容类型等信息。每条信息称为一个域,由域名后加“:”和信息内容构成,域的首行必须顶头写。

2、邮件体:有text/plain(纯文本)和text/html(超文本)之分,由邮件头的“content type”域指出。可以同时存在,也可以只存在一种。这就是为什么有些邮件既可以用html格式查看,又可以用文本格式查看的原因。邮件体分为多个段,称为Payload。每个段也包括段头段尾,中间以空行分隔。multipart类型有3种:multipart/mixed multipart/related multipart/alternative。邮件里添加附件要定义multipart/mixed段,如果纯文本超文本共存,则要定义multipart/alternative,如存在内嵌资源,要定义multipart/related。

3、附件(attach)。发送邮件时,可以将本机的文件一起发送。附件可以有0个或多个,只要附件的总大小,不超过邮件服务器所声明的最大容量。 4、

包括的类主要有(更加详细的介绍可见:

http://docs.python.org/library/email.mime.html):

class email.mime.text.MIMEText(_text[, _subtype[, _charset]])

用于生成MIME对象的主体文本:_text指定邮件内容,_subtype指定邮件类型,_charset指定编码。

class email.mime.multipart.MIMEMultipart()

用于生成包含多个部分的邮件体的MIME对象

class email.mime.base.MIMEBase(_maintype, _subtype, **_params)

这是MIME的一个基类。一般不需要在使用时创建实例。其中_maintype是内容类型,如text或者image。_subtype是内容的minor type 类型,如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@YYY.com' #自己的邮件地址

msg['date']='2013-5-25' #时间日期

msg['subject']='hello python' #邮件主题

class email.mime.text.MIMEText(_text[, _subtype[, _charset]])

MIME文本对象,其中_text是邮件内容,_subtype邮件类型,可以是text/plain(普通文本邮件),html/plain(html邮件), _charset编码,可以是gb2312等等。

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

1.普通文本和html邮件的发送

普通文本邮件发送的实现,关键是要将MIMEText中_subtype设置为plain。首先导入smtplib和mimetext。创建smtplib.smtp实例,connect邮件smtp服务器,login后发送.

html信息发送和普通文本一样,conten内容变为html信息,并将_subtype设置为html。

具体代码如下(python 2.7):

#import getpass #如果需要交互获取密码

#pwd_input = getpass.getpass('Password:')

import time

import smtplib

import email.utils

from email.mime.text import MIMEText

#Initialize mail information

#mailto_list = ['XXX@163.com','YYY@qq.com']

mail_host = 'smtp.163.com' #设置网易163服务器

mail_user = 'ZZZ' #用户名

mail_pass = '*********' #口令

mail_postfix = '163.com' #发件箱后缀

mail_from = '@'.join([mail_user,mail_postfix]) #收件箱

#Create the message

#html信息

#content = "Dyllian使用程序给你发了个链接!"

#msg = MIMEText(content,_subtype='html',_charset='utf8')

#普通文本

content = "Hello dyllian"

msg = MIMEText(content,_subtype='plain',_charset='utf8')

msg['From'] = email.utils.formataddr(('Author',mail_from)) #str type

msg['To'] = email.utils.formataddr(('Recipient',mailto_list)) #mail to list

msg['Subject'] = 'Test from python!'

msg['date']=time.strftime('%a, %d %b %Y %H:%M:%S %z')#定义发送时间(不定义的可能有的邮件客户端会不显示发送时间)

#msg.preamble = 'This is a common message in MIME format.'

#Send mail to list recipient

try:

server = smtplib.SMTP(mail_host)

server.login(mail_user,mail_pass)

server.sendmail(mail_from,mailto_list,msg.as_string()) #mail to list recipient

except Exception,e: #try中有异常则执行

print 'Mail passed unsuccessfully!\n',str(e)

else: #try中没有异常则执行

print 'Mail passed successfully!'

finally: #try中有无异常都执行

server.close()

2.带附件的邮件发送(附件图片,附件一般文件)

import os

import time

import smtplib

import email.utils

from email.mime.text import MIMEText

from email.mime.image import MIMEImage

from email.mime.multipart import MIMEMultipart

#Get local path

path = os.path.dirname(__file__)

#Initialize mail infomation

#mailto_list = ['XXX@163.com','YYY@qq.com']

mailto_list = ['XXX@163.com']

mail_host = 'smtp.163.com' #设置服务器

mail_user = 'ZZZ' #用户名

mail_pass = '******' #口令

mail_postfix = '163.com' #发件箱后缀

mail_from = '@'.join([mail_user,mail_postfix]) #收件箱

#构建一个带附件的实例

msg = MIMEMultipart()

#用MIMEImage附件图片

fp = open(path+'\\ning1.jpg', 'rb')

msgImage = MIMEImage(fp.read())

fp.close()

msgImage.add_header('Content-ID', '')

msg.attach(msgImage)

#构造附件1图片

att1 = MIMEText(open(path+'\\ning1.jpg','rb').read(),_subtype='base64',_charset='utf8')

att1['Content-Type'] = 'application/octet-stream'

att1['Content-Disposition'] = "attachment; filename=ningning1.jpg" #这里的filename可以随便取,写什么名字,邮件中显示什么名字

msg.attach(att1)

#构造附件2文件

att2 = MIMEText(open(path+'\\ning2.txt','rb').read(),_subtype='base64',_charset='utf8')

att2['Content-Type'] = 'application/octet-stream'

att2['Content-Disposition'] = "attachment; filename=test2.txt"

msg.attach(att2)

#加邮件头

msg['From'] = email.utils.formataddr(('Author',mail_from)) #str type

msg['To'] = email.utils.formataddr(('Recipient',mailto_list)) #mail to list

msg['Subject'] = 'Test from python!'

msg['date']=time.strftime('%a, %d %b %Y %H:%M:%S %z')#定义发送时间(不定义的可能有的邮件客户端会不显示发送时间)

#msg.preamble = 'This is a multi-part message in MIME format.'

#Send mail to list recipient

try:

server = smtplib.SMTP(mail_host)

server.login(mail_user,mail_pass)

server.sendmail(mail_from,mailto_list,msg.as_string()) #mail to list recipient

except Exception,e: #try中有异常则执行

print 'Mail passed unsuccessfully!\n',str(e)

else: #try中没有异常则执行

print 'Mail passed successfully!'

finally: #try中有无异常都执行

server.close()

四:遇到的问题

希望在邮件正文中显式图片信息,思路是用html属性发送,查了几个资料,遇到了同样的问题:

1.如果做以下处理,结果还是以附件的形式发送图片:

#构建一个带附件的实例

msg = MIMEMultipart('ralated')

#用MIMEImage附件图片

fp = open(path+'\\ning1.jpg', 'rb')

msgImage = MIMEImage(fp.read())

fp.close()

msgImage.add_header('Content-ID', '')

msg.attach(msgImage)

2.如果做以下的处理,结果有编译错误:

import os

import smtplib

import email.utils

from email.mime.text import MIMEText

from email.mime.image import MIMEImage

from email.mime.multipart import MIMEMultipart

#Get local path

path = os.path.dirname(__file__)

#Initialize mail infomation

mailto_list = ['XXX@163.com']

mail_host = 'smtp.163.com' #设置服务器

mail_user = 'YYY' #用户名

mail_pass = '******' #口令

mail_postfix = '163.com' #发件箱后缀

mail_from = '@'.join([mail_user,mail_postfix]) #收件箱

#构建一个带附件的实例

msg = MIMEMultipart('ralated')

#html附带图片正文

msgAlternative = MIMEMultipart('alternative')

msg.attach(msgAlternative)

html = '本邮件,正文中显示图片!path+"\\ning1.jpg"'

htmlText = MIMEText(html,_subtype='html',_charset='utf8')

msgAlternative.attach(htmlText)

#内置图片

fp = open(path+'\\ning1.jpg','rb+')

msgImage = MIMEImage(fp.read())

fp.close()

msgImage.add_header('Content-ID','')

msg.attach(msgImage)

#加邮件头

msg['From'] = email.utils.formataddr(('Author',mail_from)) #str type

msg['To'] = email.utils.formataddr(('Recipient',mailto_list)) #mail to list

msg['Subject'] = 'Test from python!'

msg.preamble = 'This is a multi-part message in MIME format.'

#Send mail to list recipient

try:

server = smtplib.SMTP(mail_host)

server.login(mail_user,mail_pass)

server.sendmail(mail_from,mailto_list,msg.as_string()) #mail to list recipient

except Exception,e: #try中有异常则执行

print 'Mail passed unsuccessfully!\n',str(e)

else: #try中没有异常则执行

print 'Mail passed successfully!'

finally: #try中有无异常都执行

server.close()

编译结果:

Mail passed unsuccessfully!

(554, 'DT:SPM smtp11, D8CowEDp5XJrPKBR0ATQBg--.765S2 1369455724 http://mail.163.com/help/help_spam_16.htm?ip=61.150.43.98&hostid=smtp11&time=1369455724')

不知道哪里出了错,哪位可能提供思路解决?谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/410294.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

区分Activity的四种加载模式

在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。 这需要为Activity配置特定的加载模式,而不是使用默认的加载模…

laravel常用响应操作

转载于:https://www.cnblogs.com/saintdingspage/p/11298246.html

python中mat函数_python matplotlib中的subplot函数使用详解

python里面的matplotlib.pylot是大家比较常用的,功能也还不错的一个包。基本框架比较简单,但是做一个功能完善且比较好看整洁的图,免不了要网上查找一些函数。于是,为了节省时间,可以一劳永逸。我把常用函数作了一个总…

if else if else语句格式_你还在用if/else吗?

你还在用if/else吗?前提我们在日常开发当中经常会遇到复杂的条件判断,一般的做法是用if/else,或者优雅一点的写法是用switch语句来实现多个条件的判断,这样的话会有很多问题,随着判断条件的增加,代码中if/e…

乔梁专访——让持续交付变为可能

本月起,图灵社区陆续推出专业IT人访谈版块,首期人物是百度公司项目管理部高级架构师、《持续交付》译者乔梁。   本次访谈分三个主题:   1、 从概念和技术两个层次来解释持续交付   2、.持续交付是可实施的   3、持续交付将变成必备…

java 变量锁_并发编程高频面试题:可重入锁+线程池+内存模型等(含答案)

对于一个Java程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一。因为并发编程是Java语言中最为晦涩的知识点,它涉及操作系统、内存、CPU、编程语言等多方面的基础能力,更为考验一个程序员的内功。那到底应该怎么学习并发编程呢? Java SDK的并发工具包有很多,是…

element中select默认选中第一个_探索在网页中使用“标注”

github地址:https://github.com/1314mxc/yunUI ,欢迎star!说起“标注”,在HTML5之前,你可能想起的是各种浏览器插件,emmmmmmm或者说你根本不认为浏览器上可以有这种玩意。但是HTML5来了,这是它的…

佳能g3800故障灯说明书_热水器维修电话|史密斯燃气热水器出现16故障码

热水器出现故障代码其实是一件很常见的事情,大多是住户的热水器都出现过这样的问题,为了防止这样的事情也发生在我身上,我熟读热水器说明书,终于参透其中的道理,那么接下来我为大家介绍史密斯燃气热水器出现16故障码。…

git语言包安装_Git分布式版本管理系统快速入门指南

为什么要使用版本管理系统无论有没有使用过专业化工具,每个人都或多或少地有版本管理的需求。我们在做论文、写报告或者设计方案时,因为难以避免的不断改动,总会形成很多个不同的版本,我们可能会用“某某设计方案_20180910”这样加…

(十)、java内部类与内部类的闭包和回调

一、成员内部类 1.可以把一个内部类看做是一个成员。成员内部类可以无条件访问外部类的所有成员属性和成员方法。 class OutterClass {//外部类private int in 0;static int inn4;public OutterClass(int in) {this.in in;}class InnerClass { //内部类public void outpu…

vb.net中滚动条一直显示没有数据时也显示_Android Studio 中 System Trace 的新增功能...

Android Studio 中 System Trace 的新增功能在 Android Studio 4.0 中,我们已经对 CPU Profiler 的 UI 做了大量调整来提供更加直观的工作流记录,而在 Android Studio 4.1 中,我们基于开发者们的反馈对此功能进行了持续改进,并且新…

第一节 Memcached分布式缓存入门

关于Memcached的博文太多了,以下是个人学习的收集整理。 本节讨论问题: 简单介绍与应用下载安装注意事项简单测试Memcached分布式原理 一、介绍与应用 在常规的WEB开发下,基本都会利用到缓存用以降低对数据库的压力,提高访问速度。有时候缓存…

tomcat 拦截指定url_一口气说出 过滤器 和 拦截器 6个区别,别再傻傻分不清了

点击“ 程序员内点事 ”关注,选择“ 设置星标 ”坚持学习,好文每日送达!周末有个小伙伴加我微信,向我请教了一个问题:老哥,「过滤器 (Filter) 和 拦截器 (Interceptor) 有啥区别啊?」 听到题目我…

Java 多线程练习---创建两个子线程,每个线程交替输出“你好--来自线程***”...

|--需求说明 |--实现思路 1、创建一个类,实现Runnable,在这个类里面重写run()方法,在run()方法里面写一个20的for循环 2、创建一个类,实例化上面的类,用这个类的对象创建线程 |--代码内容 1 package cn.thread;2 3 /**…

js保留两位小数的函数_使用率低但功能强大的6个Excel函数公式应用技巧解读!...

在Excel函数公式中,有部分函数的使用率是比较低的,但是其功能也是非常强大的。一、Median函数。功能:返回一组数的中值。中值就是一组数的中间数值,如果参数包含的数值是偶数,Median函数将返回位于中间两个值的平均值。…

.net复习之七

表A: 表B: 1. SELECT * FROM A JOIN B ON A.Id B.Id 將顯示 9 條數據。 Inner join(等值连接)只返回两个表中联结字段相等的行 2. SELECT * FROM A LEFT JOIN B ON A.Id B.Id 將顯示 12 條數據…

原生js实现tab栏切换效果

我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注小歌谣一起学习前后端知识 运行效果 首先我们来看一下原生js实现的效果 下面就开始直接上代码了 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…

线程八大核心+java并发核心知识体系精讲_Java从业者如果不懂这些,面试80%都会挂在这些核心知识上面...

JVM无论什么级别的Java从业者&#xff0c;JVM都是进阶时必须迈过的坎。不管是工作还是面试中&#xff0c;JVM都是必考题。如果不懂JVM的话&#xff0c;薪酬会非常吃亏(近70%的面试者挂在JVM上了)详细介绍了JVM有关于线程、内存模型、JVM运行时内存、垃圾回收与算法、Java中四种…

Ajax技术简单入门

随着Google公司推出的Gmail服务后,越来越多的人开始关注Ajax技术了,所谓Ajax(Asynchronous JavaScript and XML缩写)技术,就是指运用JavaScript和XML在不用刷新Web页的情况下与Web服务器通信的技术&#xff0e;一般来说&#xff0c;使用Ajax技术主要有两个原因&#xff1a;一是…

Alt Gr or Shift

This is interesting. The keyboard here is different from what we always use in China. Characters and layout are different. Hans gave me the password to logon the system. There s a “” character in it. With Chinese keyboard, I will use “Shift 2″ to gener…