本期做一个selenium详细实例,会把我在元素定位中遇到的一些阻塞和经验分享给大家。
(浏览器为Chrome)
(如果只需要最终的完整代码,请直接跳转到文章最后)
浏览器打开QQ邮箱登录网址
QQ邮箱登录地址为:https://mail.qq.com/
from selenium import webdriver import time zhengyi = webdriver.Chrome() zhengyi.get('https://mail.qq.com/')
这一步没有遇到问题,至于为什么导入时间库,后面会说。
元素定位,输入QQ账号和QQ密码
手动进入QQ邮箱登录网页,按下F12打开开发者工具,点击查看元素,选择元素:
可以看到QQ账号输入框的id、name等属性,都是可以直接拿来定位的好选择。
我这里选择最通用的xpath方法来定位,id=‘u',并用send事件输入QQ账号
(也可以用zhengyi.find_element_by_id(‘u')来定位,代码更清晰,不过我个人习惯采用通用的xpath)
zhengyi.find_element_by_xpath('//*[@id="u"]').send_keys("XXXXXXXXX")
同理,QQ密码元素属性id=‘p',同样定位方法
zhengyi.find_element_by_xpath('//*[@id="p"]').send_keys("XXXXXXXX")
再同理,登录按钮元素属性id=‘login_button',这里不需要发送信息,所以选择click点击事件
zhengyi.find_element_by_xpath('//*[@id="login_button"]').click()
好的,原则上到此为止,运行pycharm应该是能够输入账号和密码,并登陆成功。
but事情没有那么简单,运行后发现,selenium报错,无法找到id为u的元素。
进过仔细观察,发现是frame嵌套页面在作怪。
我们可以这样理解,每一个网页都是一个父类的frame,从我们访问这个网址开始,就已经进入了这个父类frame嵌套。顾名思义,有父即有子。frame(父)里嵌套了iframe(子),如果我们要定位的元素在iframe里,那么我们需要先切换至iframe。
iframe也是有自己的元素属性的,selenium也提供了switch方法供我们使用
重新F12往上找iframe信息,可以看到被iframe嵌套了,id和name都是‘login_frame'
在定位元素之前,先输入如下代码:
zhengyi.switch_to.frame("login_frame")
这样就切换到iframe了,再继续之前的元素定位,即可成功。
这一步的完整代码为:
# 定位login_frame zhengyi.switch_to.frame("login_frame") zhengyi.find_element_by_xpath('//*[@id="switcher_plogin"]').click() # 定位账号、密码,并输入 zhengyi.find_element_by_xpath('//*[@id="u"]').send_keys("839811794") zhengyi.find_element_by_xpath('//*[@id="p"]').send_keys("199306zy") # 定位登录按钮 zhengyi.find_element_by_xpath('//*[@id="login_button"]').click()
这个时候网页已经可以成功QQ邮箱。
元素定位,写信界面
继续,邮箱登录成功之后,来到写信界面,按照常规操作,我们需要先点击左上角写信按钮,展开具体写信界面
同样的方法,F12操作起来,查看写信按钮,元素定位为id=‘composebtn',发送点击事件
# 定位写信按钮 zhengyi.find_element_by_xpath('//*[@id="composebtn"]').click()
这个时候调试程序,网页成功打开结果为selenium定位不到id为composebtn的元素。
这个时候就暴露了在上一个环节中出现的问题,之前的代码将嵌套切换到了iframe的login_frame中,而此时的写信元素,不在iframe中,所以在定位之前,需要先离开这个嵌套,返回到主文档中
zhengyi.switch_to.default_content()
这样嵌套就切换到主文档了,再次运行程序,发现还是报错
通过反复查资料,终于发现,写信是在QQ登录后才会出现的。如果我们登陆之后的瞬间就去定位写信按钮,这个时候受网速、PC的客观影响,会定位不到元素。
我们只需要加一个sleep一秒,即可完美解决。(这个时候就体现了导入时间库的作用了~)
#离开login_frame zhengyi.switch_to.default_content() #等待一秒 time.sleep(1) # 定位写信按钮 zhengyi.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来切换。具体为:
#切换到iframe zhengyi.switch_to.frame(zhengyi.find_element_by_xpath('//*[@class="qmEditorIfrmEditArea"]'))
4.邮件正文需要先调用一个点击事件激活,才能启动send事件。如果没有先点击再编写,那么send的内容会放在主题后面的文本框中。(也不知道为啥会有这样的设定~)
所以综上所述,这一步的代码为:
# 切换到mainFrame zhengyi.switch_to.frame('mainFrame') time.sleep(1) # 定位收件人,并输入 zhengyi.find_element_by_xpath("//*[@id='toAreaCtrl']/div[2]/input").send_keys("XXXXXXXXX@qq.com") # 定位主题,并输入 zhengyi.find_element_by_xpath('//*[@id="subject"]').send_keys("来自zhengyi的邮件") # 定位邮件正文,先进入到iframe zhengyi.switch_to.frame(zhengyi.find_element_by_xpath('//*[@class="qmEditorIfrmEditArea"]')) # 必须先点击正文,再send_keys zhengyi.find_element_by_xpath('/html/body').click() zhengyi.find_element_by_xpath('/html/body').send_keys("Hello World","\nZhengyi") # 返回到mainframe zhengyi.switch_to.parent_frame() # 定位发送按钮 zhengyi.find_element_by_xpath('//*[@name="sendbtn"]').click()
(就这么短短数十行,耗死了不少脑细胞)
元素定位总结
1、frame很重要,一定要看清楚是否被嵌套,以及注意切换
2、元素的id或者name如果是动态的,请放弃
3、用xpath定位真香
4、如果元素有子节点,使用相对路径继续定位
5、实在排查不出为什么定位失败,尝试一下用time.sleep()
最终程序代码
from selenium import webdriver #导入时间模块 import time # 注意大写Chrome的C zhengyi = webdriver.Chrome() zhengyi.get('https://mail.qq.com/') # 定位login_frame zhengyi.switch_to.frame("login_frame") zhengyi.find_element_by_xpath('//*[@id="switcher_plogin"]').click() # 定位账号、密码,并输入 zhengyi.find_element_by_xpath('//*[@id="u"]').send_keys("839811794") zhengyi.find_element_by_xpath('//*[@id="p"]').send_keys("199306zy") # 定位登录按钮 zhengyi.find_element_by_xpath('//*[@id="login_button"]').click() # 离开login_frame # zhengyi.switch_to.parent_frame() zhengyi.switch_to.default_content() # 等待一秒 time.sleep(1) # 定位写信按钮 zhengyi.find_element_by_xpath('//*[@id="composebtn"]').click() # 切换到mainFrame zhengyi.switch_to.frame('mainFrame') time.sleep(1) # 定位收件人,并输入 zhengyi.find_element_by_xpath("//*[@id='toAreaCtrl']/div[2]/input").send_keys("839811794@qq.com") # 定位主题,并输入 zhengyi.find_element_by_xpath('//*[@id="subject"]').send_keys("来自zhengyi发来的邮件") # 定位邮件正文,先进入到iframe zhengyi.switch_to.frame(zhengyi.find_element_by_xpath('//*[@class="qmEditorIfrmEditArea"]')) # 必须先点击正文,再send_keys zhengyi.find_element_by_xpath('/html/body').click() zhengyi.find_element_by_xpath('/html/body').send_keys("Hello World","\nZhengyi") # 返回到mainframe zhengyi.switch_to.parent_frame() # 定位发送按钮 zhengyi.find_element_by_xpath('//*[@name="sendbtn"]').click() time.sleep(5) #关闭浏览器 zhengyi.quit()
tips
分享几点在开发者工具里,比较方便的小窍门:
1、在开发者工具里,选中元素,点击Console,可以很直观的看到元素是否被iframe嵌套
2、Elements,选中想定位的元素,右键–COPY–Copy XPath,可以直接复制元素的xpath
3、希望您能给我分享一点tips
总结
以上所述是小编给大家介绍的selenium+python实现自动登陆QQ邮箱并发送邮件功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 明达年度发烧碟MasterSuperiorAudiophile2021[DSF]
- 英文DJ 《致命的温柔》24K德国HD金碟DTS 2CD[WAV+分轨][1.7G]
- 张学友1997《不老的传说》宝丽金首版 [WAV+CUE][971M]
- 张韶涵2024 《不负韶华》开盘母带[低速原抓WAV+CUE][1.1G]
- lol全球总决赛lcs三号种子是谁 S14全球总决赛lcs三号种子队伍介绍
- lol全球总决赛lck三号种子是谁 S14全球总决赛lck三号种子队伍
- 群星.2005-三里屯音乐之男孩女孩的情人节【太合麦田】【WAV+CUE】
- 崔健.2005-给你一点颜色【东西音乐】【WAV+CUE】
- 南台湾小姑娘.1998-心爱,等一下【大旗】【WAV+CUE】
- 【新世纪】群星-美丽人生(CestLaVie)(6CD)[WAV+CUE]
- ProteanQuartet-Tempusomniavincit(2024)[24-WAV]
- SirEdwardElgarconductsElgar[FLAC+CUE]
- 田震《20世纪中华歌坛名人百集珍藏版》[WAV+CUE][1G]
- BEYOND《大地》24K金蝶限量编号[低速原抓WAV+CUE][986M]
- 陈奕迅《准备中 SACD》[日本限量版] [WAV+CUE][1.2G]