Skip to content

🚤 iframe 操作

<iframe>元素是一种特殊的元素,它既是元素,也是页面,因此独立一个章节对其进行介绍。

与 selenium 不同,DrissionPage 无需切入切出即可处理<iframe>元素。因此可实现跨级元素查找、元素内部单独跳转、同时操作<iframe>内外元素、多线程控制多个<iframe>等操作,功能更灵活,逻辑更清晰。

我们使用菜鸟教程在线编辑器来演示:

菜鸟教程在线编辑器 (runoob.com)

源代码框内容要作一点调整,然后按“点击运行”:

<!DOCTYPE html>
<html>        
    <head> 
        <meta charset="utf-8"> 
        <title>菜鸟教程(runoob.com)</title> 
    </head> 

    <body>
        <iframe id="sss" src="https://www.runoob.com">
            <p>您的浏览器不支持  iframe 标签。</p>
        </iframe>
    </body>
</html>

F12,可以看到网页右侧是一个两层<iframe>,一个 id 是'iframeResult'<iframe>里面有一个 id 是'sss'<iframe>。最里层的<iframe> 页面指向 https://www.runoob.com。


✅️ 获取<iframe>对象

获取<iframe>对象的方法有两种,可用获取普通元素的方式获取,或者用get_frame()方法获取。推荐优先使用get_frame()方法,因为当作普通元素获取时,IDE 无法正确识别获取到的时<iframe>元素。

📌 get_frame()

此方法用于获取页面中一个<frame><iframe>对象。

参数名称 类型 默认值 说明
loc_ind_ele str
int
ChromiumFrame
必填 定位符
<iframe>元素序号(从1开始)
ChromiumFrame对象
id属性内容
name属性内容
timeout float None 超时时间,为None时使用页面超时时间
返回类型 说明
ChromiumFrame <frame><iframe>元素对象
NoneElement 找不到时返回NoneElement

示例:

# 使用定位符获取
iframe = page.get_frame('#sss')

# 获取第2个iframe
iframe = page.get_frame(2)

📌 get_frames()

此方法用于获取页面中多个符合条件的<frame><iframe>对象。

参数名称 类型 默认值 说明
loc_ind_ele str
int
ChromiumFrame
None 定位符,为None时返回所有
timeout float None 超时时间,为None时使用页面超时时间
返回类型 说明
List[ChromiumFrame] <frame><iframe>元素对象组成的列表

📌 普通元素方式

可以用获取普通元素的方式获取<iframe>对象:

iframe = page('#sss')
print(iframe.html)

输出:

<iframe id="sss" src="https://www.runoob.com"><html><head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>菜鸟教程 - 学的不仅是技术,更是梦想!</title>

  <meta name="robots" content="max-image-preview:large">

下面省略。。。

这个ChromiumFrame对象既是页面也是元素。由于 IDE 不会提示<iframe>元素对象相关的属性和方法,因此用这种方式获取时建议再用get_frame()包装一下:

iframe = page('#sss')
iframe = page.get_frame(iframe)

✅️ 查找<iframe>内元素

从刚才获取元素对象看出,我们并不须要先切入 id 为'iframeResult'<iframe>,就可以获取到里面的元素。所以我们获取元素也并不一定要先获取到ChromiumFrame对象。

📌 在<iframe>内查找

使用我们刚才获取到的元素,可以在里面查找元素:

ele = iframe('首页')
print(ele)

输出:

<ChromiumElement a href='https://www.runoob.com/' data-id='index' title='菜鸟教程' class='current'>

📌 页面跨<iframe>查找

如果<iframe>元素的网址和主页面是同域的,我们可以直接用页面对象查找<iframe>内部元素,而无需先获取ChromiumFrame对象:

ele = page('首页')
print(ele)

输出:

<ChromiumElement a href='https://www.runoob.com/' data-id='index' title='菜鸟教程' class='current'>

只要是同域名的,无论跨多少层<iframe>都能用页面对象直接获取。


📌 与 selenium 对比

WebPage

from DrissionPage import WebPage

page = WebPage()
ele = page('首页')

MixPage(基于 selenium):

from DrissionPage import MixPage

page = MixPage()
page.to_frame('#iframeResult')
page.to_frame('#sss')
ele = page('首页')
page.to_frame.main()

可见,原来的逻辑要切入切出,比较繁琐。


📌 重要事项

如果<iframe>跟当前标签页是不同域名的,不能使用页面对象直接查找其中元素,只能先获取其ChromiumFrame元素对象,再在这个对象中查找。


✅️ ChromiumFrame的元素特征

正如上面所说,ChromiumFrame既是元素也是页面,这里说一下其元素方面的用法。

📌 tag

此属性返回元素名称。

类型:str


📌 html

此属性返回整个<iframe>元素的 outerHTML 文本。

类型:str


📌 inner_html

此属性返回 innerHTML 文本。

类型:str


📌 attrs

此属性以dict形式返回元素所有 attribute 属性。

类型:dict


📌 size

此属性以tuple形式返回元素大小。

类型:Tuple[int, int]


📌 location

此属性以tuple形式返回元素在主页面中的位置,左上角为 (0, 0)。

类型:Tuple[int, int]


📌 locations

此属性返回用于获取大小和位置的对象,用法与ChromiumElement一致。


📌 states.is_displayed

此属性返回元素是否可见。

类型:bool


📌 xpath

此属性返回元素在其页面上的 xpath 路径。

类型:str


📌 css_path

此属性返回元素在其页面上的 css selector 路径。

类型:str


📌 attr()

此方法用于一个获取元素 attribute 属性。

参数名称 类型 默认值 说明
attr str 必填 属性名
返回类型 说明
str 属性值文本
None 没有该属性返回None

📌 set.attr()

此方法用于设置元素的 attribute 属性。

参数名称 类型 默认值 说明
attr str 必填 属性名
value str 必填 属性值

返回:None


📌 remove_attr()

此方法用于删除元素的 attribute 属性。

参数名称 类型 默认值 说明
attr str 必填 属性名

返回:None


📌 相对定位

相对定位方法与普通元素一致,详见获取元素章节。

  • parent():返回上面某一级父元素。

  • prev():返回前面的一个兄弟元素。

  • next():返回后面的一个兄弟元素。

  • before():返回当前元素前面的一个元素。

  • after():返回当前元素后面的一个元素。

  • prevs():返回前面全部兄弟元素或节点组成的列表。

  • nexts():返回后面全部兄弟元素或节点组成的列表。

  • befores():返回当前元素后面符合条件的全部兄弟元素或节点组成的列表。


✅️ ChromiumFrame的页面特征

📌 url

此属性返回页面当前 url。

类型:str


📌 title

此属性返回页面当前 title 文本。

类型:str


📌 cookies

此属性返回页面当前 cookies 内容。

类型:dict


📌 get()

此方法用于实现<iframe>页面跳转,使用方法与ChromiumPage一致。

iframe.get('https://www.runoob.com/css3/css3-tutorial.html')

📌 refresh()

此方法用于刷新页面。

参数: 无

返回:None

iframe.refresh()

📌 ready_state

此属性为页面加载状态,包括'loading''interactive''complete'3 种。

类型:str


📌 is_loading

此属性返回页面是否正在加载。

类型:bool


📌 active_ele

此属性返回页面中焦点所在元素。

类型:ChromiumElement


📌 frame_size

此属性以tuple形式返回页面大小。

类型:Tuple[int, int]


📌 run_js()

此方法用于在<iframe>内执行 js 脚本。

参数名称 类型 默认值 说明
script str 必填 js 脚本文本
*args - 传入的参数,按顺序在js文本中对应arguments[0]arguments[1]...
as_expr bool False 是否作为表达式运行,为Trueargs参数无效
返回类型 说明
Any 脚本执行结果

📌 scroll

ChromiumFrame的滚动方法与页面或元素是一致的。

示例: 使<iframe>元素向下滚动 300 像素

iframe.scroll.down(300)

📌 get_screenshot()

此方法用于对<iframe>进行截图。由于技术限制,只能对视口截图。

下面三个参数三选一,优先级:as_bytes>as_base64>path

参数名称 类型 默认值 说明
path str
Path
None 保存图片的完整路径,文件后缀可选'jpg''jpeg''png''webp'
None时以 jpg 格式保存在当前文件夹
as_bytes str
True
None 是否以字节形式返回图片,可选'jpg''jpeg''png''webp'NoneTrue
不为Nonepathas_base64参数无效
True时选用 jpg 格式
as_base64 str
True
None 是否以 base64 形式返回图片,可选'jpg''jpeg''png''webp'NoneTrue
不为Nonepath参数无效
True时选用 jpg 格式
返回类型 说明
bytes as_bytes生效时返回图片字节
str as_bytesas_base64None时返回图片完整路径
str as_base64生效时返回 base64 格式的字符串