python发送邮件程序

python发送邮件程序


  hello!我是wakeyo_J,每天一个konwledge point,一起学python,让技术无限发散。

1. 完成项目的流程

在这里插入图片描述

2. 项目程序的目的

  为了避免每次发送邮件都需要登录账号的问题,制作一个邮件发送程序。项目目标:使用python发送邮件。

3. 分析流程,拆解项目

3.1 项目拆分为以下两个版本

在这里插入图片描述

3.2 逐步解决并逐步完善两个版本

  • 版本1.0 —— 完成简单的邮件发送
    先度娘一波,看看使用python发送邮件需要用到的知识
    在这里插入图片描述

SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。

Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件。
在这里插入图片描述

1.首先,构造一个简单的纯文本邮件

from email.mime.text import MIMEText
msg = MIMEText('hello, send by Python...', 'plain', 'utf-8')
''' 第一个参数就是邮件正文,
    第二个参数是MIME的subtype,传入’plain’表示纯文本,最终的MIME就是’text/plain’,
    最后一定要用utf-8编码保证多语言兼容性。
'''

MIMEText对象中, 有三个参数
在这里插入图片描述

造MIMEText对象时,第一个参数就是邮件正文,第二个参数是MIME的subtype,传入’plain’表示纯文本,最终的MIME就是’text/plain’,最后一定要用utf-8编码保证多语言兼容性。

2.用SMTP发送:

(1)发送邮件代码格式

# 输入Email地址和口令:
from_addr = input('From: ')
password = input('Password: ')
# 输入SMTP服务器地址:
smtp_server = input('SMTP server: ')
# 输入收件人地址:
to_addr = input('To: ')

SMTP服务器地址,实际上就是代收发服务器地址,是由邮箱服务商提供的。说白了,你用哪家公司的邮箱, 就是哪家公司收发邮件服务器的地址。

本程序以QQ邮箱来测试. 我们使用QQ邮箱的收发邮件服务器的地址。

QQ邮箱SMTP服务器地址:smtp.qq.com, 端口465, QQ邮箱默认的端口是25, 我们这里使用的是加密端口465

  • 开始配置SMTP服务了
server = smtplib.SMTP_SSL(smtp_server, 465) # SMTP协议加密端口是465
server.set_debuglevel(1)               #调试级别

用set_debuglevel(1)就可以打印出和SMTP服务器交互的所有信息。

  • 发送邮件
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())

login()方法用来登录SMTP服务器,参数有两个, from_addr是用户输入的发件邮箱, password是发件邮箱的密码。

sendmail()方法就是发邮件,需要引入三个参数:

  • 第一个参数:from_addr是发件人的邮箱地址

  • 第二个参数:[to_addr] 是收件人的邮箱地址, 是列表形式。因为邮件可能一次发给多个人,使用列表,如果发送多个人,就写多个邮箱,中间使用逗号隔开。

  • 第三个参数:msg.as_string()把邮件内容MIMEText对象变成str。

  • server.quit()
    server.quit()语句,是邮件发送结束后,停止服务的意思.

(2)发送纯文本邮件代码

import smtplib
from email.mime.text import MIMEText

# 构造一个纯文本邮件
msg = MIMEText("hello world","plain","utf-8")
''' 第一个参数就是邮件正文,
    第二个参数是MIME的subtype,传入’plain’表示纯文本,最终的MIME就是’text/plain’,
    最后一定要用utf-8编码保证多语言兼容性。
'''

# 使用SMTP发送邮件
# 输入发件人Email地址课口令
from_addr = input("请输入发件人邮箱号码From:")
from_pwd = input("请输入发件人邮箱口令Password::")
# 收件人Email地址
to_addr = input("请输入收件人邮箱地址To:")
# 输入SMTP服务器地址:
smtp_server = input('请输入邮箱服务器地址SMTP server: ')

server = smtplib.SMTP_SSL(smtp_server, 465) # SMTP协议加密端口是25
server.set_debuglevel(1)
server.login(from_addr, from_pwd)
server.sendmail(from_addr, [to_addr], msg.as_string())
# 停止服务
server.quit()

如果出现以下错误:

在这里插入图片描述
出现这种错误, 就说明邮箱出现授权问题. 也就是邮箱的SMTP服务没有开启。

接下来,我们开启邮箱SMTP服务。不要慌,这个开启服务只在QQ邮箱客户端里设置即可。

打开QQ邮箱客户端, 输入账号,密码进去. 在QQ邮箱页面, 点击【设置】
在这里插入图片描述
点进【设置】页面进去,点击第二个选项,【账户】,往下滑动, 滑动在下方的时候, 出现如图内容:
在这里插入图片描述
这里, 我们的SMTP服务还是关闭状态, 我们点击【开启】按钮, 开启SMTP服务。然后验证短信。

验证结束后, 会出现一个弹框:
在这里插入图片描述
这个授权码, 就是以后我们运行代码,在输入密码的地方进行输入。

在这里插入图片描述
发送成功在这里插入图片描述

  • 版本2.0 —— 完整邮件
    仔细观察上图, 你会发现,现在还存在如下两个问题: 1.邮件没有主题; 2.收件人的名字没有显示为友好的名字
# 导包
import smtplib
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr,formataddr
'''
1、encoders模块负责编码 
2、Header模块负责处理邮件头 
3、MIMEText模块负责处理文本 
4、parseaddr模块与formataddr模块 负责将输入的内容格式化
'''

def _format_addr(s):
    name,addr = parseaddr(s)
    return formataddr((Header(name,"utf-8").encode(),addr))

# 发件人Email地址和口令
from_addr = input("From:")
from_pwd = input("pwd:")
# 收件人Email地址
to_addr = input("To:")
# 输入SMTP服务器地址:
smtp_server = input("SMTP server:")
# 邮件内容
content = '''
    桃之夭夭,灼灼其华。之子于归,宜其室家。
    桃之夭夭,有蕡其实。之子于归,宜其家室。
    桃之夭夭,其叶蓁蓁。之子于归,宜其家人。
'''
# 实例化MIMEText对象
msg = MIMEText(content,"plain","utf-8")
# 发件人
msg['From'] = _format_addr(u'python爱好者<%s>'%from_addr)
# 收件人
msg["To"] = _format_addr(u'管理员<%s>'%to_addr)
# 主题
msg["Subject"] = Header(u'来自xxx的问候。。。。','utf-8').encode()

server = smtplib.SMTP(smtp_server,465)
server.set_debuglevel(1)
server.login(from_addr,to_addr)
server.sendmail(from_addr,[to_addr],msg.as_string())
# 结束服务
server.quit()

收到的邮件是:
在这里插入图片描述

4. 发送HTML邮件

发送HTML邮件,而不是普通的纯文本文件怎么办?方法很简单,在构造MIMEText对象时,把HTML字符串传进去,再把第二个参数由plain变为html就可以了:

msg = MIMEText('<html><body><h1>Hello</h1>' +
    '<p>send by <a href="http://www.python.org">Python</a>...</p>' +
    '</body></html>', 'html', 'utf-8')

在这里插入图片描述

5 发送附件

如果Email中要加上附件怎么办?带附件的邮件可以看做包含若干部分的邮件:文本和各个附件本身,所以,可以构造一个MIMEMultipart对象代表邮件本身,然后往里面加上一个MIMEText作为邮件正文,再继续往里面加上表示附件的MIMEBase对象即可:

from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.mime.text import MIMEText
from email import encoders
import smtplib
from email.mime.base import MIMEBase
from email.utils import formataddr,parseaddr

# 发件人邮箱和口令
from_addr = input("From:")
from_pwd = input("Password:")

# 收件人邮箱吧地址
to_addr = input("To:")

# 服务器地址
smtp_server = input("smtp_server:")

def _from_addr(s):
    name,addr = parseaddr(s)
    return formataddr((Header(name,"utf-8").encode(),addr))

# # 邮件对象:
msg = MIMEMultipart()
msg["From"] = _from_addr("python爱好者<%s>"%from_addr)
msg["To"] = _from_addr("管理员<%s>"%to_addr)
msg['Subject'] = Header("来自SMTP的问候","utf-8").encode()

# 邮件正文是MIMEText:
msg.attach(MIMEText("send with file","plain","utf-8"))

# 添加附件就是加上一个MIMEBase,从本地读取一个图片:
with open('./1.jpg',"rb") as fp:
    # 设置附件的MIME和文件名,这里是jpg类型:
    mime = MIMEBase("image","jpg",filename="1.jpg")
    mime.add_header('Content-Disposition', 'attachment', filename='1.jpg')
    mime.add_header('Content-ID', '<0>')
    mime.add_header('X-Attachment-Id', '0')
    # 把附件的内容读进来:
    mime.set_payload(fp.read())
    # 用Base64编码:
    encoders.encode_base64(mime)
    # 添加到MIMEMultipart:
    msg.attach(mime)

server = smtplib.SMTP_SSL(smtp_server,465)
server.set_debuglevel(1)
server.login(from_addr,from_pwd)
server.sendmail(from_addr,[to_addr],msg.as_string())

server.quit()
  • 结果:
  • 在这里插入图片描述
    在这里插入图片描述

6. 发送图片

msg.attach(MIMEText('<html><body><h1>Hello</h1>' +
    '<p><img src="cid:0"></p>' +
    '</body></html>', 'html', 'utf-8'))
  • 效果
    在这里插入图片描述

同时支持HTML和Plain格式
如果收件人使用的设备太古老,我们发送HTML邮件,收件人通过浏览器或者Outlook之类的软件是可以正常浏览邮件内容的,但是,查看不了HTML邮件怎么办?

办法是在发送HTML的同时再附加一个纯文本,如果收件人无法查看HTML格式的邮件,就可以自动降级查看纯文本邮件。

利用MIMEMultipart就可以组合一个HTML和Plain,要注意指定subtype是alternative:

msg = MIMEMultipart('alternative')
msg['From'] = ...
msg['To'] = ...
msg['Subject'] = ...

msg.attach(MIMEText('hello', 'plain', 'utf-8'))
msg.attach(MIMEText('<html><body><h1>Hello</h1></body></html>', 'html', 'utf-8'))
# 正常发送msg对象...

7. 加密SMTP

使用标准的25端口连接SMTP服务器时,使用的是明文传输,发送邮件的整个过程可能会被窃听。要更安全地发送邮件,可以加密SMTP会话,实际上就是先创建SSL安全连接,然后再使用SMTP协议发送邮件。

某些邮件服务商,例如Gmail,提供的SMTP服务必须要加密传输。我们来看看如何通过Gmail提供的安全SMTP发送邮件。

必须知道,Gmail的SMTP端口是587,因此,修改代码如下:

smtp_server = 'smtp.gmail.com'
smtp_port = 587
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls()
# 剩下的代码和前面的一模一样:
server.set_debuglevel(1)
...

小结

使用Python的smtplib发送邮件十分简单,只要掌握了各种邮件类型的构造方法,正确设置好邮件头,就可以顺利发出。

构造一个邮件对象就是一个Messag对象,如果构造一个MIMEText对象,就表示一个文本邮件对象,如果构造一个MIMEImage对象,就表示一个作为附件的图片,要把多个对象组合起来,就用MIMEMultipart对象,而MIMEBase可以表示任何对象。它们的继承关系如下:

Message
+- MIMEBase
   +- MIMEMultipart
   +- MIMENonMultipart
      +- MIMEMessage
      +- MIMEText
      +- MIMEImage

总结

  本文属于作者原创,转载请注明出处,不足之处,希望大家能过给予宝贵的意见,如有侵权,请私信。每天一个knowledge point,一起学python,让技术无限发散

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Python独角兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值