Python处理邮件内容和提取邮件里的url地址

最近在搞一个邮箱验证账号注册和登录的模块。总结一下。就当记载。文章中涉及到域名和邮箱等都经过处理。

需求是这样子的,通过selenium注册某个网站的账号,然后注册需要邮件内容里的链接激活,登录的时候如果不是常用设备的话也需要认证,而两种认证方式给出的链接方式是不一样的。一种是直接通过发放激活链接给你,就是纯网址,这个好处理,直接用str或者text就能从邮件内容里将原始的url地址提取出来了。但是登录认证的话就是一个锚文本链接,这个如果还用str或者text方式提取的话,就会出现一个问题,就是提取出来的url里的"&"它会变成"&",在浏览器地址栏中输入的话,就会出错。所以用str或者text方式提取出来的,还得还原一下地址栏能用的网址。用模块html就行了。所有问题搞定。然后将提取出来的链接加载到selenium里继续愉快的xxoo就行了。

思路: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 = 'xxx@xxx.com'
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 = 'xxxx@xxx.com'
68 pwd = 'xxxx'
69 ac = AmazonSignInConfirm(username, pwd) #实例化
70 
71 
72 verify_link = ac.get_the_sign_in_verify_link()
73 print(verify_link) #打印,符合预期

两段代码基本上是相同的,除了最后一个类方法处理方式有点不同的话。文中有些合法性验证是不需要的,我是为了方便调试和查看程序运行轨迹才加那么多的。记录是记录,也希望有志同道合的人,给出更完美的解决方案。

原文地址:https://www.cnblogs.com/mafu/p/14181503.html