pin_drop当前位置:知识文库 ❯ 图文
Selenium执行JavaScript教程 - execute_script与异步方法详解
目录
一、执行JavaScript概述
Selenium通过execute_script()和execute_async_script()方法在浏览器中直接执行JavaScript代码。这为自动化测试提供了强大的扩展能力,可以完成Selenium原生API不支持的操作,如滚动页面、修改元素样式、获取页面性能数据、触发自定义事件等。
当Selenium原生方法无法满足需求时,执行JavaScript是最强大的补充手段,几乎可以操作页面上的任何内容。
二、同步执行execute_script
execute_script()是同步执行方法,会阻塞等待JavaScript代码执行完成并返回结果。这是最常用的JS执行方式。
语法格式
代码示例
# 同步执行
result = driver.execute_script(script, *args)参数说明
三、异步执行execute_async_script
execute_async_script()用于执行异步JavaScript代码,适用于需要等待回调的场景,如setTimeout、Promise、Ajax请求等。
语法格式
代码示例
# 异步执行
result = driver.execute_async_script(script, *args)
重要提示:异步脚本中必须调用arguments[arguments.length - 1]作为回调函数来表示执行完成,否则会超时抛出异常。
代码示例
# 异步执行示例:等待3秒后返回结果
result = driver.execute_async_script("""
var callback = arguments[arguments.length - 1];
setTimeout(function() {
callback('异步任务完成');
}, 3000);
""")
print(result) # 输出: 异步任务完成四、Python与JavaScript数据传递
Selenium自动处理Python与JavaScript之间的数据类型转换,支持双向数据传递:
五、代码示例详解
示例1:页面滚动操作
使用JavaScript控制页面滚动是最常见的应用场景之一,包括滚动到顶部、底部、指定位置或滚动到特定元素:
代码示例
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.example.com")
driver.set_window_size(800, 600)
# 滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
print("已滚动到页面底部")
# 滚动到页面顶部
driver.execute_script("window.scrollTo(0, 0);")
print("已滚动到页面顶部")
# 滚动到指定位置
driver.execute_script("window.scrollTo(0, 300);")
print("已滚动到300px位置")
# 滚动到元素位置
element = driver.find_element(By.TAG_NAME, 'h1')
driver.execute_script("arguments[0].scrollIntoView();", element)
print("已滚动到元素位置")
driver.quit()输出结果:
代码示例
已滚动到页面底部
已滚动到页面顶部
已滚动到300px位置
已滚动到元素位置示例2:修改元素样式和属性
通过JavaScript可以直接修改DOM元素的样式、文本内容、属性等,这在处理隐藏元素或改变页面状态时非常有用:
代码示例
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.example.com")
heading = driver.find_element(By.TAG_NAME, 'h1')
# 修改元素样式
driver.execute_script(
"arguments[0].style.color = 'red'; arguments[0].style.fontSize = '50px';",
heading
)
print("已修改标题样式为红色50px")
# 修改元素文本
driver.execute_script("arguments[0].textContent = 'Modified by JS';", heading)
print(f"修改后文本: {heading.text}")
# 获取元素属性
text = driver.execute_script("return arguments[0].textContent;", heading)
print(f"JS获取文本: {text}")
# 隐藏元素
driver.execute_script("arguments[0].style.display = 'none';", heading)
print("已隐藏标题元素")
driver.quit()输出结果:
代码示例
已修改标题样式为红色50px
修改后文本: Modified by JS
JS获取文本: Modified by JS
已隐藏标题元素示例3:获取页面性能数据
通过JavaScript可以获取浏览器内置的性能API数据、页面尺寸、DOM元素信息等:
代码示例
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.example.com")
# 获取页面性能数据
performance = driver.execute_script(
"return JSON.stringify(window.performance.timing);"
)
print(f"性能数据: {performance[:100]}...")
# 获取页面高度
page_height = driver.execute_script("return document.body.scrollHeight;")
print(f"页面高度: {page_height}px")
# 获取视口尺寸
viewport = driver.execute_script(
"return {width: window.innerWidth, height: window.innerHeight};"
)
print(f"视口尺寸: {viewport}")
# 获取所有链接
links = driver.execute_script(
"return Array.from(document.querySelectorAll('a')).map(a => a.href);"
)
print(f"链接数量: {len(links)}")
for link in links:
print(f" {link}")
driver.quit()输出结果:
代码示例
性能数据: {"navigationStart":1704067200000,"unloadEventStart":0,...
页面高度: 800px
视口尺寸: {'width': 800, 'height': 600}
链接数量: 1
https://www.iana.org/domains/example六、实际应用场景
-
无限滚动页面处理:对于采用懒加载的无限滚动页面(如微博、小红书),可以通过JS逐步滚动到底部,触发内容加载,直到获取全部数据。
-
隐藏元素操作:某些表单或按钮可能被CSS隐藏(display:none),通过JS修改样式使其可见,然后进行Selenium操作。
-
页面性能监控:获取window.performance.timing数据,监控页面加载速度、DOM渲染时间等性能指标,用于性能测试和回归检测。
小贴士
在处理复杂JS代码时,建议使用三引号"""..."""包裹多行JavaScript代码,提高可读性。同时可以使用return语句将JS计算结果返回给Python。
七、执行方式对比
八、注意事项
⚠️ 注意1:execute_script()中的JS代码在浏览器沙箱中执行,受同源策略限制,无法跨域访问其他页面的数据。
⚠️ 注意2:传递WebElement给JS时使用arguments[0]、arguments[1]等索引引用,不是直接使用变量名。
⚠️ 注意3:execute_async_script()必须在JS代码中调用callback函数(即arguments[arguments.length - 1])表示完成,否则会因超时而抛出TimeoutException。
⚠️ 注意4:JS执行出错时Selenium会抛出JavascriptException,可以使用try-except捕获异常进行处理。
九、练习题
练习1
编写程序,使用execute_script()实现页面平滑滚动效果,从顶部平滑滚动到底部。
练习2
编写程序,使用execute_script()获取页面中所有图片的URL和尺寸信息,并打印输出。
常见问题
execute_script和execute_async_script有什么区别?
execute_script是同步执行,等待JS代码执行完成后立即返回结果,适用于大多数场景。execute_async_script是异步执行,需要在JS中手动调用callback表示完成,适用于需要等待异步操作的场景,如setTimeout、Ajax请求等。
如何在JS代码中引用Python的WebElement?
将WebElement作为execute_script的第二个参数传入,在JS中通过arguments[0]访问。例如:driver.execute_script("arguments[0].click();", element)。多个元素依次使用arguments[1]、arguments[2]等。
execute_async_script的callback函数在哪里?
callback函数自动作为arguments数组的最后一个元素传入。可以通过arguments[arguments.length - 1]获取,通常建议在JS开头定义:var callback = arguments[arguments.length - 1];,然后在异步操作完成后调用callback(result)返回结果。
如何使用JS实现页面平滑滚动?
可以使用window.scrollTo()的behavior选项实现平滑滚动:driver.execute_script("window.scrollTo({top: document.body.scrollHeight, behavior: 'smooth'});")。这需要浏览器支持CSSOM View规范,现代浏览器均支持。
JS执行报错JavascriptException如何调试?
可以先在浏览器开发者工具的Console中直接运行相同的JS代码进行测试,确认语法无误后再放入execute_script中。也可以使用try-except捕获JavascriptException,打印异常信息定位问题。
本文涉及AI创作
内容由AI创作,请仔细甄别