• 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

  • 相关阅读:
    windows版redis
    苹果Mac电脑文件夹路径怎么看?“访达”也能显示文件路径
    Windows下Nginx初始化
    Win10微信查看图片卡顿或发送图片卡顿的原因和解决方法
    【Windows安装RabbitMQ详细教程】
    pb中打印设置
    字典pop,filter
    case when 用法
    自定义函数封装变量
    MySQL WorkBench 导入数据
  • 原文地址:https://www.cnblogs.com/wilson-5133/p/10935835.html
Copyright © 2020-2023  润新知