开发环境没有网络,若想传文件必须通过外网发邮件给内网,经人审核后再内网发邮件给我,而且更麻烦的一封邮件携带的附件大小不能超过20M,而且每封还要写上与项目相关的主题。
首先人工将大文件压缩然后设置每卷大小为19M,放到一个文件夹里面。
然后遍历此文件夹下的所有压缩文件,利用Python的smtplib和email模块,对每个压缩文件进行邮件发送。
中途遇到的问题:
mtplib.SMTPDataError: (451, b'Error: queue file write error')
。解决办法:压缩文件大小最好在20M以内。msg = MIMEMultipart()
放到方法内,处于全局变量中。550:出错原因:该服务器IP的发信频率大幅度超过QQ邮箱限制。
QQ邮箱对来自相同IP的外部发信服务器有一定的频率限制:
1、超过每分钟发信量限制,此IP地址被禁止发信若干分钟。
2、超过每小时发信量限制,此IP地址被禁止发信若干小时。
3、超过每日发信量限制,此IP地址本日内禁止再发信。
4、以上频率限制数值属于QQ邮箱保密数据,恕不公开。
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
import smtplib
import random
from threading import Thread
import os
from config import *
def _format_addr(s):
"""添加头部信息"""
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
def installMsg(from_addr, to_addr, message, each_rar):
msg = MIMEMultipart()
msg['From'] = _format_addr('HUST<%s>' % from_addr)
msg['To'] = _format_addr('zytldq<%s>' % to_addr)
msg['Subject'] = Header(message, 'utf-8').encode()
msg.attach(MIMEText(message+",此附件用于信息中心ERP系统开发,请转发谢谢。", 'plain', 'utf-8'))
with open(each_rar, 'rb') as f:
# 设置附件的MIME和文件名,这里是rar类型:
mime = MIMEBase('rar', 'rar', filename=each_rar)
# 加上必要的头信息:
mime.add_header('Content-Disposition', 'attachment', filename=each_rar)
mime.add_header('Content-ID', '<0>')
mime.add_header('X-Attachment-Id', '0')
# 把附件的内容读进来:
mime.set_payload(f.read())
# 用Base64编码
encoders.encode_base64(mime)
#添加到MIMEMultipart
msg.attach(mime)
return msg
def sendRAR(email_user, to_addr, message, each_rar):
server = smtplib.SMTP(email_user[2], 25)
server.login(email_user[0], email_user[1])
msg = installMsg(server.user, to_addr, message, each_rar)
print("使用【%s】发送 ----> "%server.user, end="")
server.sendmail(server.user, [to_addr], msg.as_string())
server.quit()
if __name__ == '__main__':
#单线程版本
os.chdir(PATH)
failedEmail = []
for i in range(len(os.listdir())):
errors = 0
while errors < 5:
try:
sendRAR(random.choice(EMAIL_USERS), TO_ADDR, MESSAGE, os.listdir()[i])
print("第%d封邮件发送完成"%(i+1),"还有%d封"%(len(os.listdir())-i-1))
except Exception as e:
print("第%d封邮件发送【失败】,将重新发送!原因:%s"%(i+1, e))
errors += 1
if errors == 5:
failedEmail.append((i+1, e))
continue
break
print("-------------------压缩文件发送结果-------------------")
if not failedEmail:
print("文件全部发送完毕!")
else:
for i in failedEmail:
print("第%d封文件发送失败!错误原因:%s"%(i[0], i[1]))
"""多线程版本
os.chdir(PATH)
failedEmail = []
processList = []
for i in range(len(os.listdir())):
p = Thread(target = sendRAR, args = (random.choice(EMAIL_USERS), TO_ADDR, MESSAGE, os.listdir()[i])
p.start()
processList.append(p)
for i in range(len(processList)):
processList[i].join()
print("第%d封邮件发送完成"%(i+1),"还有%d封"%(len(os.listdir())-i-1))
print("邮件发送完毕")
"""