You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在iframe中发送快捷键?Nodriver框架按键模拟异常排查

问题描述

使用Nodriver框架开发机器人,目标是访问www.keyboardtester.com网站后,在输入框输入内容并按下Enter键。目前机器人无法定位iframe,查阅Git文档和支持资料未解决,手动操作正常,运行代码时报错:

Error: 'NoneType' object is not callable

原代码

import time
import asyncio
import nodriver as uc
from nodriver.cdp import fetch
from nodriver import *

async def website():
    browser_args = ['--disable-web-security', '--disable-site-isolation-trials']
    browser = await uc.start(browser_args=browser_args)
    
    try:
        tab = await browser.get("https://iframetester.com/?url=https://www.keyboardtester.com/tester.html")
        await asyncio.sleep(5)         

        # Select the iframe
        iframes = await tab.select('iframe')
        if iframes:
            iframe = iframes[0]
            
            # Now find the textarea inside the iframe
            input = await iframes.find("//textarea[@id='testarea']")
            if input:
                await asyncio.sleep(1)
                
                await input.send_keys("Test")
                
                # Simulate pressing Enter
                await input.send(uc.cdp.input_.dispatch_key_event(
                    type_="rawKeyDown",
                    windows_virtual_key_code=13,
                ))
                await input.send(uc.cdp.input_.dispatch_key_event(
                    type_="rawKeyUp",
                    windows_virtual_key_code=13,
                ))

                print('Entered')
            else:
                print("Unable to find text inside the iframe.")
        else:
            print("No iframes found on the page.")
      
        await asyncio.sleep(10)

    except Exception as e:
        print(f"Error: {e}")
    finally:
        browser.stop()

if __name__ == "__main__":
    uc.loop().run_until_complete(website())
问题原因
  • 方法调用对象错误:代码中获取iframes列表后,错误调用iframes.find(),但列表对象没有find方法,返回None,后续调用时触发'NoneType' object is not callable错误。
  • 未切换iframe上下文:Nodriver中操作iframe内部元素需要先切换到iframe的执行上下文,直接在主页面上下文无法定位内部元素。
  • 多余的代理访问:通过iframetester.com间接访问目标页面,增加了额外的iframe层级,加大定位难度,直接访问目标页面更高效。
解决思路
  1. 直接访问目标页面https://www.keyboardtester.com/tester.html,避免额外的iframe层级
  2. 获取iframe元素后,通过iframe.get_content()切换到iframe的上下文(获取对应的tab对象)
  3. 在iframe上下文内定位输入框元素
  4. 使用Nodriver内置的send_keys结合Key.ENTER简化Enter键模拟逻辑
修正后的代码
import asyncio
import nodriver as uc

async def website():
    browser_args = ['--disable-web-security', '--disable-site-isolation-trials']
    browser = await uc.start(browser_args=browser_args)
    
    try:
        # 直接访问目标页面,减少层级
        tab = await browser.get("https://www.keyboardtester.com/tester.html")
        await asyncio.sleep(3)         

        # 定位页面中的iframe
        iframes = await tab.select('iframe')
        if iframes:
            iframe = iframes[0]
            # 切换到iframe的上下文,获取对应的tab对象
            iframe_tab = await iframe.get_content()
            await asyncio.sleep(2)
            
            # 在iframe上下文中定位输入框
            input_box = await iframe_tab.select_one("#testarea")
            if input_box:
                # 输入文本
                await input_box.send_keys("Test")
                # 直接发送Enter键
                await input_box.send_keys(uc.cdp.input_.Key.ENTER)
                
                print("输入完成并按下Enter键")
            else:
                print("未找到iframe内的输入框")
        else:
            print("页面中未找到iframe")
      
        await asyncio.sleep(10)

    except Exception as e:
        print(f"错误: {e}")
    finally:
        browser.stop()

if __name__ == "__main__":
    uc.loop().run_until_complete(website())

内容的提问来源于stack exchange,提问作者Vinix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 12:16:19