• Selenium—iframe的操作


    什么是iframe?

    <iframe> 标签是一个内联框架,即用来在当前 HTML 页面中嵌入另一个文档的,且所有主流浏览器都支持iframe标签。

    简单说,就是在一个页面内,又嵌入了一个页面,看似是一个页面,但是在selenium中,无法对iframe内元素进行直接定位

    示例:

      打印出网易云音乐-云音乐热歌榜中前10首歌曲名

    我们先定位出排行榜中前10首歌曲的元素

    简单说一下,为什么使用红色框内的 id 信息

    1. 定位元素,一般我们会直接先定位到某一首歌曲信息,此时我们发现该歌曲的 id 属性值为一长串数字,此时我们有必要怀疑,该数值是随机生成的

    2. 验证:复制该元素的 id 属性值,刷新界面,重新查看该元素的 id 属性值,是否与刚刚复制下来的内容一致,如不一致,则验证了第 1 条的假设

    3. 验证第 1 条之后,此时我们需要做的就是往上层找,看看是否存在我们能直接定位到元素的属性值

    4. 父元素的 class 属性值,可以直接准确定位,则该元素可用

    5. 再往上找,蓝色框内的 id 属性值可以看出,均存在乱序内容,我们第一反应就应该为 该属性值 不可用

    6. 再往上找到 id = song-list-pre-cache 的属性值,可以看出是有序的,可直接定位

    7. 此时,第 4 条与第 6 条均可实现精准定位,作者这里是习惯性的使用了 id 属性

     查找到元素后,我们直接撸代码,打印出歌曲信息即可

    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)
    # 抓取排行榜信息
    driver.get('https://music.163.com/#/discover/toplist?id=3778678')
    
    div = driver.find_elements_by_css_selector('#song-list-pre-cache .m-table-rank tbody tr:nth-child(-n+10) b')
    
    # 使用for循环,获取到每首歌曲的元素,并打印出该元素的 text 属性值
    
    
    for one in div:
        print(one.get_attribute('title')) 
    
    driver.quit()

    输出结果:

    # 在漫长的隐式等待(10s)中,输出结果为空,并没有报错,这是为什么呢?

    知识点

    1. find_elements :注意 s ,复数;返回的为列表形式,如果为查找到元素,则返回空列表,无报错信息

    2. find_element : 定位某一元素,如果指定的时间内,未找到该元素,则会抛出错误

    修改一下我们的代码:

    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)
    # 抓取排行榜信息
    driver.get('https://music.163.com/#/discover/toplist?id=3778678')
    
    songList = driver.find_element_by_id('song-list-pre-cache')
    div = songList.find_elements_by_css_selector('.m-table-rank tbody tr:nth-child(-n+10) b')
    
    # 使用for循环,获取到每首歌曲的元素,并打印出该元素的 text 属性值
    for one in div:
        print(one.get_attribute('title')) 
    driver.quit()

    看一看我们的输出结果:

    阿西吧,果然报错了,错在第8行:songList = driver.find_element_by_id('song-list-pre-cache');但是我们明明可以在浏览器中定位到该元素啊?

    定位iframe

    定位没有问题,那么我们就需要考虑是不是 iframe 在搞鬼!

    重新查看一下我们的元素信息

    从红色的框框内,我们看到了 id="song-list-pre-cache" 的 父元素 和 子元素,我们往前找,蓝色框内,存在了一个 #g_iframe 的父元素

    点击蓝色区域,让我们看一下 iframe 

    我们可以确定了,排行榜的歌曲信息,是写在一个 iframe 框架内,那我们该如何操作 iframe 中的元素呢?

     

    切换iframe

    • 通过 id 切换,且 id 唯一

      • driver.switch_to.frame('g_iframe')
    • 通过 name 切换,且 name 唯一

      • driver.switch_to.frame('contentFrame')
    • 若无 id 和 name ,则需要先定位到 iframe ,然后再切换

      1. iframe = driver.find_elements_by_tag_name('iframe')[0]
      2. driver.switch_to.frame(iframe)

    切回主文档

      我们切入到 iframe 框架内进行操作后,需要再次回到主文档区域进行操作,就必须要切回主文档

    • driver.switch_to_default_content()

    多嵌套iframe

      既然主文档可以嵌套 iframe ,那么 iframe 同样可以嵌套 iframe ,那么存在这种多重嵌套我们要怎么处理呢?

    <html>
        <iframe id="frame1">
            <iframe id="frame2" / >
        </iframe>
    </html>

      如果我们需要操作 iframe2 中的元素,我们需要切换 2 次

    • 先从主文档切换至 iframe1
      • driver.switch_to.frame('iframe1')
    • 再从 iframe1 切换至 iframe2
      • driver.switch_to.frame('iframe2')

      

      我们切到 iframe2 中操作完之后,需要回到 iframe1 中进行操作,selenium 提供了一个更好的方式,避免了从 iframe2 切到主文档 再切到 iframe1 的复杂

    • 从 iframe2 切回至 iframe1

      • driver.switch_to.parent_frame()

    让我们来完成之前的需求:

    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)
    # 抓取排行榜信息
    driver.get('https://music.163.com/#/discover/toplist?id=3778678')
    
    # 定位到 iframe 的元素
    iframe = driver.find_elements_by_tag_name('iframe')[0]
    
    # 切到 iframe 框架内
    driver.switch_to.frame(iframe)
    
    songList = driver.find_element_by_id('song-list-pre-cache')
    div = songList.find_elements_by_css_selector('.m-table-rank tbody tr:nth-child(-n+10) b')
    
    # 使用for循环,获取到每首歌曲的元素,并打印出该元素的 text 属性值
    for one in div:
        print(one.get_attribute('title'))
    
    # 切到 iframe 的上一层,即为主文档
    driver.switch_to.parent_frame()
    
    # 打印主文档的一段内容
    meta = driver.find_element_by_css_selector('meta[name="description"]')
    print('
    '+meta.get_attribute('content'))
    
    driver.quit()

    输出结果如下:

    心如止水
    多想在平庸的生活拥抱你
    归去来兮
    晚安
    我曾
    四块五
    出山
    Monsters
    那个女孩
    像鱼
    
    网易云音乐是一款专注于发现与分享的音乐产品,依托专业音乐人、DJ、好友推荐及社交功能,为用户打造全新的音乐生活。

      

    参考文档:

      selenium切换到iframehttps://www.cnblogs.com/xiaoxiaolvdou/p/9316805.html

  • 相关阅读:
    上周热点回顾(5.9-5.15)团队
    上周热点回顾(5.2-5.8)团队
    上周热点回顾(4.25-5.1)团队
    .NET跨平台之旅:升级ASP.NET Core示例站点团队
    上周热点回顾(4.18-4.24)团队
    上周热点回顾(4.11-4.17)团队
    如何在Eclipse中正确安装Jetty插件并初步使用(图文详解)
    Spark Mllib里如何采用保序回归做回归分析(图文详解)
    机器学习概念之梯度下降算法(全量梯度下降算法、随机梯度下降算法、批量梯度下降算法)
    程序代码里出现illegal character 'ufeff' 和 expected class or object definition的解决办法(图文详解)
  • 原文地址:https://www.cnblogs.com/wilson-5133/p/10935835.html
Copyright © 2020-2023  润新知