如何在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层级,加大定位难度,直接访问目标页面更高效。
解决思路
- 直接访问目标页面
https://www.keyboardtester.com/tester.html,避免额外的iframe层级 - 获取iframe元素后,通过
iframe.get_content()切换到iframe的上下文(获取对应的tab对象) - 在iframe上下文内定位输入框元素
- 使用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
相关产品推荐
相关产品推荐

