国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python自動發郵件腳本

2019-11-25 16:16:29
字體:
來源:轉載
供稿:網友

緣起

這段時間給朋友搞了個群發郵件的腳本,為了防止進入垃圾郵件,做了很多工作,剛搞完,垃圾郵件進入率50%,覺得還不錯,如果要將垃圾郵件的進入率再調低,估計就要花錢買主機了,想想也就算了,先發一個月,看看效果再拓展吧。

腳本主要是通過Python寫的,調的smtplib庫,這些是基礎,大家在網上一搜一大堆,今天主要給大家講解下如何避免進入垃圾郵件系統,以及整個系統搭建時的一些思想。可能剛搞Python不久,有很多可能是錯誤的寫法望大家提出來哈~

配置

CentOS7.0系統

Python 3.4

CentOS7.0下面默認的是Python2.7.5,我們先來將Python的版本提升上去

#wget https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz

下載Python3.4版本

#tar -xf Python-3.4.3.tgz#cd Python-3.4.3/#./configure

這邊configure的時候可能會遇到你的環境沒有安裝gcc編譯環境,執行下面的語句再configure即可

#yum -y install gcc#yum -y install gdb#yum -y install gcc-c++

編譯安裝

#make#make install

因為替換了python版本之后yum可能不能正常使用,需改兩個文件

#vim /usr/bin/yum#vim /usr/libexec/urlgrabber-ext-down

將這兩個文件的頭部的#!/usr/bin/python改成#!/usr/bin/python2.7即可,保存退出,yum滿狀態復活

編譯完了之后,將python3.4設置為默認python解析。

#ln -s /usr/local/bin/python3.4 /usr/bin/python

鏈接完成之后檢查python版本

#python -V

出現Python3.4就標識版本切換完成

系統架構

 

Account:用于存放發送者郵箱賬號的目錄,我的163郵箱,sina郵箱,sohu郵箱和tom郵箱均在淘寶上購買了30個可以發送smtp服務的賬號,花費一頓飯的錢不到就可以搞到啦~賬號密碼用【:】分割,每個賬號之間使用【,】分割。

Common:引用類文件夾,里面是日至系統配置文件和日志系統源代碼

Conf:全局配置文件,目前還木有用到

Image:郵件發送過程中需要使用到的圖片資源

Log:日志文件,按日期區分

Logbackups:日志備份文件,用于備份過期日志

Sendmail:用于存儲收件人的郵箱信息,賬號之間用【,】分割

mail_html.py:主要執行腳本

README.md:git版本控制用戶須知,我是通過碼云來管理我的代碼的

日志系統

提起腳本系統,日志是相當關鍵的一個角色,尤其是當你的腳本出錯,你要查錯的時候,就非常重要了,我也是從網上搞來的一段Log日志系統的代碼,覺得挺好用,供大伙參考~

主要思想是,打印log到指定文件,打印log到屏幕,啥也不說了,先上代碼,因為是網上的代碼,我就放上來啦~

# coding: utf-8#from lxml import etreeimport logging.handlersimport loggingimport osimport sysimport timeimport datetimetry:  import xml.etree.cElementTree as ET except ImportError:  import xml.etree.ElementTree as ET # 提供日志功能class logger: # 先讀取XML文件中的配置數據 # 由于config.xml放置在與當前文件相同的目錄下,因此通過 __file__ 來獲取XML文件的目錄,然后再拼接成絕對路徑 # 這里利用了lxml庫來解析XML root = ET.parse(os.path.join(os.path.dirname(__file__), 'config.xml')).getroot() # 讀取日志文件保存路徑 logpath = root.find('logpath').text # 讀取日志文件容量,轉換為字節 logsize = 1024*1024*int(root.find('logsize').text) # 讀取日志文件保存個數 lognum = int(root.find('lognum').text) # 添加分天日志名 now = datetime.datetime.now() now_time = now.strftime('%Y%m%d') log_file_name = sys.argv[0].split('/')[-1].split('.')[0] + '_' + now_time # 日志文件名:由用例腳本的名稱,結合日志保存路徑,得到日志文件的絕對路徑 logname = os.path.join(logpath, log_file_name) # 初始化logger log = logging.getLogger() # 日志格式,可以根據需要設置 fmt = logging.Formatter('[%(asctime)s][%(filename)s][line:%(lineno)d][%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S') # 日志輸出到文件,這里用到了上面獲取的日志名稱,大小,保存個數 handle1 = logging.handlers.RotatingFileHandler(logname, maxBytes=logsize, backupCount=lognum) handle1.setFormatter(fmt) # 同時輸出到屏幕,便于實施觀察 handle2 = logging.StreamHandler(stream=sys.stdout) handle2.setFormatter(fmt) log.addHandler(handle1) log.addHandler(handle2) # 設置日志基本,這里設置為INFO,表示只有INFO級別及以上的會打印 log.setLevel(logging.INFO) # 日志接口,用戶只需調用這里的接口即可,這里只定位了INFO, WARNING, ERROR三個級別的日志,可根據需要定義更多接口 @classmethod def info(cls, msg):  cls.log.info(msg)  return @classmethod def warning(cls, msg):  cls.log.warning(msg)  return @classmethod def error(cls, msg):  cls.log.error(msg)  return

日志系統的配置文件

<?xml version="1.0" encoding="utf-8"?><config> <!-- 日志保存路徑 --> <logpath>/Users/litao/Desktop/mail_html/Log</logpath> <!-- 每個腳本對應的日志文件大小,單位MB --> <logsize>8</logsize> <!-- 每個腳本保存的日志文件個數 --> <lognum>100</lognum></config>

保存的路徑各位隨意哈。

如何使用

logger.info('郵件總數量【'+str(len(recivers))+'】')                       logger.info('總計發送郵件數量【'+str(send_num)+'】')                       logger.info('總計發送錯誤數量【'+str(error_num)+'】')                      logger.info('成功郵箱賬號集合:'+','.join(send_success_account))                    logger.info('失敗郵箱賬號集合:'+','.join(send_failure_account))                    logger.info('腳本結束------------------------------------------------------------------')             logger.info('')

error的話將info換成error即可

執行主文件

提起垃圾郵件,大家首先想到的就是那個令人討厭的垃圾箱里面的營銷郵件,但是,如果你的郵件內容寫的很棒,是不是就可以避免被封殺,答案是否定的,郵件被封殺是機器干的,如果是機器干的事,那就好辦了,首先,我們得先知道機器的工作原理。

大部分被列為垃圾郵件的郵件均有兩個特征:內容不變,IP不變,其實做到內容一直變,IP一直變理論上就可以做到不進垃圾郵箱,但是哪有那么多的人力物力做這事,所以,我們要做的是解決概率性的問題。

內容混淆

內容不變我們可以使用多套模板,嵌套著發,這個問題好解決,但是IP不變,這個就難一點了,其實我也沒解決,主要是怕花錢,我能做的就是通過多套模板來實現內容概率性的不被封殺。

好了,我們先準備30個郵件的subject,30套郵件的內容模板,下面就是我的全局subject配置

 

這樣做的好處就是可以防止郵件的內容被封殺,假設我們30秒發一封郵件,那么在20分鐘內的郵件,沒有一封是重復的。我們是從接受郵箱域名的角度考慮的,也就是如果我們的營銷對象全是QQ郵箱,那么QQ郵箱的郵箱服務器在20分鐘內收到同一IP的郵件內容是不一樣的,這很大程度上就能避免被封殺。

賬戶混淆

設置這么多賬號是干嘛用的呢,主要還是想混淆機器,讓垃圾郵件進率更低。

下面我個人經過測試,發現郵箱服務器具有的一些特性。

163郵箱

163郵箱設置了每天每個賬號郵件發送的上限位50封,賬號554出錯重發的時間是3小時。

tom郵箱

tom郵箱每天郵件發送數量不做限制,我們也假設是50封,但是每封郵件之間的發送間隔一定要超過30秒,要不然會被短時間連接數過大報錯。

sohu郵箱

業界良心,基本上沒出過啥錯誤,一直保持著良好的發送成功率。我們也將其定位發送間隔30秒,每日上線50封。

sina郵箱

惡心的玩意兒,每次發送郵箱前需要先登錄,認證手機號,每個手機號5個郵箱哈,但是效果顯著,認證完畢,和sohu一樣,基本沒出錯過。

時間混淆

有了這些基礎,我們就可以知道了,我們有120個賬號,30個郵件模板,每天一刻不停的發送,每封郵件之間的間隔為30秒,一天的郵件發送量在2800封左右。

我覺得一天2800封,如果有錢的話,一臺ESC的費用是3元每天,獨立ip哈,如果找第三方發送,一封郵件是3分錢,量大2分錢,他們是EDM的,我測試過1500封,達到率不足千分之一。也就是說,我們發送1500封,只需要1塊多錢,找第三方發送,1500封怎么也得40塊錢。成本是不是很低。

好的,那就來看看郵件是如何發送的吧。

郵件發送

下面我們來看下我的主文件是如何搞的

#coding=utf-8import smtplibimport mimetypesimport timeimport datetimefrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.mime.image import MIMEImage#引入外部文件from Common.log import *

導入模塊,以來的外部庫和內部的文件

#目錄主位置
_root_dir = '/Users/litao/Desktop/mail_html/'
_title_common = '愚人節'
愚人節主題禮物,也是為了以后省事,subject和內容中設計到title的均會被改為愚人節,馬上愚人節了嗎,營銷方式,代碼實現,異常方便修改。

#郵箱內容設置_content = """/<html> <style> .title{font-weight:bold;font-size:18px;}</style> <body>  <p>   <img src="cid:image1">   <br><br>   <span   class="title">【愚人節】將至,您還沒準備禮物?那你一定會過個開心的愚人節的</span>   <br>   愚人節就要來啦,禮朵朵給大伙準備了大批量的禮物伴你度過愚人節,具體百度一下【禮朵朵】,趕緊進站選禮物吧~   <br>   選禮物前別忘了先去心愿墻許愿喲,你的愿望可能被禮朵朵看到,可以幫你實現喲,實現的時候別忘了來禮朵朵還愿哈~   <br><br>   <span class="title">【禮朵朵】介紹</span>   <br>   國人從古至今都有送禮的習俗,送禮作為傳統之一,一直流傳至今,禮尚往來成為人生必修課。   <br>   【禮朵朵】集合商業送禮和現代送禮搭建禮物導購分享平臺【朵朵禮物】,帶給老少皆宜的送禮分享體驗新體驗。   <br>   與此同時,禮朵朵還給大伙準備了禮物攻略【禮物說】,讓大家可以對禮物有個更全面的了解~   <br><br>   <span class="title">百度搜索【禮朵朵】,開啟你的禮物新旅程吧~</span>   <br><br>  </p> </body></html> """

營銷內容模板,html模式實現郵件的發送,少不了有模板~

#發送郵箱smtp地址_smtp_address = ['smtp.163.com','smtp.sina.cn','smtp.tom.com','smtp.sohu.com']

smtp地址數組,用于在不同的郵件服務器間切換。

def sendMail(sender,reciver,subject,content,passwd,smtpadd): username=sender password=passwd msg=MIMEMultipart('related') msg['Subject']=subject #html格式 html=content htm = MIMEText(html,'html','utf-8') msg.attach(htm) #構造圖片 fp=open(_root_dir+'Image/logo_small.png','rb') msgImage=MIMEImage(fp.read()) fp.close() msgImage.add_header("Content-ID", "<image1>") msg.attach(msgImage) fp2=open(_root_dir+'Image/yurenjie.png','rb') msgImage2=MIMEImage(fp2.read()) fp2.close() msgImage2.add_header('Content-Disposition', 'attachment',       filename="愚人節活動海報.jpg") msg.attach(msgImage2) msg['From']=sender msg['To']=reciver #發送郵件 smtp=smtplib.SMTP() smtp.connect(smtpadd) smtp.login(username, password) smtp.sendmail(sender, reciver, msg.as_string()) smtp.quit()

發郵件方法,里面有兩個地方需要注意,一個是

msgImage.add_header("Content-ID", "<image1>")msg.attach(msgImage)

將郵件模板中的image1的img標簽內容替換成我們想要的圖片

第二個

 fp2=open(_root_dir+'Image/yurenjie.png','rb') msgImage2=MIMEImage(fp2.read()) fp2.close() msgImage2.add_header('Content-Disposition', 'attachment',       filename="愚人節活動海報.jpg")

插入附件,圖片是一個海報,說起海報,強烈建議大家使用創客貼這個平臺,非常好用。

下面就是發送郵件啦!!!

#發送郵件 smtp=smtplib.SMTP() smtp.connect(smtpadd) smtp.login(username, password) smtp.sendmail(sender, reciver, msg.as_string()) smtp.quit()

通用方法,將文件中的以,分割的內容以數組形式返回

#讀取文件中的數據,并將使用,分割的數據變為數組def readFileToSplit(filepath): file_stream = open(filepath) try:  data = file_stream.read() finally:  file_stream.close() data_split = data.split(',') return data_split

主方法

1、切割賬號

2、切換郵件服務器

3、每發送一封郵件,休息25秒,切換賬號,繼續發送

4、日志記錄

5、錯誤處理

if __name__=="__main__": content=_content # 接收人的郵箱按照每天2000封來,每天的郵箱都需要更換,文件名最后以日期為準,郵件發送量以日志為準 recivers=readFileToSplit(_root_dir+'Sendmail/mail_test.txt') # 把4個郵箱的賬號都獲取到,方便下面for循環中使用 account_163=readFileToSplit(_root_dir+'Account/account163') account_sina=readFileToSplit(_root_dir+'Account/accountsina') account_tom = readFileToSplit(_root_dir+'Account/accounttom') account_sohu = readFileToSplit(_root_dir+'Account/accountsohu') # 獲取郵件發送模板 # 注意模板之間的切換 #log_file_stream = open(_root_dir+'log', 'w+') logger.info('') logger.info('腳本開始------------------------------------------------------------------') # 統計郵件發送量 send_num = 0 # 統計發送出錯量 error_num = 0 # 統計發送失敗的郵箱發送賬號 send_success_account = [] # 統計發送成功的郵箱發送賬號 send_failure_account = [] subject_num = len(_subject) # 最后統計沒有發出去的郵箱號,放到下日,繼續發送 for i in range(0, len(recivers)):  try:   sendindex = i - error_num   num = i % 30   account = account_163[num].split(':')   addindex=i%4   subjectindex = sendindex%subject_num   if addindex == 1:    account=account_sina[num].split(':')   elif addindex == 2:    account=account_tom[num].split(':')   elif addindex == 3:    account=account_sohu[num].split(':')   sender=account[0]   passwd=account[1]   smtpadd = _smtp_address[addindex]   #smtpstr=str('163')   sendMail(sender, recivers[sendindex], _subject[subjectindex], content, passwd, smtpadd)   #print('發送賬號', sender, '正在發送')   str_success_1 = '發送賬號【'+sender+'】正在發送'   logger.info(str_success_1)   #writeLog(log_file_stream,str_success_1)   #print('接收序號', i, recivers[i],'發送成功')   str_success_2 = '接受序號【'+str(i)+'】【'+recivers[sendindex]+'】發送成功'   #writeLog(log_file_stream,str_success_2)   logger.info(str_success_2)   logger.info('')   #print('')   send_num+=1   send_success_account.append(sender)   time.sleep(25)  except Exception as e:   #print('停止于:', i, recivers[i],',發送失敗')   str_failure_1 = '產生錯誤于:【'+sender+'】發送失敗'   #writeLog(log_file_stream,str_failure_1)   logger.error(str_failure_1)   #print(e)   str_failure_2 = str(e)   #writeLog(log_file_stream,str_failure_2)   logger.error(str_failure_2)   logger.info('')   error_num+=1   send_failure_account.append(sender)   #print('')   #break #print('安全抵達底部') #writeLog(log_file_stream,'腳本結束') set(send_success_account) set(send_failure_account) logger.info('郵件總數量【'+str(len(recivers))+'】') logger.info('總計發送郵件數量【'+str(send_num)+'】') logger.info('總計發送錯誤數量【'+str(error_num)+'】') logger.info('成功郵箱賬號集合:'+','.join(send_success_account)) logger.info('失敗郵箱賬號集合:'+','.join(send_failure_account)) logger.info('腳本結束------------------------------------------------------------------') logger.info('') #log_file_stream.close()

代碼就這么多,至于subject郵件主題和模板怎么搞,可以自由發揮哈,可以放在主執行文件中,也可以放到配置文件中,實現可以配置,這里就不再贅述啦

開工

下面就可以開工啦,直接到項目主目錄

#python mail_html.py

看到屏幕上有輸出就OK啦,下面就是等待收獲的季節

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 祁门县| 遂宁市| 肥西县| 包头市| 安吉县| 公安县| 迭部县| 探索| 太仆寺旗| 县级市| 礼泉县| 崇左市| 罗山县| 祁阳县| 汶川县| 嵊泗县| 来凤县| 元阳县| 新巴尔虎右旗| 丁青县| 鸡东县| 清涧县| 淮滨县| 通辽市| 无为县| 镇雄县| 顺义区| 屏南县| 德庆县| 密云县| 万山特区| 凌源市| 盘山县| 岳阳县| 高密市| 新沂市| 华容县| 德保县| 五指山市| 曲松县| 赤壁市|