一、浏览器打开QQ邮箱登录网址

QQ邮箱登录地址为:https://mail.qq.com/

driver = webdriver.Chrome()driver.get('https://mail.qq.com/')

二、元素定位,输入QQ账号和QQ密码

手动进入QQ邮箱登录网页,按下option+command+i打开开发者工具,点击查看元素,选择元素:

可以看到QQ账号输入框的id、name等属性,都是可以直接拿来定位的好选择。

我这里选择最通用的xpath方法来定位,id=‘u’,并用send事件输入QQ账号

(也可以用driver.find_element_by_id(‘u’)来定位,代码更清晰,不过我个人习惯采用通用的xpath)

driver.find_element_by_xpath('//*[@id="u"]').send_keys("XXXXXXXXX")

同理,QQ密码元素属性id=‘p’,同样定位方法

driver.find_element_by_xpath('//*[@id="p"]').send_keys("XXXXXXXXX")

再同理,登录按钮元素属性id=‘login_button’,这里不需要发送信息,所以选择click点击事件

driver.find_element_by_xpath('//*[@id="login_button"]').click()

好的,原则上到此为止,运行pycharm应该是能够输入账号和密码,并登陆成功。

但是事情没有那么简单,运行后发现,selenium报错,无法找到id为u的元素。

进过仔细观察,发现是frame嵌套页面在作怪。

我们可以这样理解,每一个网页都是一个父类的frame,从我们访问这个网址开始,就已经进入了这个父类frame嵌套。顾名思义,有父即有子。frame(父)里嵌套了iframe(子),如果我们要定位的元素在iframe里,那么我们需要先切换至iframe。

iframe也是有自己的元素属性的,selenium也提供了switch方法供我们使用

重新option+command+i往上找iframe信息,可以看到被iframe嵌套了,id和name都是‘login_frame’

在定位元素之前,先输入如下代码:

driver.switch_to.frame("login_frame")

这样就切换到iframe了,再继续之前的元素定位,即可成功。

这一步的完整代码为:

# 定位login_framedriver.switch_to.frame("login_frame")# 定位账号、密码,并输入driver.find_element_by_xpath('//*[@id="u"]').send_keys("XXXXXXXXX")driver.find_element_by_xpath('//*[@id="p"]').send_keys("XXXXXXXXX")driver.find_element_by_xpath('//*[@id="login_button"]').click()# 定位登录按钮driver.find_element_by_xpath('//*[@id="login_button"]').click()

这个时候网页已经可以成功QQ邮箱。

三、元素定位,写信界面

继续,邮箱登录成功之后,来到写信界面,按照常规操作,我们需要先点击左上角写信按钮,展开具体写信界面

同样的方法,option+command+i操作起来,查看写信按钮,元素定位为id=‘composebtn’,发送点击事件

driver.find_element_by_xpath('//*[@id="composebtn"]').click()

邮件内容编辑有四个部分,收件人、主题、正文,以及最后点击发送按钮

通过之前踩的坑,到了这一步,我对iframe嵌套变得格外小心,准备定位的每个元素都去观察是否被iframe嵌套。

果不其然,“收件人”、“主题”和“发送”被主文档下的mainFrame嵌套了,而“正文”又被mainFrame的子frame嵌套了。

so,这一步的逻辑为:

(1)先切换到mainFrame,

(2)分别定位 收件人 和 主题 ,调用发送事件

(3)继续切换到子frame

(4)定位正文,调用发送事件

(5)从子frame,返回到它的父frame,也即是mainFrame中

(6)定位发送按钮,调用点击事件

这一步中,也有很多意向不到的坑:

1、定位收件人的时候,发现定位到的元素,还有子div,经过模拟,发现只有第二个子div才是真正能够定位到收件人的元素,于是先定位id=‘toAreaCtrl’,然后选择第二个div中的input作为定位。

具体xpath定位内容为:

“//*[@id=‘toAreaCtrl’]/div[2]/input”

2.同样是定位收件人遇到的问题,必须在切换到mainFrame后、定位收件人之前,加一个延迟执行,不然一定会无法定位到收件人元素。原因不明,所以我建议如果以后遇到元素定位不到,可以尝试加一个time.sleep。

3.定位正文时,从mainFrame切换到iframe,发现iframe的id和name是动态的一串数字,但是switch_to.frame只支持固定id或者name。所以想了别的法子,先用iframe的class进行xpath定位,然后把传给switch_to.frame来切换。具体为:

# 切换到iframedriver.switch_to.frame(driver.find_element_by_xpath('//*[@class="qmEditorIfrmEditArea"]'))

4.邮件正文需要先调用一个点击事件激活,才能启动send事件。如果没有先点击再编写,那么send的内容会放在主题后面的文本框中。(也不知道为啥会有这样的设定~)

所以综上所述,这一步的代码为:

# 切换到mainFramedriver.switch_to.frame('mainFrame')sleep(1)# 定位收件人,并输入driver.find_element_by_xpath("//*[@id='toAreaCtrl']/div[2]/input").send_keys("XXXXXX@qq.com")# 定位主题,并输入driver.find_element_by_xpath('//*[@id="subject"]').send_keys("来自lucas的邮件")# 定位邮件正文,先进入到iframedriver.switch_to.frame(driver.find_element_by_xpath('//*[@class="qmEditorIfrmEditArea"]'))# 必须先点击正文,再send_keysdriver.find_element_by_xpath('/html/body').click()driver.find_element_by_xpath('/html/body').send_keys("Hello World", "\nlucas")# 返回到mainframedriver.switch_to.parent_frame()
# 定位发送按钮driver.find_element_by_xpath('//*[@name="sendbtn"]').click()

最终程序代码:

# -*- coding: utf-8 -*-"""@author: lucas@Function:@file: sendEmail.py@time: 2021/8/26 2:55 下午"""from telnetlib import ECfrom selenium import webdriverfrom time import sleepfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.wait import WebDriverWaitdriver = webdriver.Chrome()driver.get('https://mail.qq.com/')sleep(2)driver.maximize_window()# 定位login_framedriver.switch_to.frame('login_frame')# driver.find_element_by_xpath('//*[@id="switcher_plogin"]').click()# 定位账号、密码,并输入sleep(2)driver.find_element_by_xpath('//*[@id="u"]').send_keys("XXXXXXXXX")sleep(2)driver.find_element_by_xpath('//*[@id="p"]').send_keys("XXXXXXXXX")sleep(2)driver.find_element_by_xpath('//*[@id="login_button"]').click()# 定位登录按钮driver.find_element_by_xpath('//*[@id="login_button"]').click()sleep(2)driver.find_element_by_xpath('//*[@id="composebtn"]').click()# 切换到mainFramedriver.switch_to.frame('mainFrame')sleep(1)# 定位收件人,并输入driver.find_element_by_xpath("//*[@id='toAreaCtrl']/div[2]/input").send_keys("XXXXXXXXX")# 定位主题,并输入driver.find_element_by_xpath('//*[@id="subject"]').send_keys(" from lucas")# 定位邮件正文,先进入到iframedriver.switch_to.frame(driver.find_element_by_xpath('//*[@class="qmEditorIfrmEditArea"]'))# 必须先点击正文,再send_keysdriver.find_element_by_xpath('/html/body').click()driver.find_element_by_xpath('/html/body').send_keys("Hello World", "\nlucas")# 返回到mainframedriver.switch_to.parent_frame()# 定位发送按钮driver.find_element_by_xpath('//*[@name="sendbtn"]').click()sleep(5)

最后邮件发送成功:

四、元素定位总结

1、frame很重要,一定要看清楚是否被嵌套,以及注意切换
2、元素的id或者name如果是动态的,请放弃
3、用xpath定位真香
4、如果元素有子节点,使用相对路径继续定位
5、实在排查不出为什么定位失败,尝试一下用time.sleep()

五、小技巧:

分享几点在开发者工具里,比较方便的小窍门:

1、在开发者工具里,选中元素,点击Console,可以很直观的看到元素是否被iframe嵌套

2、邮件复制可以直接得到元素定位的xpath

selenium之qq邮箱登录-发邮件相关推荐

  1. phpmail通过qq发邮箱失败_PHP中利用PHPMailer配合QQ邮箱实现发邮件

    phpmailer实现给网站用户发送邮件,WordPress好像禁用了mail()函数,也不能直接使用自带的发送邮件,以防止暴露IP PHPMailer的介绍: 可运行在任何平台之上 支持SMTP验证 ...

  2. python实现kindle每天推送博客1----kindle推送原理,python实现qq邮箱登录及邮件发送

    kindle想每天看新闻,看博客, 其实自己用python写个代码就能很简单实现了. 1.kindle推送原理 kindle不仅可以买书看书,还可以自己推送内容 原理很简单,往你个人的kindle邮箱 ...

  3. 非QQ邮箱 无法发邮件给 QQ号@qq.com的邮箱 问题 解决方案

    工作中遇到了一个问题: 使用 非QQ邮箱 进行发件时,发送给 QQ号@qq.com1 的邮件总是提示发件失败. 正当我百思不得其解的时候,同事给了我个解决方案: 把收件邮箱 @后面小写的"q ...

  4. PHP中利用PHPMailer配合QQ邮箱实现发邮件

    前言: 由于作业的需要,要实现给我们的网站用户发送邮件,于是就有了这篇博客.以下的内容是我结合网上的例子加上自己的实践的出来的.希望对大家有帮助. PHPMailer的介绍: 优点: 可运行在任何平台 ...

  5. Laravel5使用qq邮箱smtp发邮件配置及测试

    第一步:.env中的MAIL配置: MAIL_DRIVER=smtp MAIL_HOST=smtp.qq-com MAIL_PORT=587 MAIL_USERNAME=xxxxxxxxx@qq-co ...

  6. 第三方软件要使用QQ邮箱进行发邮件相关设置

    1.要在QQ邮箱的设置界面进行相关设置. 开启相应的服务器,然后获得相应的授权密码即可. 相关参考: http://service.mail.qq.com/cgi-bin/help?subtype=1 ...

  7. Python selenium模拟QQ邮箱登录

    from selenium import webdriver import timebrowser = webdriver.Chrome() browser.get('https://mail.qq. ...

  8. 使用matlab编程给qq或163邮箱等发邮件

    平时在科研中经常会被导师要求使用matlab跑一些大程序,许多时候一个结果跑下来得花去好几个小时的时间,然后改改参数再继续跑,这样真的很让人不淡定啊,如果使用matlab编程让matlab跑出的让自己 ...

  9. Microsoft 帐户异常登录活动,QQ邮箱代收hotmail邮件不成功

    最近打算让QQ邮箱代收hotmail的邮件,总是提示不成功,而且homail里的备用邮箱一直到"安全阻止登录"邮件,同时QQ添加代收也不成功.而且关闭了二步验证还是不行.经过和微软 ...

  10. java实现通过QQ邮箱发送激活邮件 springBoot

    用户邮件激活 通过QQ邮箱发送激活邮件 soringBoot 本文主要介绍了使用java 调用邮箱发送邮件的功能 首先新建一个springboot项目 pom依赖如下 <parent>&l ...

最新文章

  1. 695.岛屿的最大面积
  2. ASP .NET Core Web Razor Pages系列教程三:自动生成Razor Pages (CRUD)
  3. 算法--------翻转字符串里的单词(Java版本)
  4. 三菱伺服电机选型手册_PLC触摸屏控制伺服电机程序设计
  5. VueX(Vue状态管理模式)
  6. day22 Pythonpython 本文json模块
  7. c# 计算空格宽度像素_Adv. Mater:2D材料缺陷工程实现全光控存储和神经形态计算...
  8. P4145-上帝造题的七分钟2/花神游历各国【并查集,树状数组】
  9. 办学10年,进入全国前10名!这所神奇的高校,迎来10岁生日
  10. 看完这篇你就明白,为什么说大部分企业建设数据中台都会失败?
  11. 管理后台--4,删除分类
  12. 单片机c语言数字频率计课程设计,单片机数字频率计设计和调试 课程设计论文...
  13. 金橙子打标软件学习流程
  14. 投影仪与计算机连接方式,电脑怎么接投影仪教程 简单三步教你搞定
  15. linux学习笔记(十二)
  16. 发散思维能力(1-2)
  17. android的UI性能优化
  18. 前言 金融大叔的梦想
  19. 跑过的城市,走过的路
  20. Linux多线程——生产者消费者模型

热门文章

  1. ffmpeg实现视频切割
  2. SDN先行开拓者们获得可视性和带宽控制
  3. SEO人员:如何预估SEO投资回报率?
  4. 关于HDS的高端存储设备USPV
  5. Vim简单介绍和使用方法
  6. 华为机试题 好友关系管理
  7. 软件测试项目反思,软件测试之项目线上问题总结与反思
  8. 崂山道士“法术”已成真?还需VR+AI+5G三强紧联合
  9. 改纸盒大小_包装纸箱改大小
  10. hdu2079选课时间(动态规划母函数)