系统学习 execute_script 的核心语法、实操示例与最佳实践
JS 定位是在 Selenium 中通过 driver.execute_script() 方法把一段原生 JavaScript 代码注入浏览器执行,利用 JavaScript 内置的 DOM 查询 API(如 document.getElementById()、document.querySelector()、document.querySelectorAll()、document.forms['login'].username 等)来查找元素。注意:它并不是 Selenium 官方提供的定位器(没有 By.JS 或 By.EXECUTE_SCRIPT 这样的枚举值),而是一个"宿主注入"的机制 — Selenium 把 JS 字符串丢给浏览器引擎执行,浏览器返回的 DOM 节点自动映射为 Selenium 的 WebElement 对象。因此 JS 定位本质上是"借浏览器之力",绕过了 Selenium 8 种内置定位器(ID/NAME/CLASS/TAG/XPATH/CSS/LINK_TEXT/PARTIAL_LINK_TEXT)的能力边界。它的价值在于解决其他 8 种定位方式搞不定的场景:① shadow DOM 内部元素(常规选择器穿透不了);② 虚拟滚动列表中尚未渲染到 DOM 的元素;③ 需要计算后才能定位的元素(如"第 3 个可见的、有 data-id 属性且未被禁用的按钮");④ 绕过 click() 不生效的问题(用 JS 直接触发事件)。使用时注意:JS 代码字符串里不能直接引用 Python 变量,需要用 arguments[0] 占位符传参。
driver.execute_script("return document.getElementById('demo-js-username');") (getElementById)driver.execute_script("return document.getElementsByName('demo-js-input')[0];") (getElementsByName)driver.execute_script("return document.getElementsByClassName('demo-js-btn')[0];") (getElementsByClassName)driver.execute_script("return document.getElementsByTagName('button')[0];") (getElementsByTagName)driver.execute_script("return document.querySelector('.demo-js-card');") (querySelector)driver.execute_script("return document.querySelectorAll('.demo-js-card');") (querySelectorAll) ① 选择套餐(3 个 .demo-js-card,可被 querySelector / querySelectorAll 命中)
② 录入开通手机号(可被 getElementById 命中)
该输入框 id="demo-js-username",高级 JS 定位会用 execute_script 直接注入 value
document.getElementById('id'),返回单个元素,速度最快。document.getElementsByClassName('btn'),返回 HTMLCollection(有 length、可索引),多个 class 空格分隔时只取一个。document.getElementsByName('username'),返回同名元素列表(常用于单选按钮组、表单控件),页面同名时返回全部匹配。document.getElementsByTagName('input'),返回页面上全部该标签的元素列表,配合父元素可做层级缩小搜索。document.querySelector('.cls'),CSS 选择器语法,返回首个匹配。document.querySelectorAll('.cls'),返回 NodeList,需 list() 转换。arguments[0],向 execute_script 传递已定位的 WebElement。.value = '...',绕过 send_keys 直接注入值。