如何向带data-dojo-attach-point属性的地址栏输入文本
问题描述
使用如下Python Selenium代码向Esri地图的搜索地址栏输入文本:
driver.find_element_by_xpath('//*[@id="esri_dijit_Search_0_input"]').send_keys('text')
非调试模式运行时,代码无法成功输入任何内容。目标地址栏的HTML结构如下:
<form data-dojo-attach-point="formNode"> <input maxlength="128" autocomplete="off" type="text" tabindex="0" class="searchInput" value="" aria-haspopup="true" id="esri_dijit_Search_0_input" data-dojo-attach-point="inputNode" role="textbox" placeholder="Address or Grid Reference" title="Address or Grid Reference" style="width: 170px;"> </form>
失效原因
该输入框是Dojo框架渲染的Esri搜索组件,非调试模式下脚本执行速度远快于调试模式,常见失效原因有三点:
- DOM节点渲染完成但组件未完成初始化,事件监听还未绑定,直接输入不会被组件识别
- 旧版Selenium的
find_element_by_xpath接口本身稳定性差,高版本Selenium已废弃该系列接口 - 元素未激活、被遮挡或不在可交互状态,输入操作被拦截
解决方案
方案1:显式等待+稳定定位(优先使用)
放弃旧版定位接口,使用ID定位(该输入框ID唯一固定,比XPath稳定性更高),搭配显式等待判断元素可交互后,先点击激活输入框再输入内容:
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 最长等待10秒,直到输入框进入可交互状态 search_input = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "esri_dijit_Search_0_input")) ) # 点击激活输入框,清空残留内容后输入 search_input.click() search_input.clear() search_input.send_keys("需要输入的地址内容")
如果存在元素被遮挡的情况,可先滚动到元素位置再操作:
from selenium.webdriver.common.action_chains import ActionChains ActionChains(driver).scroll_to_element(search_input).perform() search_input.click() search_input.clear() search_input.send_keys("需要输入的地址内容")
方案2:JS注入输入(适配Dojo事件绑定特殊场景)
如果方案1仍无法输入,说明Selenium的原生输入触发的事件没有被Dojo框架捕获,可直接通过JavaScript给输入框赋值,手动派发组件监听的输入事件:
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC search_input = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "esri_dijit_Search_0_input")) ) input_content = "需要输入的地址内容" driver.execute_script(""" const el = arguments[0]; const text = arguments[1]; el.focus(); el.value = ''; el.value = text; // 手动派发Dojo组件监听的输入、变更事件 el.dispatchEvent(new Event('input', {bubbles: true})); el.dispatchEvent(new Event('change', {bubbles: true})); """, search_input, input_content)
注意事项
- 不要使用固定时长的
time.sleep()等待,优先用上述显式等待逻辑,既可以保证组件加载完成后立刻执行,也不会因为等待时长不足导致操作失效 - 若页面存在多个Esri搜索组件,先确认目标输入框的ID序号,避免定位到其他隐藏的同名元素
内容的提问来源于stack exchange,提问作者Valeriy Willetts
相关产品推荐
相关产品推荐

