[python] 使用selenium模块实现QQ邮箱的自动化登录及邮件发送

您所在的位置:网站首页 打开qq邮箱登录过哪些东西会消失 [python] 使用selenium模块实现QQ邮箱的自动化登录及邮件发送

[python] 使用selenium模块实现QQ邮箱的自动化登录及邮件发送

2024-06-06 07:26| 来源: 网络整理| 查看: 265

文章目录 前言 前期准备selenium模块测试 过程讲解1.配置驱动,启动浏览器2.登录操作2.1 转换为账号密码登录 2.2 键入邮箱密码并登录 3.发送邮件 实现完整代码总结

前言

在我们日常工作中,会有很多需要通过邮箱进行的推送,比如数据集更新推送、自动回复等等。这些操作的前提是需要自动化的登录到邮箱中,并操作QQ邮箱进行写信发送的操作,所以接下来配合着code来解释一下一个完整的邮件登录发送过程。

前期准备 selenium模块

这里需要使用pip安装selenium,并且根据自己的浏览器版本下载对应的驱动。还没有配置过的朋友可以参考一下我之前的文章,有任何问题欢迎私信或评论。 ↓ [python] 使用selenium+pywinauto模块处理弹窗中的图片/文件上传

这里顺带一提,我在conda环境下下载的selenium模块在驱动安装配置完毕的情况下并不能正常使用,需要更进一步的查看原因,所以这里暂时不推荐使用conda环境。

测试

同样,这里给出一个示例,如果你可以成功打开浏览器就说明配置成功了!

from selenium import webdriver driver_edge=webdriver.Edge() driver_edge.get("https://www.baidu.com/") 过程讲解

这里我以QQ邮箱举例,当然在理解本文中的登录发送操作后,对于别的邮箱。也可以举一反三。这里讲解时使用部分代码,完整版我会放在文末。

1.配置驱动,启动浏览器 # 配置浏览器驱动 url="https://mail.qq.com/" # 确保浏览器打开后不会自动关闭 option = webdriver.EdgeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) option.add_experimental_option("detach", True) # 配置浏览器驱动 driver=webdriver.Edge(options=option) # 打开网页 driver.get(url) # 将浏览器网页最大化 driver.maximize_window() 2.登录操作

这里首先要讲一个和定位元素有关的知识点。

一般的登录网页都是将登陆框结构写在外层html网页内的,比如说csdn的登陆界面… 在这里插入图片描述 我们可以通过以下代码快速的定位到登录按钮并点击

driver.find_element(By.XPATH,'/html/body/div[2]/div/div[2]/div[2]/div[2]/div/div[2]/div/div[4]/button').click()

但是!但是!邮箱的登录页面一般使用frame的内嵌网页,可以大致理解为一个frame框为一个独立的网页。所以,常规的定位方法无法定位到对应frame框中的元素,需要先切入到所需元素所在的frame,再在frame内定位对应的元素。具体的操作方法可以参考这位大佬的文章 ↓ selenium之 定位以及切换frame

2.1 转换为账号密码登录

这里我们需要使用邮箱密码登录,由于网页默认的登陆方式扫码登录,所以必须先点击密码登录按钮,进行登录方式的转换。

可以通过右键检查的方法查看该按钮的位置: 在这里插入图片描述 可以大致看到这个元素嵌套在两个frame框当中,所以我们需要两次切入到当前元素所在的frame框中。

注意:这里最好使用id、name、class_name等定位方法去做定位,相对简洁且可以避免大部分frame框加密和元素定位重复的问题。

切入到第一层frame中(使用class_name方法,当然也可以结合使用src和xpath方法定位): 在这里插入图片描述

iframe1=driver.find_element(By.CLASS_NAME,"QQMailSdkTool_login_loginBox_qq_iframe") driver.switch_to.frame(iframe1)

切入到第二层方法相同,这里不过多赘述。

iframe2=driver.find_element(By.NAME,'ptlogin_iframe') driver.switch_to.frame(iframe2)

定位到当前frame中的密码登录按钮,并点击。

在这里插入图片描述

# 定位到密码登录,并使用邮箱进行登录 trans=driver.find_element(By.XPATH,'//*[@id="switcher_plogin"]').click()

ok!到这一步我们就可以使用邮箱和密码进行登陆了。

2.2 键入邮箱密码并登录

与上面定位密码登录按钮的操作相似,我们也来定位一下邮箱和密码输入框的位置。

不难发现,当前的邮箱和密码输入框及登 录按钮是处在我们之前切入的id为ptlogin_iframe的frame中的,所以这里我们就不需要再做任何切入操作了。具体的位置如下图所示 在这里插入图片描述

(1) 邮箱定位 既然不需要做任何操作,这里直接使用xpath定位到邮箱输入框并输入邮箱就行,这里最好clear一下文本框,以防之前浏览器记录过的邮箱或密码出现:

email=driver.find_element(By.XPATH,'//*[@id="u"]') email.clear() email.send_keys("your email")

(2) 密码定位 密码输入框的定位方式和邮箱输入框一样:

password=driver.find_element(By.XPATH,'//*[@id="p"]') password.clear() password.send_keys("your password")

(3) 登录 定位到按钮并点击

driver.find_element(By.XPATH,'//*[@id="login_button"]').click()

这里我使用了强制等待20s的方式来等待新页面的出现,大家也可以使用selenium自带的显式等待方法until(),这个方法在本文的后半段会使用到,这里就先不做解释。

driver.find_element(By.XPATH,'//*[@id="login_button"]').click() # 等待30s直到写信的按钮出现 time.sleep(20) windows=driver.window_handles # 切换到当前最新打开的窗口中 driver.switch_to.window(windows[-1])

window_handles方法获取当前浏览器中的所有窗口句柄,并使用switch_to.window(windows[-1]) 转换到最新的页面中。

ok!到这里登陆操作已经全部完成了,可以操作邮箱发送邮件了。

3.发送邮件

左上角的写 信按钮在最外层的html中,直接定位点击

# 定位到写信按键 driver.find_element(By.XPATH,'//*[@id="composebtn_td"]').click()

右侧出现的写信界面也不出意料的在id为mainFrame的frame框中,先切入该frame

在这里插入图片描述

# 与之前相同,还是先转换到写信的frame iframe3=driver.find_element(By.ID,'mainFrame') driver.switch_to.frame(iframe3)

下方的收件人和主题都属于这个frame,和之前邮件密码的输入方式相同

# 输入收件人 driver.find_element(By.XPATH,'/html/body/form[2]/div[2]/div[3]/div[2]/table[2]/tbody/tr/td[2]/div[1]/div[2]/input').send_keys(address) # 输入主题 driver.find_element(By.XPATH,'/html/body/form[2]/div[2]/div[3]/table[3]/tbody/tr[2]/td[2]/div/div/div/input').send_keys(title)

我在这里遇到了问题,在定位正文的文本框的时候每次都会出现NoSuchElement的错误,后来才发现正文的文本框是在mainFrame下的另一个frame中的,大家要注意!

切入frame并输入邮件正文

# 输入正文 """ 这里正文仍然嵌套了一个frame框架 所以这里只有定位到该frame后才能输入正文 """ iframe4=driver.find_element(By.CLASS_NAME,'qmEditorIfrmEditArea') driver.switch_to.frame(iframe4) # 定位到文本框,并输入正文 text_label=driver.find_element(By.XPATH,'/html/body/div[1]') text_label.clear() text_label.send_keys(text)

然后点击发送,细心的朋友一定会发现发 送按钮是在mainFrame当中的,那要重新回到最外层html中重新一层层切进来吗?当然不需要,selenium模块提供了退回的方法parent_frame(),可以退回到上一层frame中,如果已经在最外层html中了,该方法不会生效。

ok,那我们退回到mainFrame中,再点击发 送按钮。

在这里插入图片描述

# 现在退回到上一层frame中进行发送操作 driver.switch_to.parent_frame() driver.find_element(By.XPATH,'/html/body/form[2]/div[1]/div/a[1]').click()

接下来我们检查一下邮件是否发送成功,这里使用selenium.webdriver.support中的expected_conditions(简称EC)和WebDriverWait设置显式等待。

# 隐式等待发送完成的页面出现 WebDriverWait(driver,20,0.5).until(EC.presence_of_element_located((By.XPATH, '/html/body/div/div[1]/div/div[2]/span[2]/a[1]')))

这里的WebDriverWait中的三个参数依次为浏览器驱动,最长等待时间和时间间隔,until()方法中的是需要等待出现的某个元素。可以将其简单的理解为比强制等待更加高级的等待方式…一旦元素出现就会结束等待,若超过最大等待时间就会和强制等待一样,进行后续操作。

实现

由于隐私问题,我就不展示我的测试账号了…大家可以用自己的账号发给自己来测试。

if __name__=='__main__': # 配置浏览器驱动 url="https://mail.qq.com/" # 邮箱密码 email="your email" password="your password" # 目标邮箱、正文、标题 addressee="your email" text="This is a test email..." title="test email" # 确保浏览器打开后不会自动关闭 option = webdriver.EdgeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) option.add_experimental_option("detach", True) # 配置浏览器驱动 driver=webdriver.Edge(options=option) # 打开网页 driver.get(url) # 将浏览器网页最大化 driver.maximize_window() QQLogin(email=email,password=password) QQSend(address=addressee,text=text,title=title) 完整代码 # 使用selenium进行登录下载操作 from selenium import webdriver import time from selenium.webdriver.common.by import By from selenium.webdriver import ActionChains from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def QQLogin(email,password): """ 本函数主要负责QQ邮箱登录操作 参数包括 eamil-您的登录邮箱 password-您邮箱所对应的登陆密码 """ # 以下为登录邮箱流程 # 先定位到QQ登录的frame print("当前开始登陆操作") iframe1=driver.find_element(By.CLASS_NAME,"QQMailSdkTool_login_loginBox_qq_iframe") driver.switch_to.frame(iframe1) # 再定位到登录框的frame iframe2=driver.find_element(By.NAME,'ptlogin_iframe') driver.switch_to.frame(iframe2) time.sleep(3) # 定位到密码登录,并使用邮箱进行登录 driver.find_element(By.XPATH,'//*[@id="switcher_plogin"]').click() email_label=driver.find_element(By.XPATH,'//*[@id="u"]') email_label.clear() email_label.send_keys(email) time.sleep(3) password_label=driver.find_element(By.XPATH,'//*[@id="p"]') password_label.clear() password_label.send_keys(password) time.sleep(3) driver.find_element(By.XPATH,'//*[@id="login_button"]').click() # 等待30s直到写信的按钮出现 time.sleep(20) windows=driver.window_handles # 切换到当前最新打开的窗口中 driver.switch_to.window(windows[-1]) print("登陆成功!正在进行邮件发送请稍后...") def QQSendPrepare(address,title=""): """ 本函数主要负责QQ邮箱发送邮件前的收件人和标题键入操作 参数包括 address-收件人邮箱地址 title-邮件主题(此处默认为空) """ # 以下为写信发邮件流程 # 定位到写信按键 driver.find_element(By.XPATH,'//*[@id="composebtn_td"]').click() # 与之前相同,还是先转换到写信的frame iframe3=driver.find_element(By.ID,'mainFrame') driver.switch_to.frame(iframe3) # 输入收件人 driver.find_element(By.XPATH,'/html/body/form[2]/div[2]/div[3]/div[2]/table[2]/tbody/tr/td[2]/div[1]/div[2]/input').send_keys(address) # 输入主题 driver.find_element(By.XPATH,'/html/body/form[2]/div[2]/div[3]/table[3]/tbody/tr[2]/td[2]/div/div/div/input').send_keys(title) def QQSend(address,text,title=""): """ 本函数为QQ邮箱发送邮件主函数 参数包括 address-收件人邮箱地址 text-邮件具体内容 title-邮件主题(此处默认为空) """ QQSendPrepare(address,title) # 输入正文 """ 这里正文仍然嵌套了一个frame框架 所以这里只有定位到该frame后才能输入正文 """ iframe4=driver.find_element(By.CLASS_NAME,'qmEditorIfrmEditArea') driver.switch_to.frame(iframe4) # 定位到文本框,并输入正文 text_label=driver.find_element(By.XPATH,'/html/body/div[1]') text_label.clear() text_label.send_keys(text) # 现在退回到上一层frame中进行发送操作 driver.switch_to.parent_frame() driver.find_element(By.XPATH,'/html/body/form[2]/div[1]/div/a[1]').click() # 隐式等待发送完成的页面出现 WebDriverWait(driver,20,0.5).until(EC.presence_of_element_located((By.XPATH, '/html/body/div/div[1]/div/div[2]/span[2]/a[1]'))) # 等待当前的邮件发送完成,点击查看发送状态 driver.find_element(By.XPATH,'/html/body/div/div[1]/div/div[1]/div[1]/a').click() # 切入状态frame中 iframe5=driver.find_element(By.NAME,'mailSendStatus') driver.switch_to.frame(iframe5) status_text=driver.find_element(By.XPATH,"/html/body/div/table/tbody/tr[2]/td[2]/div").get_attribute("title") time.sleep(5) if status_text=="已投递到对方邮箱": driver.quit() print("当前邮件已经投递完毕") if __name__=='__main__': # 配置浏览器驱动 url="https://mail.qq.com/" # 邮箱密码 email="your email" password="your password" # 目标邮箱、正文、标题 addressee="your email" text="This is a test email..." title="test email" # 确保浏览器打开后不会自动关闭 option = webdriver.EdgeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) option.add_experimental_option("detach", True) # 配置浏览器驱动 driver=webdriver.Edge(options=option) # 打开网页 driver.get(url) # 将浏览器网页最大化 driver.maximize_window() QQLogin(email=email,password=password) QQSend(address=addressee,text=text,title=title) 总结

以上就是使用python中的selenium模块实现QQ邮箱的登录和邮件发送的所有内容啦,本文有什么问题还请大家海涵!有问题欢迎在评论区留言或私信,希望大家能够多多点赞收藏,你们的点赞收藏就是我创作的动力喔!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3