1. 为什么需要 JS
前面 3 篇文章讲了 Selenium 的一些基本操作,利用这部分技能,大部分网站的自动化都能顺利完成。
但是,也有一些网站的网页操作没法利用 WebDriver API 来完成,也有一些功能即使利用 WebDriver API 实现了,兼容性也不强,经常需要去维护这套脚本,比如:浏览器的位置滑动、元素点击失效、选择日期等。
这时候,利用 JavaScript 直接操作网页内部元素,能够辅助我们完成 Selenium 自动化测试中不能覆盖的功能。
2. 怎么使用
Selenium 提供了下面这个方法:
代码语言:javascript复制driver.execute_script(js_code)
其中 js_code 是一段 JS 脚本,常见的 JS 脚本包含:设置元素属性、移除属性、设置元素值、设置窗口位置等
和 Selenium CSS Selector 类型,利用 JS 查找元素的方式包含下面这 6 种:
代码语言:javascript复制# 1、通过元素id属性,获取元素
document.getElementById('id');
# 2、通过元素name属性,获取元素
document.getElementsByName('name');
# 3、通过标签名,获取元素列表
# 获取的是一个列表
document.getElementsByTagName('tag_name');
# 4、通过类名,获取元素列表
document.getElementsByClassName("class_name");
# 5、通过选择器,获取一个元素
document.querySelector("css selector")
# 6、通过CSS选择器,获取元素列表
document.querySelectorAll("css selector")
拿到元素之后,就可以操作元素属性了,比如:
代码语言:javascript复制# 操作属性值
# 设置元素某一个元素值
element.setAttribute('属性名','属性值')
# 设置元素值
element.value="element_value";
# 删除属性
element.removeAttribute('属性名')
组合上面的 3 个操作,即可以通过 JS 改变一个网页元素的值了。
代码语言:javascript复制# 待执行的js语句
exec_js = 'document.getElementById(element_id).value="element_value";'
# 执行js语句改变元素的值
driver.execute_script(exec_js)
3. 常见操作
以打开 12306 网站,选择一个出发日期为例。
首先,利用常规模式编写一波自动化,利用 WebDriver 找到元素,然后直接给元素设置一个日期值。
运行后会直接报错,运行日志会提示目标元素存在一个不可以编辑的属性 - readonly
这时候通过 JS 方法可以很方便地去掉这个属性,然后再加上对元素的属性操作,就能正常的设置日期。
改写后的代码如下:
代码语言:javascript复制from time import sleep
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.12306.cn/index/')
# 去除掉元素的属性
exec_js = 'document.getElementById("train_date").removeAttribute("readonly");'
driver.execute_script(exec_js)
# 输入日期
element_train_date = driver.find_element_by_id("train_date")
element_train_date.clear()
element_train_date.send_keys("2012-12-12")
sleep(5)
driver.quit()
当然,除了去掉元素属性外,也可以先利用 JS 查找元素的语法获取目标元素,然后直接对元素设置一个日期,也能满足我们的需求。
代码语言:javascript复制# 找到元素,直接设置一个容器
exec_js = 'document.getElementById("train_date").value="2012-12-12";'
# 执行js代码
driver.execute_script(exec_js)
4. 其他
Selenium 自动化的很多操作都能转换为 JS 语句,然后利用 execute_script() 也能完成相同的功能。
但是,实际使用自动化的过程中,JS 只是作为一个补充,协助我们完成一些 WebDriver 没法实现的功能。