Python发送邮件

1、主要功能介绍

邮件协议

在开始之前下面我们来认识一下邮件协议(POP3,IMAP,SMTP)

协议 功能
POP3 主要用于客户端远程管理服务器上的邮件
IMAP 交互式邮件访问协议
SMTP 简单邮件传输协议
下面就简单的来说一下各协议的区别,协议的详细内容可以自行查看网络资料,和相关书籍

POP3

POP3协议是Post Office Protocol 3的简称,即邮局协议的第3个版本,是TCP/IP协议族中的一员(默认端口是110)。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。

IMAP

IMAP全称是Internet Mail Access Protocol,即交互式邮件访问协议,是一个应用层协议(端口是143)。用来从本地邮件客户端(Outlook Express、Foxmail、Mozilla Thunderbird等)访问远程服务器上的邮件。

SMTP

SMTP的全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议(25号端口)。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。我们知道SMTP协议简单来说就是一个邮件发送的传输协议(不提供邮件接收功能),而POP3和IMAP这两个协议是邮件的接收(下载)协议。那么POP3和IMAP的区别是什么呢?

POP3和IMAP协议的区别

下面就来说一说这两个协议的主要区别。
虽然这两个协议都是从邮件服务器那里下载邮件到本地的协议,但是不同的是IMAP提供跟邮件服务器的双向通信,也即在客户端所作的更改会反馈给服务器端,跟服务器端形成同步(例如删除邮件,创建文件夹等等的操作)。而POP3是单向通信的,即下载邮件到本地就算了,所作的更改都只是在客户端,不会反映到服务器端。所以使用IMAP协议也会更便捷,体验更好,更可靠。

2、发送文本邮件

登陆服务器

首先要简历连接

这里使用的163邮箱,需要配置smtp地址、端口、邮箱用户名和密码以及接收人的信息


def send_txt_mail():

    smtp_server = 'smtp.163.com'
    mail_user = 'xxxx@163.com'
    mail_pass = 'password'

    # 邮件发送方邮箱地址
    sender = 'xxxx@163.com'
    # 邮件接受方邮箱地址,注意需要[]包裹,这意味着你可以写多个邮件地址群发
    receivers = ['xxxxxxxx@protonmail.com']
    subject = 'SEND YOU'
    # 邮件内容
    content = "send message by py!"

    # 邮件内容设置
    # plain 任何东西渲染为纯文本
    message = MIMEText(content, 'plain', 'utf-8')
    # 附件
    message['From'] = sender
    message['To'] = receivers[0]
    message['Subject'] = subject

    # 登录并发送邮件
    try:
        server = smtplib.SMTP(smtp_server, 25)
        server.starttls()
        server.login(mail_user, mail_pass)
        server.sendmail(sender, receivers, message.as_string())
        server.quit()
        print('success')
    except smtplib.SMTPException as e:
        print('error', e)  # 打印错误

如果是需要通过给多个联系人发生邮件的话 使用数组即可

    receivers = ['xxx@protonmail.com', 'xxx@gmail.com', 'xxxx@qq.com']
    # 登录并发送邮件
    try:
        server = smtplib.SMTP(smtp_server, 25)
        server.starttls()
        server.login(mail_user, mail_pass)
        for rec in receivers:
            # 邮件内容设置
            # plain 任何东西渲染为纯文本
            message = MIMEText(content, 'plain', 'utf-8')
            message['From'] = sender
            message['Subject'] = subject
            message['To'] = rec
            server.sendmail(sender, rec, message.as_string())
        server.quit()
        print('success')
    except smtplib.SMTPException as e:
        print('error', e)  # 打印错误

image-20210412110739938.png

3、发送富文本

对于一些想要复杂描述的,仅仅使用单一文本还不够 ,这就需要使用富文本,被解析成html内容。

即需要简历和html文件,本地被浏览器解析是什么样子,被可以发送邮件是什么样子,需要注意的是一个引入的文件可能加载不到。

建立html文件

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html" ;charset="utf-8">
    <title>A send real love email</title>
</head>
<body>
<div align="left">
    <p>亲爱的 :</p>
    <p>Dear:</p>
</div>
<p>
<h5 align="center">爱是恒久忍耐,又有恩慈。爱是不嫉妒。爱是不自夸。不张狂。</h5>
<h5 align="center">Love is patient, love is kind. It does not envy, it does not boast, it is not proud.
</h5>
</p>
<p>
<div align="center">
    <h5>不作害羞的事。不求自己的益处。不轻易发怒。不计算人的恶。</h5>
</p>
<p>
<h5>It is not rude, it is not self-seeking, it is not easily angered, it keeps no record of wrongs. </h5>
</p>
<p>
<h5>不喜欢不义。只喜欢真理。</h5></p>
<p>
<h5>Love does not delight in evil but rejoices with the truth. </h5></p>
<p>
<h5>凡事包容。凡事相信。凡事盼望。凡事忍耐。</h5></p>
<p>
<h5>It always protects, always trusts, always hopes, always perseveres.</h5></p>
</div>
<div align="center">
    <p>
    <h5> 爱是永不止息。</h5></p>
    <p>
    <h5> Love never fails.</h5></p>
</div>
<div align="right">
    <p><h6>上帝祝福你。</h6></p>
    <p><h6>GOD BLESS YOU.</h6></p>
</div>
</body>
</html>
# 读取文件,更改发送的类型即可
with open('../../file/love.html', 'r') as f:
    content = f.read()
message = MIMEText(content, 'html', 'utf-8')

如果引入图片或者文件,需要通过网络的方式会更好。

image-20210412113300919.png

4、发送附件

附件的内容,可以是图片文件或者文本文件


def to_163():
    smtp_server = 'smtp.163.com'
    mail_user = 'xxxx@163.com'
    mail_pass = 'password' 

    # 邮件发送方邮箱地址
    sender = 'xxxx@163.com'
    receivers = ['xxxx@protonmail.com']
    subject = 'LOVE YOU'
    # 邮件内容
    content = get_html_msg()
    # 添加附件地址
    part_img = get_att_image()
    part = get_att_file()
    # 邮件内容设置
    # 附件
    message = MIMEMultipart()
    message['From'] = sender
    message['To'] = receivers[0]
    message['Subject'] = subject

    # 邮件正文内容
    message.attach(MIMEText(content, 'html', 'utf-8'))
    # 构造附件
    message.attach(part)
    message.attach(part_img)
    # 登录并发送邮件
    try:
        server = smtplib.SMTP(smtp_server, 25)
        server.starttls()
        server.login(mail_user, mail_pass)
        server.sendmail(sender, receivers, message.as_string())
        server.quit()
        print('success')
    except smtplib.SMTPException as e:
        print('error', e)  # 打印错误


# 发送html文件内容到邮件
def get_html_msg():
    with open('../../file/love.html', 'r') as f:
        content = f.read()
    return content

# 发送附件内容到邮件
def get_att_image():
    path = '.../data/web/cat.jpg'
    with open(path, 'rb') as f:
        att3 = MIMEBase('image', 'png', filename='Red_Bag.png')
        att3.add_header('Content-Disposition', 'attachment', filename='Red_Bag.png')
        att3.add_header('Content-ID', '<0>')
        att3.add_header('X-Attachment-Id', '0')
        att3.set_payload(f.read())
        encode_base64(att3)
    return att3


# 发送附件内容到邮件
def get_att_file():
    path = '../../file/love.html'
    att2 = MIMEText(open(path, 'rb').read(), 'base64', 'utf-8')
    att2["Content-Type"] = 'application/octet-stream'
    att2["Content-Disposition"] = 'attachment; filename="ru.html"'
    return att2

这封示例邮件发送附件是文件和图片,需要需要读取文件的内容放入att2中,再构造附件message.attach(part)

image-20210412113322258.png

5、其他

需要引入的lib
from smtplib import SMTP_SSL
from email.encoders import encode_base64
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
import smtplib
import poplib
import base64

通过gmail和protonmail发送邮件,暂时没有成功,对于国内的qq、126邮箱应该都没有问题,直接更换发送的服务器地址就OK。

对于一些应该场景,可以发送一些预警,或者使用邮箱验证码等等。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容