`

Python操作Gmail@定时定向群发邮件

阅读更多

问题描述:1. A向不认识的B、C、D发送了邮件,B、C、D业务繁忙,对于A的邮件可能不回复,但是A希望得到B、C、D的回复;

 

                  2. A的想法是在不删除收发邮件的基础上

                      第一天[手动],A向B、C、D发邮件,未得到回复

                      第二天[自动],发件箱的收件人列表[B、C、D],收件箱的发件人列表为[],目标列表[B、C、D],B回复

                      第三天[自动]发件箱的收件人列表[B、C、D、[B、C、D]],收件箱的发件人列表为[B],目标列表[C、D],C回复

                      第四天[自动]发件箱的收件人列表[B、C、D、[B、C、D][C、D]],收件箱的发件人列表为[B、C]目标列表[D],D不回复

                                            ......

                      第N天[自动]发件箱的收件人列表[B、C、D、[B、C、D][C、D]、D、D...D],收件箱的发件人列表为[B、C]目标列表[D],D不回复(可以手工终止)

 

                   3. A希望将以上自动部分做成定时任务,并尽可能的减少人工参与


工具环境:Win7(32bit)  Python2.7

解决过程:1. 使用python imap收邮件模块检查邮箱中的发件人列表和收件人列表,发现有发件人列表有不在收件人列表的项,都记录下来,作为自动发邮件的目标
连接登陆服务器
    mailServer = "imap.gmail.com" #imap收邮件模块的gmail服务器
    mailPort = 993 #gmail的imap协议通信端口
    mailUser  = "XXXXX@gmail.com" #账户
    mailPass = "XXXXX" #密码
    imapConnect = imaplib.IMAP4_SSL(mailServer, mailPort) #以SSL的形式连接gmail服务
    imapConnect.logout()imapConnect.login(mailUser, mailPass) #登陆
    imapConnect.logout() #退出
取收件箱的发件人列表
    imapConnect.select('INBOX') #进入收件箱
    att, receiveItems = imapConnect.search(None, 'ALL')
    fromList = [] #收件箱的发件人列表
    for item in receiveItems[0].split():
        pos, mailData = imapConnect.fetch(item, "(RFC822)")
        receiveText = mailData[0][1]
        receiveJson = email.message_from_string(receiveText)
        pattern = re.compile(r"<(.*?)>", re.I|re.X) #python的正则表达式切割,真的很好用
        fromList.extend(pattern.findall(receiveJson['From']))
获取发件箱的收件人列表
    imapConnect.select('[Gmail]/&XfJT0ZCuTvY-') #进入发件箱
    att, sentItems = imapConnect.search(None, 'ALL')
    toList = [] #发件箱的收件人列表
    for item in sentItems[0].split():
        pos, mailData = imapConnect.fetch(item, "(RFC822)")
        sentText = mailData[0][1]
        sentJson = email.message_from_string(sentText)
        toList.append(sentJson['To'])
对比收件人列表和发件人列表,获取未回复人的列表,作为目标
delList = [] #处理收件箱发件人列表中的子列表
    for item in fromList:
        itemList = item.split() #将发件人列表中的子列表变成发件人元素,注意是以空字符串切割(包括1个以上的空格字符)
        if len(itemList) > 1:
        delList.append(item)
        fromList.extend(itemList) #将子列表的元素加入发件人列表
    for rub in delList:
        del fromList[fromList.index(rub)] #删除发件人列表中的子列表
    delList = [] #处理发件箱收件人列表中的子列表
    for item in toList:
        itemList = item.split() #将收件人列表中的子列表变成收件人元素
        if len(itemList) > 1:
        delList.append(item)
        toList.extend(itemList) #将子列表的元素加入收件人列表
    for rub in delList:
        del toList[toList.index(rub)] #删除收件人列表中的子列表
    fromList = set(fromList) #变成集合,去除重复元素
    toList = set(toList) #变成集合,去除重复元素
    jobList = [] #获取未回复邮件的收件人列表,作为今天的发件对象
    for item in toList:
        if item not in fromList:
        jobList.append(item)
特别注意,imapConnect.select('[Gmail]/&XfJT0ZCuTvY-')、imapConnect.select('INBOX'),这里的发件箱类型、收件箱类型....不同类型的邮箱代码也不一样,可以通过for item in imapConnect.list():print item.split('分隔符')[下标]获得

                 2. 根据第一步的目标列表,使用python smtp群发邮件
连接登陆退出
    smtp = smtplib.SMTP()
    server = 'smtp.gmail.com:587' #smtp发邮件模块的gmail服务器
    userName = 'XXXXX@gmail.com' #账户
    passWord = 'XXXXX' #密码
    smtp.set_debuglevel(1) #输出调试信息
    smtp.connect(server) #连接服务器
    smtp.ehlo()
    smtp.starttls() #安全模式
    smtp.login(userName, passWord) #登录
    smtp.quit() #退出
添加信件头
    mailFrom = 'XXXXX@gmail.com' #发件人
    mailTo = argTo #收件人列表
    mailMain = MIMEMultipart('related') #设置邮件头
    mailMain.set_charset('utf-8')
    mailMain['Subject'] = subject
    mailMain['From'] = mailFrom
    mailMain['To'] = mailTo
    mailMain.preamble = 'This is a multi-part message in MIME format.'
添加信件内容
    mailAlternative = MIMEMultipart('alternative')
    mailMain.attach(mailAlternative)
    mailText = MIMEText(htmlText, 'html', 'gb2312') #邮件主信息
    mailAlternative.attach(mailText)
添加附件
    att = MIMEBase('application', 'octet-stream') #添加附件
    att.set_payload(open('C:\\Users\\HK\\Desktop\\杂事\\简历\\Resume.pdf', 'rb').read())
    encoders.encode_base64(att)
    att.add_header('Content-Disposition', 'attachment; filename="Resume.pdf"')
    mailMain.attach(att)
群发邮件
    smtp.sendmail(mailFrom, mailTo, content)
    time.sleep(30) #为了防止异常断开,添加睡眠时间
    特别注意,在邮件群发过程中,发现smtp.sendmail(....)的收件人不能为参数列表,那么就不能群发,然后我根据报错去阅读../Lib/email/header.py发现代码段1如下(其中s参数是传入的收件人参数)
                if chunks and chunks[-1].endswith(' '):
                    extra = ''
                else:
                    extra = ' '
                _max_append(chunks, s, maxlinelen, extra)from email.mime.base import MIMEBase
继续追查_max_append的来源,阅读../Lib/email/quoprimime.py发现代码段2
    def _max_append(L, s, maxlen, extra=''):
    if not L:
        L.append(s.lstrip())
    elif len(L[-1]) + len(s) <= maxlen:
        L[-1] += extra + s
    else:
        L.append(s.lstrip())
 原来最终的地方,列表使用append()方法添加元素,当然不能传入列表参数
 为了减小影响,又实现我的功能,我选择修改代码段1(header.py的源代码)替换为如下一段
        if isinstance(s,basestring):#单个字符串参数
            if chunks and chunks[-1].endswith(' '):
                    extra = ''
                else:
                    extra = ' '
                _max_append(chunks, s, maxlinelen, extra)
        if isinstance(s,list):#字符串列表参数
            for item in s:
            if chunks and chunks[-1].endswith(' '):
                        extra = ''
                    else:
                        extra = ' '
                    _max_append(chunks, item, maxlinelen, extra)L[-1] += extra + s
修改后,重新编译,群发邮件OK

                  3. 使用win7的dos命令at做定时任务,让它定时执行(只有管理员权限才能使用at命令),如下
 C:\windows\system32>at 14:10 /every:Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday "python C:\Users\HK\Desktop\Python\operateMail.py"
    或者
 C:\windows\system32>at 14:10 /every:Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday "C:\Users\HK\Desktop\Python\operateMail.py"
    这里的定时任务步骤,也可以使用python的OS模块写在脚本里,甚至还可以在脚本里控制at定时任务的执行。
    具体源代码见附件
   
分享到:
评论

相关推荐

    卷料回转库sw20可编辑_三维3D设计图纸_三维3D设计图纸.zip

    卷料回转库sw20可编辑_三维3D设计图纸_三维3D设计图纸.zip

    前端分析-2023071100789s+7

    前端分析-2023071100789s+7

    电磁场仿真:瞬态电磁场仿真.zip

    电磁领域系列仿真模拟教程,每个包10几个教程,从基础到精通,案例多多。

    嵌入式开发中ADC数据采集的多种软件滤波算法及其STM32工程应用

    内容概要:本文详细介绍了嵌入式开发中常用的几种软件滤波算法,旨在解决ADC采集数据中的误差问题。文中首先解释了限幅滤波、中位值滤波、递推平均滤波、一阶滞后滤波以及消抖滤波的基本原理和应用场景,并提供了相应的C语言代码实现。接着讨论了这些算法在实际项目中的优化技巧,如使用环形缓冲区、DMA传输、Q格式定点数运算等。最后强调了根据不同场景选择合适的滤波算法组合的重要性。 适合人群:从事嵌入式系统开发的技术人员,尤其是那些需要处理ADC采集数据的工程师。 使用场景及目标:适用于各类嵌入式系统的数据采集模块,特别是面对传感器数据不稳定的情况。目标是在不改变硬件的前提下,通过软件手段提高数据的可靠性和准确性。 其他说明:文章不仅提供了理论知识,还分享了许多实践经验,帮助读者更好地理解和应用这些滤波算法。同时提醒开发者要注意硬件层面的噪声处理,不要过分依赖软件滤波。

    光伏混合储能VSG并网仿真模型:解析VSG控制与储能协同优化

    内容概要:本文详细介绍了光伏混合储能系统的虚拟同步发电机(VSG)并网仿真模型。该系统由VSG控制模块、光伏PV模块、蓄电池以及超级电容组成。VSG通过有功-频率环和无功-电压环进行精确控制,确保系统稳定运行。光伏模块采用MPPT扰动观察法跟踪最大功率点,蓄电池提供稳定的恒功率输出,超级电容则用于快速响应瞬态负载变化。文中展示了各个模块的核心代码逻辑及其在仿真环境中的表现,强调了参数整定对系统性能的影响。 适合人群:电力电子工程师、新能源研究人员、仿真建模专家。 使用场景及目标:适用于研究光伏混合储能系统的并网控制策略,优化储能设备的协同工作,提高系统的稳定性和响应速度。目标是通过仿真验证系统在各种工况下的性能,为实际应用提供理论支持和技术指导。 其他说明:文章提供了丰富的代码片段和仿真案例,帮助读者深入理解各模块的工作原理和相互关系。同时,作者分享了许多调试经验和常见错误,有助于新手更快掌握相关技术。

    (河南)土木工程毕业实习报告(高层住宅小区).doc

    (河南)土木工程毕业实习报告(高层住宅小区).doc

    电子烟多芯支架装配sw20可编辑_三维3D设计图纸_三维3D设计图纸.zip

    电子烟多芯支架装配sw20可编辑_三维3D设计图纸_三维3D设计图纸.zip

    大学毕业生土木工程毕业实习报告范文3000字(范本).doc

    大学毕业生土木工程毕业实习报告范文3000字(范本).doc

    一个纯原生JavaScript实现的轮播图,使用了面向对象的方式实现

    一个纯原生JavaScript实现的轮播图,使用了面向对象的方式实现。 如果你想锻炼自己的编码能力,可以尝试实现这样的一个轮播图。 如果你想在项目中使用,也是一个不错的选择,当然记得将缺少的图标素材补充完整。 如果你在一个页面上需要用到多个轮播图,那更应该使用它了。

    前端开发Vue框架安装与环境配置指南:涵盖Node.js、Vue CLI及项目创建运行全过程

    内容概要:本文详细介绍了 Vue.js 的安装及环境配置流程。首先强调了 Vue.js 作为渐进式 JavaScript 框架的特点,然后逐步讲解了安装 Node.js 和 Vue CLI 的步骤,包括下载、安装和版本检查。接着,演示了如何使用 Vue CLI 创建新项目,并介绍了项目创建后的运行方法。最后,简述了如何在 Vue 项目中安装常用的第三方依赖,如 Axios、Vue Router 和 Vuex,为后续开发做好准备。; 适合人群:对前端开发感兴趣的初学者或有一定 JavaScript 基础的开发者。; 使用场景及目标:①掌握 Vue.js 的安装和环境配置;②学会使用 Vue CLI 创建和运行 Vue 项目;③了解如何在 Vue 项目中安装和使用常用第三方依赖。; 阅读建议:按照文档步骤依次操作,确保每一步都正确无误,特别是 Node.js 和 Vue CLI 的安装与版本检查。在创建和运行项目时,注意终端输出的信息,遇到问题及时查阅官方文档或社区资源。

    电磁场仿真:电磁波传播仿真.zip

    电磁领域系列仿真模拟教程,每个包10几个教程,从基础到精通,案例多多。

    STM32-宿舍语音助手.zip

    STM32-宿舍语音助手.zip

    Xilinx FPGA千兆以太网与DDR4内存读写测试:基于KCU105/KC705平台的LWIP通信及DDR4读写工程代码

    内容概要:本文详细介绍了基于Xilinx KCU105/KC705平台的千兆以太网与DDR4内存读写测试工程代码。首先,文章讲解了LWIP轻量级TCP/IP协议栈的实现,包括网络接口初始化、内存池配置等。其次,探讨了DDR4内存控制器的设计,涵盖VHDL代码示例及其工作原理。最后,文章讨论了如何将这两部分整合到一个完整的工程项目中,解决了时钟域同步、资源分配和接口适配等问题,并展示了性能测试结果。 适合人群:从事FPGA开发的技术人员,尤其是关注高速数据处理和网络通信领域的工程师。 使用场景及目标:适用于需要实现高速数据传输和存储的应用场景,如实时数据采集、信号处理等。目标是掌握千兆以太网通信和DDR4内存读写的实现方法,提高系统的数据处理能力和稳定性。 其他说明:文中提供的代码片段和调试技巧有助于开发者快速上手并解决问题。此外,作者分享了许多实践经验,如PHY芯片配置、AXI总线优化等,对于初学者和有一定经验的开发者都有很大帮助。

    电大土木工程专业毕业论文31774.doc

    电大土木工程专业毕业论文31774.doc

    镍氢电池智能检测生产线sw17可编辑_三维3D设计图纸_三维3D设计图纸.zip

    镍氢电池智能检测生产线sw17可编辑_三维3D设计图纸_三维3D设计图纸.zip

    光伏储能充电Simulink仿真模型:详解恒流恒压及两阶段充电模式

    内容概要:本文详细介绍了基于Simulink平台构建的光伏储能充电仿真模型,涵盖了光伏发电模块、锂电池模型和充电控制策略的设计与实现。文中首先描述了整体架构,包括带MPPT的Boost电路用于光伏发电,二阶RC等效电路用于电池建模,以及充电控制模块中的三种充电模式(恒流、恒压、两阶段混合)及其切换逻辑。接着,作者分享了调试过程中遇到的一些常见问题及解决方案,如RC参数匹配不当引起的震荡、充电模式切换时的电流冲击、光伏输出与电池电压不匹配等问题。最后,通过对不同充电模式的仿真结果进行对比分析,展示了两阶段混合模式在充电效率和稳定性方面的优势。 适合人群:从事光伏储能系统研究与开发的技术人员,尤其是对Simulink仿真工具有一定基础的研究人员。 使用场景及目标:适用于希望深入了解光伏储能系统内部工作原理和技术细节的专业人士,旨在帮助他们掌握如何利用Simulink搭建高效稳定的充电控制系统,优化系统性能。 其他说明:文中提供了详细的参数设置指南和调试技巧,有助于读者快速上手并成功复现实验结果。同时,作者还分享了一些未公开的小技巧和隐藏功能,增加了模型的趣味性和实用性。

    前端分析-2023071100789s+12

    前端分析-2023071100789s+12

    电磁仿真:电磁场基础理论.zip

    电磁领域系列仿真模拟教程,每个包10几个教程,从基础到精通,案例多多。

    基于SSM的银行账目管理系统设计与实现.docx

    基于SSM的银行账目管理系统设计与实现.docx

Global site tag (gtag.js) - Google Analytics