概要

  我们都知道SMTP(简单邮件传输协议),是一组用于从原地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP规定电子邮件应该如何格式化、如何加密,以及如何在邮件服务器之间传递。SMTP服务器就是通过遵循SMTP协议的发送邮件服务器。

  如果你使用过邮件客户端,比如Foxmail,outlook等,那么你应该了解SMTP服务器和端口号,除了服务器和端口,我们还需要进行其他配置,默认情况下邮件服务提供商是不允许我们使用程序进行邮件发送的,如果想要使用程序发送电子邮件,就需要我们手动开启SMTP服务,并获取一个专用的授权码(用于登陆)。   -- 需要自行去了解所用邮箱的授权码获取方式

使用smtplib和email模块发送邮件

  得到邮箱的授权码就可以使用Python代码发送电子邮件了。Python标准库有多个与邮件相关的模块,其中smtplib负责发送邮件,email模块用来构造邮件和解析邮件内容。

smtplib模块

  stmplib发送邮件大概分为以下几个步骤:

  1. 连接到SMTP服务器
  2. 发送SMTP的“Hello”消息
  3. 登陆到SMTP服务器
  4. 发送电子邮件
  5. 关闭SMTP服务器的连接

  对于简单的邮件,smtplib的使用是非常简单的,下面是实例

  1. # 导入smtplib模块
  2. import smtplib
  3.  
  4. # 创建SMTP对象,括号内为SMTP服务器地址及端口号
  5. smtp = smtplib.SMTP('smtp.qq.com',25)
  6.  
  7. # 向SMTP服务器打一个招呼,查看连接状态
  8. smtp.ehlo()
  9. (250, b'smtp.qq.com\nPIPELINING\nSIZE 73400320\nSTARTTLS\nAUTH LOGIN PLAIN\nAUTH=LOGIN\nMAILCOMPRESS\n8BITMIME')
  10.  
  11. # 连接使用TLS加密(然后就可以传递敏感信息了),否则无法使用login方法登陆会提示SMTPServerDisconnected 异常
  12. smtp.starttls()
  13. (220, b'Ready to start TLS')
  14.  
  15. # 登陆邮箱,传递的是用户名密码
  16. smtp.login('287990400@qq.com','oiifptyw......') # 授权码
  17. (235, b'Authentication successful')
  18.  
  19. # 发送邮件
  20. smtp.sendmail('287990400@qq.com','932911203@qq.com','Subject:this is title\n this is content')
  21. {}
  22.  
  23. # 邮件发送完毕后关闭链接
  24. smtp.quit()
  25. (221, b'Bye')

  PS:sendmail的参数为发件人,收件人,邮件内容

  注意:可以在创建加密链接之前使用smtp.set_debuglevel(1),来显示与SMTP服务器交互的相关信息

  查看发送的邮件会发送,有两个问题,一是收件人栏为空,二是邮件内容缺失,这是因为邮件主题、如何显示发件人、收件人等信息并不是通过SMTP协议发给MTA,而是包含在发给MTA的文本中的,所以,我们必须把FromToSubject添加到email模块中的MIMEText中,才是一封完整的邮件。(MTA可以理解为邮件代理服务器)。

smtplib模块结合email模块

  使用email模块构建一个邮件对象(Message),email模块中支持很多邮件对象

  • MIMEText:表示一个纯文本的邮件     * 常用
  • MIMEImage:表示一个作为附件的图片
  • MIMEMultipart:用于把多个对象组合起来

  其中还有诸如其他的类:MIMEBase、MIMEAudio等。

MIMEText对象的主要参数是:MIMEText(_text, _subtype='plain', _charset=None),其中:

  • _text:表示邮件内容
  • _subtype:表示邮件内容的类型,默认为plain(纯文本),还可以设置为html,表示正文是html文件(会渲染HTML标签)
  • _charset:表示邮件编码,默认情况下使用ascii编码

  下面是一个发送纯文本邮件的例子:

  1. #!/usr/bin/env python3
  2.  
  3. import smtplib
  4. from email.mime.text import MIMEText
  5.  
  6. SMTP_SERVER = 'smtp.qq.com'
  7. SMTP_PORT = 25
  8.  
  9. def send_mail(user,passwd,to,subject,text):
  10. msg = MIMEText(text)
  11. msg['From'] = user # 构建msg对象的发件人
  12. msg['to'] = to # 构建msg对象的收件人
  13. msg['Subject'] = subject # 构建msg对象的邮件正文
  14.  
  15. smtp_server = smtplib.SMTP(SMTP_SERVER,SMTP_PORT)
  16. print('Connecting To mail Server')
  17. try:
  18. smtp_server.ehlo()
  19. print('Starting Encrypted Session.')
  20. smtp_server.starttls()
  21. smtp_server.ehlo()
  22. print('Loggin Into Mail Server.')
  23. smtp_server.login(user,passwd)
  24. print('Send mail.')
  25. smtp_server.sendmail(user,to,msg.as_string()) # 利用msg的as_string()方法转换成字符串
  26. except Exception as err:
  27. print('Sending Mail Failed:{0}'.format(err))
  28.  
  29. finally:
  30. smtp_server.quit()
  31.  
  32. def main():
  33. send_mail('287990400@qq.com','vgdw...ucafc','932911203@qq.com','Important','Text Message from dahlhin')
  34.  
  35. if __name__ == '__main__':
  36. main()

PS:利用msg对象,我们可以构建邮件的header,通过添加header信息,给邮件增加subject等参数,达到补全邮件信息的目的。msg的header添加方式和使用字典的方式相同。

带附件的邮件

  前面说明了发送纯文本邮件的方法,在使用邮件发送带附件(图片)的邮件时,需要使用MIMEMultipart对象,并把MIMEImage对象添加。

  1. import smtplib
  2. import os
  3. from email.mime.image import MIMEImage
  4. from email.mime.multipart import MIMEMultipart
  5. from email.mime.application import MIMEApplication
  6.  
  7. SMTP_SERVER = 'smtp.qq.com'
  8. SMTP_PORT = 25
  9.  
  10. def send_mail(user, passwd, to, subject, text):
  11. msg = MIMEMultipart(text)
  12. msg['From'] = user # 构建msg对象的发件人
  13. msg['to'] = to # 构建msg对象的收件人
  14. msg['Subject'] = subject # 构建msg对象的邮件正文
  15. msg.preamble = subject
  16.  
  17. smtp_server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
  18. print('Connecting To mail Server')
  19. try:
  20. smtp_server.ehlo()
  21. print('Starting Encrypted Session.')
  22. smtp_server.starttls()
  23. smtp_server.ehlo()
  24. print('Loggin Into Mail Server.')
  25. smtp_server.login(user, passwd)
  26.  
  27. # 添加图片附件
  28. url = r'C:\Users\Are you SuperMan\Pictures\Saved Pictures'
  29. for img in os.listdir(url):
  30.  
  31. jpgpart = MIMEImage(open(os.path.join(url,img),'rb').read(),'png')
  32. jpgpart.add_header('Content-Disposition', 'attachment', filename=img) # 用于告知浏览器下载附件文件时的名称
  33. msg.attach(jpgpart)
  34.  
  35. print('Send mail.')
  36. smtp_server.sendmail(user, to, msg.as_string()) # 利用msg的as_string()方法进行转换
  37. except Exception as err:
  38. print('Sending Mail Failed:{0}'.format(err))
  39.  
  40. finally:
  41. smtp_server.quit()
  42.  
  43. def main():
  44. send_mail('287990400@qq.com', 'jwxpwixnpruwcabj', '932911203@qq.com', 'Important2', 'Text Message from dahlhin')
  45.  
  46. if __name__ == '__main__':
  47. main()

使用yagmail发送邮件 

  Python的标准库smtplib和email,相对来说还是比较复杂的,因此许多开源项目提供了更加易用的接口来发送邮件。比如yagmail就是一个使用比较广泛的开源项目,它依旧使用smtplib和email模块,但是相对于直接使用smtplib和email模块,它提供了更加Pythonic的接口,并具有更好的易用性。

  由于yagmail属于第三方库,在使用前需要先行安装

  1. pip3 install yagmail

  下面使用yagmail发送一封简单的邮件

  1. server = yagmail.SMTP(user='287990400@qq.com',password='vgdwgrziieducafc',host='smtp.qq.com',port=25,smtp_starttls=True,smtp_ssl=False)
  2. content = ['this is my first mail','used for yagmail']
  3. server.send('932911203@qq.com','IMPORTANT',content) # 对方邮箱,主题,邮件内容

  如果要携带附件那么只需要在send后面添加即可

  1. server = yagmail.SMTP(user='287990400@qq.com',password='vgdwgrziieducafc',host='smtp.qq.com',port=25,smtp_starttls=True,smtp_ssl=False)
  2. content = ['this is my first mail','used for yagmail']
  3. server.send('932911203@qq.com','Images',content,['/Users/DahlHin/Desktop/image.jpg'])

  再也没有这么好用的第三方邮件库了

利用Python 发送邮件的更多相关文章

  1. 利用python发送邮件

    找了很多使用python发送邮件的文章, 发现写的并不是太全, 导致坑特别多, 刚把这个坑跨过去, 在此记录下来 本代码使用163作为发送客户端, 接收邮箱随意 首先登录163邮箱, 开启POP3/S ...

  2. 最全总结!聊聊 Python 发送邮件的几种方式

    1. 前言 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人,我给大 ...

  3. 利用Python+163邮箱授权码发送邮件

    背景 前段时间写了个自动打卡的脚本,但是脚本不够完善,我需要知道,打卡到底成没成功,因此,我想到了用Python执行完代码之后,再执行一段发送邮件的代码.需求开始明确了,就开始分析和写代码实现吧. 分 ...

  4. 利用Python+163邮箱授权码发送带附件的邮件

    背景 前段时间写了个自动爬虫的脚本,定时在阿里云服务器上执行,会从某个网站上爬取链接保存到txt文本中,但是脚本不够完善,我需要爬虫完毕之后通过邮件把附件给我发送过来,之前写过一个<利用Pyth ...

  5. 如何利用Python实现自动打卡签到

    需求描述 我们需要登录考勤系统(网页端,非手机端)进行签到,如果不想每天都早早起来打卡签到,就可以通过写程序实现这一功能. 业务梳理 通过长时间的早起打卡签到发现规律,我每天只是不停的点击,签到,都是 ...

  6. python 发送邮件的两种方式【终极篇】

    一,利用python自带的库 smtplib简单高效 from email.mime.multipart import MIMEMultipart from email.mime.text impor ...

  7. 利用Python进行数据分析(12) pandas基础: 数据合并

    pandas 提供了三种主要方法可以对数据进行合并: pandas.merge()方法:数据库风格的合并: pandas.concat()方法:轴向连接,即沿着一条轴将多个对象堆叠到一起: 实例方法c ...

  8. 利用Python进行数据分析(5) NumPy基础: ndarray索引和切片

    概念理解 索引即通过一个无符号整数值获取数组里的值. 切片即对数组里某个片段的描述. 一维数组 一维数组的索引 一维数组的索引和Python列表的功能类似: 一维数组的切片 一维数组的切片语法格式为a ...

  9. 利用Python进行数据分析(9) pandas基础: 汇总统计和计算

    pandas 对象拥有一些常用的数学和统计方法.   例如,sum() 方法,进行列小计:   sum() 方法传入 axis=1 指定为横向汇总,即行小计:   idxmax() 获取最大值对应的索 ...

随机推荐

  1. [OS] 操作系统常考知识点

    转自:http://jennica.space/2017/03/21/os-principle/ 大纲如下: 1.操作系统概述2.操作系统运行环境3.进程线程模型4.处理器调度5.同步机制6.存储模型 ...

  2. 第64天:CSS常用命名规范,有用!

    CSS常用命名,必须记住 一.常用命名 标题:title 摘要:summary 箭头:arrow 商标:label 网站标志:logo 转角/圆角:corner 横幅广告:banner 子菜单:sub ...

  3. C结构体【转】

    “结构”是一种构造类型,它是由若干“成员”组成的.每一个成员可以是一个基本数据类型或者又是一个构造类型.结构既是一种“构造”而成的数据类型,那么在说明和使用之前必须先定义它,也就是构造它.如同在说明和 ...

  4. Foundation框架—时间输出格式NSDateFormatter

    在开发iOS程序时,有时候需要将时间格式调整成自己希望的格式,这个时候我们可以用NSDateFormatter类来处理.下面来介绍NSDateFormatter的常用属性和API:  1.常用属性 @ ...

  5. 进程池-限制同一时间在CPU上运行的进程数

    if __name__=='__main__' :  为了区分你是主动执行这个脚本,还是从别的地方把它当做一个模块去调用. 如果是主动执行,则执行.如果是调用的,则不执行主体. 1. 串行:切记切记: ...

  6. 【题解】51nod 1203JZPLCM问题

    这题好强强啊,貌似是集训队原题?集训队原题当中值域是1e9的范围,这样各种乱搞是妥妥的不能过了,只能写正解的离线+树状数组维护前缀积. 最开始我写了几种乱搞做法,包括莫队和线段树做法.其中表现比较优秀 ...

  7. bzoj2165: 大楼 (矩阵快速幂)

    //========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明! //=============== ...

  8. POJ3974:Palindrome——题解

    http://poj.org/problem?id=3974 题目大意: 求最大回文子串长度. ———————————————————— 马拉车板子题. 马拉车大概讲解: 首先在每两个字母之间插入‘# ...

  9. 洛谷 P2657 [SCOI2009]windy数 解题报告

    P2657 [SCOI2009]windy数 题目描述 \(\tt{windy}\)定义了一种\(\tt{windy}\)数.不含前导零且相邻两个数字之差至少为\(2\)的正整数被称为\(\tt{wi ...

  10. 读取proc/uptime信息。

    #include <stdio.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h ...