问题描述: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定时任务的执行。

具体源代码见附件。

下载次数: 11

分享到:

2013-04-19 15:47

浏览 2904

评论

python邮件群发_Python操作Gmail@定时定向群发邮件相关推荐

  1. python发送邮件群发_Python发邮件脚本,Python调用163邮箱SMTP服务实现邮件群发

    邮件营销,一个昔日辉煌,如今没落的广告营销方式,曾经的恶意广告邮件群发,到现在还存留着的大站协议群发,可能还是有不少人能够做到正常群发邮件,但大概率很多人都不会点开邮件查看邮件内容吧,除非是很许可的, ...

  2. python elasticsearch模块_Python 操作 ElasticSearch

    Python操作ElasticSearch Python批量向ElasticSearch插入数据 Python 2的多进程不能序列化类方法, 所以改为函数的形式. 直接上代码: #!/usr/bin/ ...

  3. python邮件发送_Python实现邮件发送

    使用smtplib模块发送邮件,它对smtp协议进行了简单的封装. smtp协议的基本命令包括: HELO 向服务器标识用户身份 MAIL 初始化邮件传输 mail from: RCPT 标识单个的邮 ...

  4. python邮件转发_把Gmail邮件转发到gtalk的Python方法

    用Python方法把Gmail邮件转发到gtalk有多难,想知道gmail如何转发邮件?gmail自动转发已收到邮件的设置方法.本文就来把这段详细的python学习参考代码贴出来,大家一起参考下吧. ...

  5. python邮件模块_python 邮件模块

    Python内置对SMTP的支持,其中细化为smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件,我们仅仅需要编辑相关配置即可 1. 获取认证 在获取认证这一块我们需 ...

  6. python 邮件解析_Python解析邮件

    邮件的解析是个大课题,远超一般人的预期.它远比发送邮件和接收邮件要复杂的多的多. 这就是为什么网上中文外文搜邮件的问题,绝大多数都是讲发送的而讲接收的很少. 发送邮件好说,接收和下载邮件也好说.关键是 ...

  7. python 邮件抄送_Python 超简单的邮件发送方法

    在训练网络模型的时候,往往需要好几个小时,甚至十几个小时,由于时间不固定,所以有时候我去查看了好几次都没训练完,有时候训练结束很久了我才想起去看,所以我就想训练结束后自动给我发个邮件,这样我就可以专心 ...

  8. 用python播放音乐_Python实例讲解 -- 定时播放 (闹钟+音乐)

    自己写的闹钟, 只可以播放wav格式的音频. import time import sys soundFile = 'sound.wav' not_executed = 1 def soundStar ...

  9. python处理数据库_python操作数据库

    操作mysql image.png db_config = { 'user': 'root', 'password': 'qwe123', 'db': '数据库名', 'charset': 'utf8 ...

  10. python数据库实例_Python操作MySQL数据库9个实用实例

    用python连接mysql的时候,需要用的安装版本,源码版本容易有错误提示.下边是打包了32与64版本. MySQL-python-1.2.3.win32-py2.7.exe MySQL-pytho ...

最新文章

  1. nodejs安装、配置及开发工具
  2. hive-数据倾斜记录分享
  3. 【LeetCode】无重复字符的最长子串【滑动窗口法】
  4. CTFshow 信息收集 web18
  5. LeetCode 73矩阵置零74搜素二维矩阵75颜色分类
  6. IIS上部署asp.net core2.1项目
  7. RabbitMQ播放模块! 构架
  8. 学计算机的,怎么知道自己喜欢软件还是硬件
  9. ntent action大全
  10. 空间数据引擎oracle_空间数据库oracle
  11. 【Oracle】删除手工创建的数据库
  12. JavaScript -- DOM树
  13. 开关造成的毛刺_解决交易中的毛刺问题,你可以这样做
  14. mysql5.7.9 zip achive
  15. Java餐厅点餐系统【附源码报告】
  16. Spark SQL自定义函数案例(拼接字符串)
  17. Apifox测试Excel文件上传
  18. 关于Linux LOOPBACK网口抓包的一个细节
  19. Pytorch(GPU)配环境原理:cuda+cudnn+pytorch配环境的每一步到底干了些什么?
  20. 历尽千帆过尽,归来,又是一年毕业季

热门文章

  1. angular2-swiper的使用
  2. (个人)Linux基本指令收集
  3. 渴望成为架构师的你,或许需要与这些大咖来一场面基
  4. 如何利用ansible callback插件对执行结果进行解析
  5. Redis之利用锁机制来防止缓存过期产生的惊群现象
  6. OSPF在企业网络中的应用
  7. 关于PC机相关系统的远程桌面协作的相关介绍和配置(转帖整理)
  8. linux ubi代码分析,linux ubi文件系统
  9. 7建站php_2019最受欢迎的企业网站CMS建站系统排行榜
  10. git grep 全字匹配_git log --grep 筛选(转)