第五章 框架切换

Web框架

Web自动化的对象是web,目的是对web页面进行自动选择和操作,所以对web设计的思想必须有所了解。很多的前端设计人员,比较喜欢采用框架来设计自己的界面,类似于程序的模块化设计思想。通过使用框架,调用其他的html,可以在同一个浏览器窗口中显示不止一个页面。

在框架设计中经常用到的标签有frame,frameset和iframe

  • FRAMESET是用以划分框窗
  • FRAME用来定义每一框窗
  • IFRAME可以创建包含另外一个文档的内联框架

frame

frame标签定义frameset(框架集)中的一个特定的窗口(框架),可以设置不同的属性,如 border、scrolling、noresize 等。可以参考w3c school-frame了解更多相关信息。

假设定义三个测试frame页面如下:

  • frame1
<!-- frame1.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>frame1</title>
        <meta charset="utf-8">
    </head>
    <body bgcolor="#00FFFF">
    <p>frame1</p>
    </body>
</html>
  • frame2
<!-- frame2.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>frame2</title>
        <meta charset="utf-8">
    </head>
    <body bgcolor="#006400">
    <p>frame2</p>
    </body>
</html>
  • frame3
<!-- frame3.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>frame3</title>
        <meta charset="utf-8">
    </head>
    <body bgcolor="#9932CC">
    <p>frame3</p>
    </body>
</html>

frameset

frameset为框架集标签,通过框架集标签的cols 或 rows 属性可以来定义如何将窗口进行分割。可以参考w3c school-frameset了解更多相关信息

例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>frameset</title>
    <meta charset="utf-8">
        <frameset cols="25%, 50%, 25%">
            <frame src="frame1.html">A</frame>
            <frame src="frame2.html">B</frame>
            <frame src="frame3.html">C</frame>
        </frameset>
</head>
<body>
</body>
</html>

效果如下:

image

iframe

iframe为inner frame的缩写,即内联框架,可以设置一个框架嵌套另外一个框架,iframe 用于在网页内显示网页。和frameset不同的是,frameset内置好几个子html,而iframe 只内置一个子html,可以参考w3c school-iframe了解更多相关信息

例如:

  • iframe_home
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>iframe home page</title>
</head>
    <iframe src="iframe1.html" frameborder="0" width="600" height="500"></iframe>
<body style="background-color:blue">
<p style="text-align:right;">Home</p>
</body>
</html>
  • iframe1
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>iframe1</title>
</head>
<body style="background-color:red">
 <iframe src="iframe2.html" frameborder="0" width="500" height="400"></iframe>
 <p style="text-align:right;">iframe1</p>
</body>
</html>
  • iframe2
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>iframe2</title>
</head>
<body style="background-color:white">
  <iframe src="iframe3.html" frameborder="0" width="400" height="300"></iframe>
 <p style="text-align:right;">iframe2</p>
</body>
</html>
  • iframe3
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>iframe3</title>
</head>
<body style="background-color:yellow">
 <p style="text-align:right;">iframe3</p>
</body>
</html>

效果如下

image

frame与iframe对比

frame和iframe有以下几点区别

  • frame不能脱离frameSet单独使用,iframe可以
  • frame不能放在body中
  • iframe可以随意使用
  • frame的高度只能通过frameSet控制;iframe可以自己控制
  • Iframe所包含的内容与整个页面是一个整体,而Frame所包含的内容是一个独立的个体

框架带来的问题

从上面的例子可以看出,frame或者iframe 都是一个单独的html 文档, 是被嵌入的另一份html文档。但是,在实际的工作中,默认打开的是主html, 但当编写web自动化程序的时候,有时要查看的页面元素是在嵌入的html中的时候,就会出现找不到的webElement的情况。

这种情况就如同在不同的世界里找自己感兴趣的页面元素,selenium的webdriver element默认对应的是主html,所以有时不能找到相应iframe里面的html 的元素。

框架切换

Selenium对于采用框架设计的的网页,提供了如下方法进行切换

  • 切换到expected_frame
# switch to expected_frame
driver.switch_to.frame('expected_frame')

切换到expected_frame可以通过:

  1. frame元素的属性值,如name或者ID值
  2. 索引值
  3. frame 所对应的WebElement
driver.find_element_by_tag_name("iframe")
  • 切换到主默认页面
# switch back to main frame
driver.switch_to.default_content()

项目实战

  1. 访问网易音乐
  2. 获取云音乐飙升榜q前100首歌的信息
  3. 按照“歌手:歌名”的格式打印出来

完整程序如下

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from selenium import  webdriver

driver = webdriver.Chrome(r"G:\Education\BYHY\Courseware\Improvement\Selenium\chromedriver.exe")
driver.implicitly_wait(5)
# ================================================

# open URL
driver.get('https://music.163.com/#/discover/toplist')

# switch to frame
driver.switch_to.frame('g_iframe')

musicList = driver.find_element_by_id('song-list-pre-cache')
# print(musicList.text)

musicInfoList = driver.find_element_by_tag_name('tbody').find_elements_by_tag_name('tr')
#print(musicInfoList)

for musicInfo in musicInfoList:
    # musicName = driver.find_element_by_tag_name('b').get_attribute('title')
    musicName = musicInfo.find_element_by_class_name('ttc').find_element_by_tag_name('b').get_attribute('title')
    singerName = musicInfo.find_element_by_class_name('text').get_attribute('title')
    #print(musicInfo.text)

    print(f'{singerName}: {musicName}')

# switch back
driver.switch_to.default_content()

# ==================================================

input('Please input any key to continue......')
# Quit
driver.quit()


本文还不错? 分享给你的朋友吧

上一页 下一页