1. 程式人生 > 實用技巧 >Python處理郵件內容和提取郵件裡的url地址

Python處理郵件內容和提取郵件裡的url地址

最近在搞一個郵箱驗證賬號註冊和登入的模組。總結一下。就當記載。文章中涉及到域名和郵箱等都經過處理。

需求是這樣子的,註冊某個網站的賬號,然後註冊需要郵件內容啟用,登入的時候如果不是常用裝置的話也需要認證,而兩種認證方式給出的認證方式是不一樣的。一種是直接通過發放啟用連結給你,就是純網址,這個好處理,直接用str或者text就能從郵件內容裡將原始的url地址提取出來了。但是登入的話就是一個錨文字連結,這個如果還用str或者text方式提取的話,就會出現一個問題,就是提取出來的url裡的"&"它會變成"&",在瀏覽器位址列中輸入的話,就會出錯。所以用str或者text方式提取出來的,還得還原一下位址列能用的網址。用模組html就行了。所有問題搞定。

思路:1->登入郵箱;

   2->獲取最新郵件(獲取最新郵件的理由是,啟用和認證的同時,應該不會那麼巧有其他郵件發過來,所以我覺得,這種足夠滿足需求了);

   3->解析郵件內容,用imap和pop取回來的郵件我嫌太麻煩,用國人大神開發的zmail解析郵件內容只需幾個步驟。

      首先獲取郵件的html內容

      將html內容解析成str

      把str內容單獨提取出來,在本地建一個html頁面

      通過bs4解析這個本地html的內容

      提取自己想要的內容,在這裡是連結地址

提取啟用連結的程式碼:

 1 import zmail
2 from bs4 import BeautifulSoup 3 import lxml 4 5 ''' 6 #一個模組專門處理xxx新註冊使用者的郵箱驗證問題 7 #思路: 8 1,首先通過zmail登入到郵箱 9 2,因為註冊都是即時的,驗證郵件應該也是即時的 10 3,收取最新收到的郵件 11 4,獲取最新郵件的content_html內容 12 5,將content_html內容轉換成str格式方便處理 13 6,將str格式的html文件使用bs4解析 14
7,通過bs4解析出來的內容是一個列表 15 8,讀取列表裡的文字內容,這樣子也不會丟失格式 16 #坑: 17 1,郵箱裡的連結內容如果通過直接讀取,是會更改的,比如說=就會變成amp等,所以要通過text讀取 18 19 20 ''' 21 class GetTheVerifyLink(): 22 def __init__(self, emailAccount, pwd): 23 #初始化使用者名稱和密碼 24 self.emailAccount = emailAccount 25 self.pwd = pwd 26 27 def login_to_server(self): 28 ''' 29 #嘗試登入郵箱伺服器 30 ''' 31 try: 32 connect = zmail.server(self.emailAccount, self.pwd) 33 print("登入成功!") 34 except: 35 print("登入失敗!請檢查") 36 #將connect物件返回到呼叫它的程式碼行 37 return connect 38 39 def get_the_latest_mail(self): 40 ''' 41 #通過判定最新郵件的發件人是不是有xxx來判定是不是我們要的郵件 42 ''' 43 mail = self.login_to_server().get_latest() 44 #開始判定 45 sender = mail['From'] #獲取發件人 46 subject = mail['Subject'] #獲取郵件主題 47 content_text = mail['Content_text'] #獲取郵件內容 48 content_text_str = ''.join(content_text) #將郵件內容轉換為str,不轉換也行,不轉換請看下面 49 # content_text_str = ''.join(content_text[0]) #獲取列表的一個元素,將它轉換成str,因為它只有一個元素 50 if '@xxx' in sender and 'verify your e-mail address' in subject and 'https://www.xxx/xx/xxx' in content_text_str: 51 print("這是我們需要的郵件!") 52 return mail 53 else: 54 print("這不是我們需要的郵件,請登入郵箱手動刪除並保持amazon認證郵件最新!") 55 56 def get_the_mail_content_html(self): 57 content_html = self.get_the_latest_mail()['content_html'] 58 if content_html: 59 return content_html 60 else: 61 print("獲取content_html內容郵件失敗!") 62 63 def tranfer_content_html_to_str(self): 64 content_html_to_str = ''.join(self.get_the_mail_content_html()) 65 if content_html_to_str: 66 print("將郵件的content_html轉換成str成功!") 67 return content_html_to_str 68 else: 69 print("將郵件的content_html內容轉換成str失敗!") 70 71 def get_the_verify_link(self): 72 soup = BeautifulSoup(self.tranfer_content_html_to_str(), 'lxml') 73 verify_link_list = soup.select(r'body > p:nth-child(3) > a:nth-child(1)') 74 for verify_link in verify_link_list: 75 verify_link = verify_link.text 76 return verify_link 77 78 # emailAccount = '[email protected]' 79 # pwd = 'xxxx!' 80 # 81 # gt = GetTheVerifyLink(emailAccount,pwd) 82 # # latest_mail = gt.get_the_latest_mail() 83 # # print(latest_mail) 84 # verify_link = gt.get_the_verify_link() 85 # print(verify_link)

提取登入連線的程式碼:

 1 import zmail
 2 from bs4 import BeautifulSoup
 3 import lxml
 4 import html
 5 
 6 class xxxSignInConfirm():
 7     def __init__(self, username, password):
 8         self.username = username
 9         self.password = password
10 
11     def login_to_server(self):
12         try:
13             server = zmail.server(self.username, self.password)
14             print("E-mail Login success!")
15         except:
16             print("E-mail login Failed!")
17         return server
18 
19     def get_the_latest_mail(self):
20         '''
21             #通過判定最新郵件的發件人是不是有xxx.com來判定是不是我們要的郵件
22         '''
23         mail = self.login_to_server().get_latest()
24         #開始判定
25         sender = mail['From'] #獲取發件人
26         subject = mail['Subject'] #獲取郵件主題
27         content_text = mail['Content_text'] #獲取郵件內容,獲取文字的郵件內容主要是用在接下來的if語句裡的
28         content_text_str = ''.join(content_text) #將郵件內容轉換為str,不轉換也行,不轉換請看下面
29         # content_text_str = ''.join(content_text[0]) #獲取列表的一個元素,將它轉換成str,因為它只有一個元素
30         if 'security' in subject:
31             print("這是我們需要的郵件!")
32             return mail
33         else:
34             print("這不是我們需要的郵件,請登入郵箱手動刪除並保持amazon認證郵件最新!")
35 
36     def get_the_mail_content_html(self):
37         mail = self.get_the_latest_mail()
38         content_html = mail['Content_html']
39         if content_html:
40             return content_html
41         else:
42             print("獲取content_html內容郵件失敗!")
43 
44     def transfer_content_html_to_str(self):
45         content_html_to_str = ''.join(self.get_the_mail_content_html())
46         if content_html_to_str:
47             print("將郵件的content_html轉換成str成功!")
48             return content_html_to_str
49         else:
50             print("將郵件的content_html內容轉換成str失敗!")
51 
52     def get_the_sign_in_verify_link(self):
53         soup = BeautifulSoup(self.transfer_content_html_to_str(), 'lxml') #利用bs4解析html的郵件內容
54         signInconfirmLinks = soup.select(r'body > div:nth-child(3) > div:nth-child(4) > table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(5) > td:nth-child(1) > a:nth-child(1)')
55         signlinkelement = signInconfirmLinks[0]
56         signlinkstr = str(signlinkelement) #轉換成str
57         # print(signlinkstr)
58         afind = signlinkstr.find('"') #查詢字串中<a href="https//xxxxxxxx.com/"</a>的第一個引號
59         # print(afind)
60         bfind = signlinkstr[afind + 1:].find('"') #找出第二個引號的位置
61         # print(bfind)
62         signlinkamp = signlinkstr[afind + 1: afind + 1 + bfind] #在兩個引號之間就是我們需要的連結地址,切片切出來
63         # print(signlinkamp) #列印一下提取出來的地址,是我們想要的,只是&變成了&amp;
64         verify_link = html.unescape(signlinkamp) #使用html還原真實網址
65         return verify_link
66 
67 username = '[email protected]'
68 pwd = 'xxxx'
69 ac = AmazonSignInConfirm(username, pwd) #例項化
70 
71 
72 verify_link = ac.get_the_sign_in_verify_link()
73 print(verify_link) #列印,符合預期

兩段程式碼基本上是相同的,除了最後一個類方法處理方式有點不同的話。文中有些合法性驗證是不需要的,我是為了方便除錯和檢視程式執行軌跡才加那麼多的。記錄是記錄,也希望有志同道合的人,給出更完美的解決方案。