Python实现群发邮件_python smtpobj.sendmail( 接收者可以写多个人么?-程序员宅基地

技术标签: python  python习题  

邮箱设置

在开始代码前,我们需要先对我们的邮箱做一些设置,以保证我们能较好地实现群发邮件功能。

IMAP/SMTP协议

先了解下什么是IMAP、SMTP。
SMTP 的全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器就是遵循 SMTP 协议的发送邮件服务器。
IMAP全称是Internet Mail Access Protocol,即交互式邮件存取协议,它是跟POP3类似邮件访问标准协议之一。不同的是,开启了IMAP后,您在电子邮件客户端收取的邮件仍然保留在服务器上,同时在客户端上的操作都会反馈到服务器上,如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作。所以无论从浏览器登录邮箱或者客户端软件登录邮箱,看到的邮件以及状态都是一致的。

网易邮箱/qq邮箱设置

邮箱可以选择163邮箱或者qq邮箱。
这里选网易邮箱做示范的话:
打开设置:
在这里插入图片描述
开启即可:
在这里插入图片描述
OK,准备工作结束!
(QQ邮箱的步骤类似,可自己尝试下)

smtplib库和email.mime.text库的了解

smtplib库

简单了解下,它其实就是一个对stmp协议封装了的库,使用它能快捷遍历的发送电子邮件,语法如下:

import smtplib

smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )

email.mime.text库

对于这个库,主要是使用其MIMEText这个函数,它的功能是构造邮件,例如:

msg = MIMEText(content, "html", "utf-8")

第一个参数是邮件正文,第二个参数MIME的subtype,传入html表示网页,最后跟上一个utf-8,保证语言的兼容性。

开始代码

CSV文件读写收件人信息

第一步,初始化,给收件人文件命名为receiver_list.csv,并写入【姓名,邮箱】这一行数据进去(后面讲为什么这么写)。

def init():
    receivers_list = open("receivers_list.csv", "w", newline="")

    # 将文件加载到csv对象中
    writer = csv.writer(receivers_list)

    writer.writerow(["姓名", "邮箱"])
    receivers_list.close()

第二步,读入数据功能
将刚才初始化的文件加入到csv对象中。

writer = csv.writer(receivers_list)

然后通过一行一行写入的方式,写入一条一条的收件人数据:

writer.writerow([name,address])

整体代码如下:

def member_writer():
    receivers_list = open("receivers_list.csv","a",newline="")

    #将文件加载到csv对象中
    writer = csv.writer(receivers_list)

    #格式
    while True:
        name = input("请输入收件人姓名")
        address = input("请输入邮件地址")
        writer.writerow([name,address])
        end = input("如果输入完毕,键入q退出")
        if end=="q":
            break

    receivers_list.close()
   

第三步,读取收件人信息
还是先加入csv对象:

#读csv文件
csvfile_1 = open("csv_test.csv","r")

这里有两种读取方式:
1.以列表的形式输入2.以字典的形式输出
先看列表,我们读取存好的数据:

reader_1 = csv.reader(csvfile_1)

rows1 = [row1 for row1 in reader_1]
print(rows1)
print(rows1[1][0])

输出:

[['姓名', '邮件地址'], ['朱宏程', '[email protected]'], ['broly', '[email protected]']]

是一个列表,将输入的成对数据以列表的形式返回。

再看字典

reader_2 = csv.DictReader(csvfile_1)

for row2 in reader_2:
    print(row2)
csvfile_1.close()

输出:

{
    '姓名': '朱宏程', '邮件地址': '[email protected]'}
{
    '姓名': 'broly', '邮件地址': '[email protected]'}

看,他把我们初始化输入的【姓名,邮箱】当成了字典的key,而后续我们的输入成了value,这样我们就能通过key来索取value,方便快捷。
所以,这里我们选用第字典输出作为读取方式。

将读出的数据分别存在name,address列表中,很显然他们是一一对应的关系。

    for row in reader:
        name.append(row["姓名"])
        address.append(row["邮箱"])
    return name, address

构建邮件信息

键盘读入邮件主题、内容
这里其实也可以键入发送人邮箱和密码,但是由于输入比较繁琐所以略去,提前设置好一个账号密码。(安全起见,密码略去了)

    subject = input("请输入邮件的主题")  # 邮件的主题

    # content = "<a href='https://movie.douban.com/subject/1292217/' > 深夜的穆赫兰道发生一桩车祸,女子丽塔(劳拉·赫利 Laura Harring 饰)在车祸中失了忆。她跌跌撞撞来到一个公寓里藏身。。。.</a>"  # 邮件内容
    content = input("请输入邮件的内容")
    sender = "[email protected]"  # 发件人
    password = '************'  # 刚才我们在163邮箱里设置的授权密码

开始发送邮件
组装邮件
使用上面讲过的MIMEText构成message
并分别对应写入发件人、收件人、邮件主题的对应信息。

message = MIMEText(content, "html", "utf-8")
        message["From"] = sender
        message["To"] = receiver
        message["Subject"] = subject

使用stmp链接服务器,然后登入,发送邮件。
值得一提的是这里的端口号有多种选择,在具体实践中发现163邮箱使用994比较容易成功请求,而qq邮箱使用465易成功。

smtp = smtplib.SMTP_SSL('smtp.163.com', 994)#qq用465,163用994
        smtp.login(sender, password)
        smtp.sendmail(sender, [receiver], message.as_string())

总体代码
上面两部分代码其实是写在一起的,总体是这样:

import smtplib
from email.mime.text import MIMEText
import time

def sendEmail(address, name):
    subject = input("请输入邮件的主题")  # 邮件的主题

    # content = "<a href='https://movie.douban.com/subject/1292217/' > 深夜的穆赫兰道发生一桩车祸,女子丽塔(劳拉·赫利 Laura Harring 饰)在车祸中失了忆。她跌跌撞撞来到一个公寓里藏身。。。.</a>"  # 邮件内容
    content = input("请输入邮件的内容")
    sender = "[email protected]"  # 发件人
    password = '**************'  # 刚才我们在163邮箱里设置的授权密码


    order = 0
    for receiver in address:
        message = MIMEText(content, "html", "utf-8")
        message["From"] = sender
        message["To"] = receiver
        message["Subject"] = subject

        smtp = smtplib.SMTP_SSL('smtp.163.com', 994)#qq用465,163用994
        smtp.login(sender, password)
        smtp.sendmail(sender, [receiver], message.as_string())
        smtp.close()
        time.sleep(1)

        order += 1
        print("成功发送第{}份,接收方是{}".format(order,name[order-1]))

    print("成功发送所有,共计{}份".format(order)

代码实践

正式跑一下试试:
随机抽取幸运观众
在这里插入图片描述

启动群发

import receivers
import SendEmail
# receivers.init()
# receivers.member_writer()
x, y = receivers.member_reader()

SendEmail.sendEmail(y,x)

输出邮件主题、内容
在这里插入图片描述
在这里插入图片描述

结果:
在这里插入图片描述

总结

代码主体难度不高,主要是考察对一些stmplibemail.mime.text库的运用和对csv文件操作的掌握。
我的代码总体偏简单,没有做过多的复杂操作,比如缺少对不规范输入检测,导致程序比较脆弱,如果不按正确格式输入就很难完整运行。除此之外,邮件内容的输入也做的过于简单,没有考虑实际需求,例如如果需要在邮件中附加图片、视频或者超链接等功能都没实现,只能简单文字内容,过于单一,这都是可以改进的地方。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/brolyLoveEng/article/details/123636868

智能推荐

taro使用vantweapp框架_怎么在taro里使用vant组件库的输入框-程序员宅基地

文章浏览阅读641次。http://taro-docs.jd.com/taro/docs/next/vant/以上是官网地址 根据官网提供的代码找到dist文件 然后呢进行配置 打开就可以了_怎么在taro里使用vant组件库的输入框

html基础--表单_html单选框name-程序员宅基地

文章浏览阅读169次。介绍一些常用表单,包括文本输入框、单选框、email输入框等以及一些demo_html单选框name

Android P 适配 (二)将应用迁移到 Android P_安卓p 开发适配-程序员宅基地

文章浏览阅读3.5k次,点赞2次,收藏2次。Android P(API 级别 P)引入了行为变更以及您的应用中可加以利用的新功能和 API。本文概述了将应用迁移到 Android P 的两个关键阶段的步骤:确保兼容 Android P验证您的应用能够在新版本平台上全功能运行。在此阶段,您不需要使用新的 API,也不需要更改应用的 targetSdkVersion,但可能需要进行一些细微的更改。更新您的目标版本并使用 Android P 功能..._安卓p 开发适配

jupyter 远程连接服务器,在本地浏览器中编辑代码_jupyter notebook本地改服务器代码-程序员宅基地

文章浏览阅读198次。一、配置基础部分参考博客:https://blog.csdn.net/weixin_40787712/article/details/106678293二、接下来的配置1.先使用电脑自带的xshell打开远程连接,然后切换到自己新建的jupyter notebook的虚拟环境中(本人是notebook)2.torch安装命令:pip install torch1.7.1+cu101 torchvision0.8.2+cu101 torchaudio==0.7.2 -f https://downloa_jupyter notebook本地改服务器代码

MAC上环境变量PATH的几种配置方法_mac path 配置多个-程序员宅基地

文章浏览阅读3.6k次。Mac一般使用bash作为默认shell。环境变量的加载顺序为:/etc/profile /etc/paths ~/.bash_profile ~/.bash_login ~/.profile ~/.bashrc当然/etc/profile和/etc/paths是系统级别的,系统启动就会加载,后面几个是当前用户级的环境变量,按照从上到下的顺序读取,如果~/.bash_p_mac path 配置多个

【Windows】服务程序_服务报startpending-程序员宅基地

文章浏览阅读671次。修改服务启动后失败重启设置ChangeServiceConfig2 SERVICE_FAILURE_ACTIONS sdBuf={0}; BOOL bSuccess=TRUE; if (argc!=2) { return 1; } // Open a handle to the service. SC_HANDLE sch=OpenSCManager(..._服务报startpending

随便推点

Map有序转成有序json_map序列化json-程序员宅基地

文章浏览阅读559次。Map有序转成有序json项目里要对一些签名的请求值签名,后台来验签,本来的是使用一些特殊的方法直接序列化的,下面给出例子。后来使用自定义的签名方法,得要自己序列化,以便于和后台验签方法一致。之前的Map序列化 //代码片 List<Map.Entry<String, Object>> mappingList = null; mappingList = new ArrayList<Map.Entry<String, Object>>(signMap._map序列化json

MATLAB麻雀优化CNN超参数分类_为什么用优化算法优化cnn-程序员宅基地

文章浏览阅读6.5k次,点赞19次,收藏149次。在CNN分类器模型的构建中,涉及到特别多的超参数,比如:学习率、训练次数、batchsize、各个卷积层的卷积核大小与卷积核数量(feature map数),全连接层的节点数等。直接选择的话,很难选到一组满意的参数,因此可以用优化算法进行超参数优化,虽然过程比较慢,但是总比自己无脑试的效果好。 基于此思想,本文采用麻雀优化算法,对CNN上述9个超参数进行优化。1,麻雀优化算法原理 麻雀优化是2020年提出来得,具体原理:原理点这里2、麻雀优化CNN的..._为什么用优化算法优化cnn

如何彻底的删除MySQL数据库(注册表未清理,请查清理注册表的)_如何删除注册表里面的mysqlcsdn-程序员宅基地

文章浏览阅读973次。以下操作以Window7操作系统为例:1)停止window的MySQL服务。找到“控制面板”-> “管理工具”-> “服务”,停止MySQL后台服务。2)卸载MySQL安装程序。找到“控制面板”-> “程序和功能”,卸载MySQL程序。3)删除MySQL安装目录下的所有文件。(删除安装的文件夹)4)删除c盘ProgramDate隐藏目录中关于MySQL的目录。(删除文件存放的文件夹)4.1 打开window系统的“显示隐藏文件”功能,以便查看到系统的所有隐藏文件4.2 _如何删除注册表里面的mysqlcsdn

js正则表达式应用_"var str=\"hello,everyone.my name is gui, 18 years-程序员宅基地

文章浏览阅读572次。2012年3月19日 天气有雨 没事找事找 不懂得拒绝 招来的事 往心里面咽! //js中正则表达式学习 //var re=new RegExp();//RegExp是一个对象,但这样没什么效果,需要将正则表达式的内容作为字符串传进去 //re=new RegExp("a");//创建一个匹配a字符的表达式_"var str=\"hello,everyone.my name is gui, 18 years old.\"; var arr="

Java最新大厂面试真题总结:java文件传输框架-程序员宅基地

文章浏览阅读65次。话不多说,先上张图一、微服务必备技能:二、一起从浅入深理解DUBBO!**先来看一份DUBBO脑图:**HelloWorld+前置知识+适合群体+架构(核心点:生产者 消费者问题特点:连通性,健壮性,伸缩性,升级型、节点调用关系图)什么是Dubbo(分布式服务框架+RPC远程调用解决服务+SOA服务治理方案)Dubbo的由来(需要解决的问题:1、依赖管理 2、路由透明 3、服务治理)主要是对Dubbo总体的介绍,让大家对Dubbo有一个总体的认识。首先介绍后台应用架构的演进过程,从最初_java文件传输框架

字符编码和python使用encode,decode转换utf-8, gbk, gb2312_encoding.textencoder("gb2312-程序员宅基地

文章浏览阅读264次。ASCII码标准ASCII码使用7位二进制数表示大写或小写字母,数字0到9标点符号以及在美式英语中使用的特殊控制字符。在标准ASCII码中,最高位(b7)用作奇偶校验位,所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分寄校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶..._encoding.textencoder("gb2312

推荐文章

热门文章

相关标签