大数跨境
0
0

Playwright(Python) 解决iframe 上下文定位功能完整方案,附代码(下)

Playwright(Python) 解决iframe 上下文定位功能完整方案,附代码(下) 51Testing软件测试网
2025-12-05
1
点击蓝字,立即关注


接上篇《Playwright(Python) 解决iframe 上下文定位功能完整方案,附代码,今天我们将带领大家继续学习“完整的实战代码”以及其“运行原理”等内容,正文如下:


05

完整的实战代码


from playwright.sync_api import sync_playwrightimport timedef find_element_with_iframe_context(page, selector, timeout=10, verbose=False):    """    查找元素并确定它所在的iframe,同时收集iframe的详细信息    参数:        page: Playwright页面对象        selector: 要查找的元素选择器        timeout: 等待元素出现的超时时间(秒)        verbose: 是否打印详细过程信息    返回:        包含元素和iframe信息的字典,如果找不到返回None    """    start_time = time.time()    last_frame_count = 0    while time.time() - start_time < timeout:        # 获取当前所有frame(包括主frame和iframe)        frames = page.frames        if verbose:            print(f"\n检查帧... 当前帧数: {len(frames)}")            if len(frames) != last_frame_count:                print("帧数量变化,重新扫描")                last_frame_count = len(frames)        # 1. 首先在主frame中查找        if verbose:            print("检查主frame...")        main_frame = frames[0]        element = main_frame.query_selector(selector)        if element:            if verbose:                print("元素在主frame中找到")            return {                'element': element,                'frame_type''main_frame',                'frame': main_frame,                'frame_info': {                    'url': main_frame.url,                    'name''main_frame',                    'title': main_frame.title(),                    'parent_frame'None                }            }        # 2. 检查所有iframe        for i, frame in enumerate(frames[1:], start=1):            try:                if verbose:                    print(f"检查iframe #{i}...")                # 获取iframe元素句柄                frame_element = frame.frame_element()                # 尝试在iframe中查找元素                element = frame.query_selector(selector)                if element:                    if verbose:                        print(f"元素在iframe #{i}中找到")                    # 收集iframe的详细信息                    frame_info = {                        'url': frame.url,                        'name': frame.name or f"iframe_{i}",                        'title': frame.title(),                        'parent_frame': frame.parent_frame.url if frame.parent_frame else None,                        'html_attributes': {}                    }                    # 获取iframe元素的HTML属性                    attrs = ['id''class''src''width''height''title']                    for attr in attrs:                        value = frame_element.get_attribute(attr)                        if value:                            frame_info['html_attributes'][attr] = value                    return {                        'element': element,                        'frame_type''iframe',                        'frame': frame,                        'frame_info': frame_info                    }            except Exception as e:                if verbose:                    print(f"检查iframe #{i}时出错: {str(e)}")                continue        # 短暂等待后重试        time.sleep(0.5)    return None  # 超时后仍未找到元素def print_frame_info(frame_info):    """打印frame的详细信息"""    print("\n=== Frame信息 ===")    print(f"类型: {'主frame' if frame_info['frame_type'] == 'main_frame' else 'iframe'}")    print(f"URL: {frame_info['frame_info']['url']}")    print(f"标题: {frame_info['frame_info']['title']}")    if frame_info['frame_type'] == 'iframe':        print("\niframe详细信息:")        print(f"名称: {frame_info['frame_info']['name']}")        print(f"父frame URL: {frame_info['frame_info']['parent_frame']}")        print("HTML属性:")        for attr, value in frame_info['frame_info']['html_attributes'].items():            print(f"  {attr}{value}")def main():    with sync_playwright() as p:        browser = p.chromium.launch(headless=False)        page = browser.new_page()        # 导航到测试页面(这里用包含iframe的示例页面)        page.goto('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe')        # 等待页面加载        page.wait_for_load_state('networkidle')        # 要查找的元素选择器(这里选择iframe内的h1元素作为示例)        target_selector = 'h1'        # 查找元素并确定iframe上下文        result = find_element_with_iframe_context(            page,             selector=target_selector,            timeout=15,            verbose=True        )        if result:            print("\n=== 元素找到 ===")            print(f"元素选择器: '{target_selector}'")            print(f"元素文本内容: {result['element'].inner_text()}")            # 打印frame的详细信息            print_frame_info(result)            # 现在你可以使用result['frame']来操作这个frame            # 例如: result['frame'].click(target_selector)        else:            print(f"\n未找到元素: '{target_selector}'")        browser.close()if __name__ == '__main__':    main()


代码运行原理

1、初始化阶段:

  • 使用 sync_playwright() 创建 Playwright 实例;

  • 启动浏览器并创建新页面;

  • 导航到目标 URL。


2、查找元素过程:

  • 函数 find_element_with_iframe_context 开始执行;

  • 进入循环,在超时时间内不断尝试查找元素;

  • 首先在主 frame (frames[0]) 中尝试查找元素;

  • 如果主 frame 中找不到,则遍历所有 iframe (frames[1:]);

  • 在每个 iframe 中尝试查找目标元素;

  • 如果找到元素,收集该 iframe 的详细信息并返回。


3、信息收集:

对于找到元素的 iframe,收集以下信息:

  • URL;

  • 名称(name属性);

  • 标题(title);

  • 父 frame 的 URL;

  • HTML 属性(id, class, src 等)。


4、结果输出:

  • 打印找到的元素信息;

  • 打印所在 frame 的详细信息。


参数详细说明

find_element_with_iframe_context 函数参数:

1、page (必需):

  • 类型: playwright.sync_api.Page;

  • 说明: Playwright 的页面对象,代表当前浏览器标签页;


2、selector (必需):

  • 类型: str;

  • 说明: 要查找的元素 CSS 选择器,如 '#my-button' 或 '.content h1'。


3、timeout (可选,默认10):

  • 类型: int 或 float;

  • 说明: 等待元素出现的最大时间(秒),超时后返回 None。


4、verbose (可选,默认False):

  • 类型: bool;

  • 说明: 是否打印详细的查找过程信息,用于调试。


返回值说明

返回一个包含以下键的字典(如果找到元素):

1、element:

  • 类型: playwright.sync_api.ElementHandle;

  • 说明: 找到的元素句柄,可用于后续操作。


2、frame_type:

  • 类型: str;

  • 说明: 'main_frame' 或 'iframe',表示元素所在 frame 类型。


3、frame:

  • 类型: playwright.sync_api.Frame;

  • 说明: 元素所在的 frame 对象,可用于后续操作。


4、frame_info:

  • 类型: dict

  • 说明: 包含 frame 详细信息的字典,包括:


    • url: frame 的当前 URL;

    • name: frame 的 name 属性;

    • title: frame 的标题;

    • parent_frame: 父 frame 的 URL (如果是 iframe);

    • html_attributes: iframe 元素的 HTML 属性(id, class 等)。


图片
END


链接:

https://juejin.cn/post/7528128417356775466

本文为51Testing经授权转载,转载文章所包含的文字来源于作者。如因内容或版权等问题,请联系51Testing进行删除




图片
点点赞
图片
点分享
图片
点推荐

【声明】内容源于网络
0
0
51Testing软件测试网
博为峰51Testing软件测试网提供各种线上招聘、线上课程等网络服务,出版软件测试系列丛书及电子杂志,组织线上技术交流活动;同时还举办多种线下公益活动,如软件测试沙龙、软件测试专场招聘会等。
内容 3878
粉丝 0
51Testing软件测试网 博为峰51Testing软件测试网提供各种线上招聘、线上课程等网络服务,出版软件测试系列丛书及电子杂志,组织线上技术交流活动;同时还举办多种线下公益活动,如软件测试沙龙、软件测试专场招聘会等。
总阅读100
粉丝0
内容3.9k