您的位置:首页 > 编程语言 > Python开发

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

2017-11-16 17:55 761 查看

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. 代码

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: