selenium+python实现1688登录 —— iframe中元素获取


selenium+python实现1688登录 —— iframe中元素获取

1. 背景

  • 在1688网站登录时,无法通过 browser.find_element_by_xpath 直接获取到用户名和密码的输入框。
  • 从网页源代码分析,发现这个网页是一个iframe嵌套的模式,所以按照传统的方式无法定位到表单元素。

2. 环境

  • python 3.6.1
  • 系统:win7
  • IDE:pycharm
  • 安装过chrome浏览器
  • 配置好chromedriver
  • selenium 3.7.0

3. 分析过程

3.1. 进入1688登录页面,分析网页结构。

这里写图片描述

这里写图片描述

  • 也就是说,登录框是以子页面(iframe)的方式嵌入在主页面中的。
  • 所以按照以下的方式是无法获得“密码登录”这个超链接的。
# 寻找使用用户名和密码登陆的链接,并点击
links = browser.find_elements_by_tag_name("a")
for link in links:
# print(f"linkText1 = {link.text}, link = {link}")
if link.text == '密码登录':
link.click()
break
  • 需要在此之前将focus由default content转到这个frame:
# 切换到登录框frame
# 这种是网页中有frame嵌套,而且没有标记,不知道frame的name,通过源代码,知道是第一个iframe
browser.switch_to.frame(browser.find_elements_by_tag_name("iframe")[0])
  • 切换到frame的方式(browser.switch_to.frame)有三种,引用源代码中的注释:
"""
Switches focus to the specified frame, by index, name, or webelement.

:Args:
- frame_reference: The name of the window to switch to, an integer representing the index,
or a webelement that is an (i)frame to switch to.

:Usage:
driver.switch_to.frame('frame_name') # iframe标签的name属性
driver.switch_to.frame(1)
driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])
"""

3.2. 点击密码登录,分析网页结构。

  • 此时网页结构并未发生变化:
    这里写图片描述
# 输入用户名和密码
userNameInput = browser.find_element_by_xpath("//input[@name='TPL_username']")
userNameInput.clear()
userNameInput.send_keys(userName)

userPassword = browser.find_element_by_xpath("//input[@name='TPL_password']")
userPassword.clear()
userPassword.send_keys("ancode2017")
time.sleep(5)
# 敲enter键
userPassword.send_keys(Keys.RETURN)
time.sleep(30)
  • 此时大概率情况下,会直接通过。小概率会进行滑块验证码 + 手机短信验证。

3.3. 进入短信验证码页面,分析网页结构。

  • 此时网页结构又发生了变化:
    这里写图片描述

  • 分析源码可以看到手机验证输入框处于 Main ——> iframe ——> iframe两层嵌套之内。

  • 所以,需要再次改变focus
# 首先切换到新的 frame,这个是原来登录frame下又嵌套了一层frame
# 当前browser的focus已经是中间层的frame,所以这里只要再switch一层即可
browser.switch_to.frame(browser.find_elements_by_tag_name("iframe")[0])
# 寻找发送手机验证码按钮
messageSendButton = browser.find_element_by_xpath("//button[@id='J_GetCode']")
print(f"messageSendButton = {messageSendButton}")
messageSendButton.click()

# 手动获得手机验证码,并输入到程序中
messageConfirm = input("Enter your message confirm:")
print(f"messageConfirm = {messageConfirm}")

# 输入手机验证码
messageConfirmInput = browser.find_element_by_xpath("//input[@id='J_Checkcode']")
messageConfirmInput.clear()
messageConfirmInput.send_keys(messageConfirm)

# 提交
submit = browser.find_element_by_xpath("//button[@type='submit']")
submit.click()
# 进入页面
time.sleep(60)

4. 总结

  • 如果一个页面只有一个head, 一个body,那么可以直接使用browser.find_element_by_xxxx( )查找页面中的任何一个元素。
  • 假如页面中存在< iframe ………….. /iframe>的使用,使得一个html页面中包含多个子html页面。
    • 在这种情况下,使用browser.find_element_by_xxxx( )查找页面某个元素,如果元素是属于主html的,那么可以查找到。
    • 如果该元素是属于某个子的< iframe ………….. /iframe>下,使用browser.find_element_by_xxxx( )获取页面元素会失败。要想成功,首先要弄清楚该元素所属的frame的,并将focus切换到该frame
  • 方法是:先使用browser.switch_to.frame( ) , 然后再使用 browser.find_element_by_xxxx( )查找元素。
  • 操作完以后,如果想返回主页面,那么使用:browser.switch_to.default_content( )
  • 操作完以后,如果想返回上一级frame,那么使用:browser.switch_to.parent_frame( )

5. 代码


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com