python自動讀取郵件處理併發送

背景:須要讀取郵件,對提交的申請進行處理,而後回覆郵件。很是繁瑣,想要利用python實現自動處理。html

第一步:經過IMAP協議讀取未讀郵件ID;解析標題和郵箱地址。python

第二步:數據處理,標題提取出帳號;不符合規範的手動處理;提取標題符合規範的郵件對應郵箱地址。正則表達式

第三步:經過SMTP協議批量發送郵件。服務器

 

python3 imaplib庫的官方文檔
https://docs.python.org/3/library/imaplib.html?highlight=imaplib#module-imaplib
python3 email庫的官方文檔
https://docs.python.org/3/library/email.html?highlight=email#module-email併發

 

1、經過IMAP協議讀取文件,並提取標題和發件箱信息。

 

  IMAP(Internet Mail Access Protocol,Internet消息訪問協議)是斯坦福大學在1986年開發的一種郵件獲取協議。IMAP協議運行在TCP/IP協議之上,使用的端口是143。經常使用的版本是IMAP4。app

  它與POP3協議的主要區別是用戶能夠:
  •   不用把全部的郵件所有下載,能夠經過客戶端直接對服務器上的郵件進行操做。
  •   有選擇的從郵件服務器接收郵件的功能、基於服務器的信息處理功能和共享信箱功能。
  •   經過瀏覽信件頭來決定是否收取、刪除和檢索郵件的特定部分
  •   在服務器上建立或更改文件夾或郵箱。
  •   支持脫機操做模式,不一樣於POP3,它不會自動刪除在郵件服務器上已取出的郵件
  •   還支持聯機操做和斷鏈接操做,將郵件服務器做爲「遠程文件服務器」進行訪問,更加靈活方便。
  •   IMAP4支持多個郵箱。
  IMAP4的這些特性很是適合在不一樣的計算機或終端之間操做郵件的用戶(例如你能夠在手機、PAD、PC上的郵件代理程序操做同一個郵箱),以及那些同時使用多個郵箱的用戶。
 
1.鏈接郵箱服務器並登陸。
 1 # -*- coding:utf-8 -*-
 2 # 登陸郵箱併發送郵件。
 3 import imaplib
 4 import email
 5 from email.header import decode_header
 6 
 7 '''第一部分:收件IMAP4********************************************'''
 8 '''登陸郵箱IMAP4=========================================================='''
 9 from_addr = 'a@b.com'  # 發件郵箱
10 password = 'password'  # 郵箱密碼(或者客戶端受權碼)
11 imap_server = 'imap.qiye.163.com'
12 
13 try:
14     email_server = imaplib.IMAP4_SSL(imap_server, 993)  #網易企業郵箱服務器及SSL端口
15     print("imap4 服務器鏈接成功")
16 except:
17     print("imap4 服務器鏈接失敗")
18     exit(1)
19 
20 try:
21     email_server.login(from_addr, password)
22     print("imap4 帳號密碼正確,登陸成功")
23 
24 except:
25     print("imap4 帳號密碼不正確,登陸失敗")
26     exit(1)

2.獲取未讀郵件ID,解析郵件標題和郵箱地址。測試

 1 ''' 郵箱中收到的未讀郵件的數量=========================================================='''
 2 email_server.select()
 3 #未讀郵件封數 email_unseen_count
 4 email_unseen_count = len(email_server.search(None, 'UNSEEN')[1][0].split())  #全部未讀郵件
 5 print('未讀郵件一共有:',email_unseen_count,'')
 6 #獲得全部未讀郵件標號ID的byte格式 email_unseen_id_byte [b'5255', b'5256', b'5257']
 7 email_unseen_id_byte = email_server.search(None, 'UNSEEN')[1][0].split()  #[b'5255', b'5256', b'5257']
 8 
 9 #獲得全部未讀郵件標號將byte格式轉爲爲str email_unseen_id ['5255', '5256', '5257', '5258']
10 email_unseen_id = []
11 count_byte = 0
12 for row in email_unseen_id_byte:
13     email_unseen_id.append(row.decode('utf-8'))
14 print(email_unseen_id)
15 
16 '''讀取郵件標題,地址========================================================='''
17 # 經過fetch(index)讀取第index封郵件的內容
18 sub_list = []
19 addr_list = []
20 
21 #對每一封郵件進行處理
22 for a in email_unseen_id:
23     # 獲取郵件主題和地址信息,byte格式
24     typ, email_content = email_server.fetch(f'{a}'.encode(), '(RFC822)')
25     mail_text = email_content[0][1]
26     msg = email.message_from_bytes(mail_text)
27     subject = msg['Subject']
28     email_from = msg['from']
29     subdecode = decode_header(subject)   #[(b'\xc9\xed\xdd\xc8\xcf\xd6\xbb\xd8\xcc\xc2\xeb', 'gb18030')]
30     from_decode = decode_header(email_from)  # [(b'"', None), (b'\xd0\xa1\xe3', 'gb18030'), (b'" <3825@qq.com>', None)]
31     print(from_decode)
32 
33     #將郵件信息由byte格式轉換爲str
34     if subdecode[0][1] == None:    #[(b'"', None), (b'\xd8\xafA1\xc9\xb5\xb9\xcf', 'gb18030'), (b'" <970@qq.com>', None)]
35         print(subdecode[0][1])
36 
37     else:
38         addr_list.append(addr_list.append(from_decode[2][0].decode('utf-8')))
40         sub_list.append(subdecode[0][0].decode(subdecode[0][1]))  #<class 'str'>
41 
42 print('sub_list:', sub_list) #['找回', '楊 1702']
43 print('addr_list:', addr_list)   # ['" <385@qq.com>', '" <51@qq.com>']

3.關閉IMAP鏈接fetch

1 '''關閉IMAP4 select========================================================='''
2 # 關閉select
3 email_server.close()
4 # 關閉鏈接
5 email_server.logout()

2、數據處理:提取能處理的帳號和郵箱地址

1.提取標題中含有8位或10位的數字,其他用X標記ui

 1 import re # 使用正則表達式提取數字。 https://blog.csdn.net/qq_38486203/article/details/80309478
 2 import pandas as pd
 3  
 5 '''提取帳號============================================='''
 6 sub_op = []
 7 addr_op = []
 8 
 9 sub_op_f = []
10 addr_op_f = []
11 
12 count = 0
13 count_f = 0
14 
15 for a in sub_list:
16     if re.findall(r'\d+',a) == []:
17         sub_op_str = 'x'
18     else:
19         sub_op_str_num = str(re.findall(r'\d+',a))[2:-2]
20         #選出8位或10位帳號
21         if len(sub_op_str_num) == 8 or len(sub_op_str_num) == 10:
22             sub_op_str = sub_op_str_num
23         else:
24             sub_op_str = 'x'
25     sub_op.append(sub_op_str)
26 
27 print("郵件主題中的帳號爲:",sub_op,';') #['x', '1700000000', 'x']

 

2.提取有效郵件對應的郵箱spa

'''提取郵箱地址============================================='''
for b in addr_list:
    addr_op_str = b.strip()[3:-1]  #去掉頭尾 ['" <38@qq.com>', '" <31@qq.com>']
    addr_op.append(addr_op_str)

#print(addr_op)   #['38@qq.com', '31@qq.com', 'a1@qq.com']

'''刪除主題用X標記的帳號和地址============================================='''
for c in sub_op:
    if c == 'x':
        count = count+1
    else:
        sub_op_f.append(sub_op[count])
        addr_op_f.append(addr_op[count])
        count = count+1

print("郵件中地址爲:",addr_op_f)  # <class 'list'>

3.利用pandas讀取並保存爲csv備查

 1 '''把這一批次全部讀取的帳號地址和處理的帳號地址都導出到EXCLE存檔備查============================================='''
 2 import pandas as pd
 3 # 讀取全部未讀主題,帳號,地址並保存
 4 data_unseen = [sub_list,sub_op,addr_op]
 5 data_unseen1 = pd.DataFrame(data_unseen)
 6 data_unseen1.to_csv('data_unseen.csv',sep=',', header=True, index=True,encoding='utf_8_sig')
 7 
 8 # 讀取全部已處理郵件的主題,帳號,地址並保存
 9 data_op = [sub_list,sub_op_f,addr_op_f]
10 data_op1 = pd.DataFrame(data_op)
11 data_op1.to_csv('data_op.csv',sep=',', header=True, index=True,encoding='utf_8_sig')

3、發送郵件

1.鏈接SMTP服務器並登陸

 1 # 登陸郵箱併發送郵件。
 2 from email.mime.text import MIMEText
 3 from email.header import Header
 4 import smtplib
 5 
 6 #登陸郵箱
 7 smtp_server = 'smtp.qiye.163.com'  # 企業郵箱地址,如果我的郵箱地址爲:smtp.163.com
 8 server = smtplib.SMTP_SSL(smtp_server, 994)  # 第二個參數爲默認端口爲25,這裏使用ssl,端口爲994
 9 from_addr = 'a@b.com'  # 發件郵箱
10 password = 'password'  # 郵箱密碼(或者客戶端受權碼)
11 
12 try:
13     print('開始登陸')
14     server.login(from_addr, password)  # 登陸郵箱
15     print('登陸成功')
16 except Exception as e:
17     print('Error:', e)

2.發送郵件並退出

 1 print("郵件開始發送")
 2 
 3 message = '''您好,這是一封測試郵件'''
 6 msg = MIMEText(message, 'plain', 'utf-8')
 7 
 8 msg['Subject'] = Header("回覆:測試", 'utf-8')
 9 msg['From'] = Header('a@b.com')
10 
11 to_addr_list = ['a@qq.com']
13 
14 try:
15     for to_addr in to_addr_list:
16         msg['To'] = Header(to_addr, 'utf-8')
17         server.sendmail(from_addr, to_addr, msg.as_string())  # 將msg轉化成string發出
18     print("郵件發送成功")
23 
24 except Exception as e:
25     print('Error:', e)
26 
27 server.quit()

4、小結

1.在功能上實現了批量處理未讀郵件,可是須要分別執行對應的代碼,比較囉嗦,計劃後續利用圖形界面的方式進行點擊處理。

2.當處理的數據過多時,發現部分163或qq郵箱的郵件標題只有兩個參數,執行 from_decode[2][0].decode('utf-8') 會報錯超出list的定義範圍。因此須要多一個判斷 len,不一樣的長度,取的值不同。

3.越往下作,要解決的業務上的細節問題越多。

相關文章
相關標籤/搜索