Helium/Selenium点击页面多个可见元素时触发Lookup Error问题求助
问题原因
- 你提前调用
find_all(S('.year.expandable'))一次性获取了所有年份元素的引用,点击第一个年份后,AngularJS的指令触发页面DOM重绘,列表中剩余的元素引用已经失效(属于过时DOM节点),helium无法定位到对应元素就抛出LookupError。 - 你在未展开年份的前提下直接查询所有
.month.expandable元素,此时这些元素都带有ng-hide类处于隐藏状态,helium无法操作不可见元素,也会触发查找失败报错。 - 单次点击单个元素正常,是因为查询后立刻执行点击,DOM还未发生更新,引用仍然有效。
解决方案
方案1:避免提前缓存DOM引用,每次循环重新查询元素
逐个处理年份,每次点击前重新查询对应元素,点击年份后再处理当前可见的月份元素:
from helium import wait_until, get_driver # 先获取年份总数,后续循环按索引取元素避免缓存 year_total = len(find_all(S('.year.expandable'))) for idx in range(year_total): # 每次循环重新查询,保证元素引用有效 current_year = find_all(S('.year.expandable'))[idx] click(current_year) # 等待当前年份下的月份元素取消隐藏 wait_until(lambda: 'ng-hide' not in S(f'tbody:nth-child({idx+1}) .month.expandable').web_element.get_attribute('class')) # 遍历点击当前年份下所有月份 for month in find_all(S(f'tbody:nth-child({idx+1}) .month.expandable')): click(month)
方案2:直接调用JavaScript执行点击,不受可见性和DOM引用限制
该方案跳过helium的元素可见性校验,直接触发元素的点击事件,执行效率更高也更稳定:
from helium import wait_until, get_driver driver = get_driver() # 批量点击所有年份 driver.execute_script("document.querySelectorAll('.year.expandable').forEach(el => el.click())") # 等待所有月份加载显示 wait_until(lambda: len(find_all(S('.month.expandable:not(.ng-hide)'))) > 0) # 批量点击所有月份 driver.execute_script("document.querySelectorAll('.month.expandable').forEach(el => el.click())")
内容的提问来源于stack exchange,提问作者MrSlash
相关产品推荐
相关产品推荐

