目的:使用selenium执行js修改12306官网的出发日期,修改为2020-12-30,并打印出来
代码块1这段是正确的代码。第一个sleep是必须要加的,否则日期不会被修改。为了不使用sleep,我上网查找了JS的强行等待的方法setTimeout,于是写了代码块2。但是代码块2的执行结果并不正确,页面中的日期没有变成预期结果,打印结果也没有变成预期结果。
问题:代码块2如何修改才能使结果正确?
代码块1—正确的代码
from time import sleep
from selenium import webdriver
class TestExecuteScript:
def setup(self):
self.driver=webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(3)
def teardown(self):
self.driver.quit()
def test_execute_script(self):
self.driver.get("https://www.12306.cn/index/")
self.driver.execute_script("a=document.getElementById('train_date');a.removeAttribute('readonly')")
sleep(2)
self.driver.execute_script("document.getElementById('train_date').value='2020-12-30'")
sleep(2)
print(self.driver.execute_script("return document.getElementById('train_date').value"))
代码块2----修改为JS的setTimeout的不能正确执行的代码
from time import sleep
from selenium import webdriver
class TestExecuteScript:
def setup(self):
self.driver=webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(3)
def teardown(self):
self.driver.quit()
def test_execute_script(self):
self.driver.get("https://www.12306.cn/index/")
self.driver.execute_script("a=document.getElementById('train_date');a.removeAttribute('readonly')")
# sleep(2)
self.driver.execute_script("setTimeout(document.getElementById('train_date').value='2020-12-30',3000)")
sleep(2)
print(self.driver.execute_script("return document.getElementById('train_date').value"))
_AD
(霍格沃兹_AD)
2
为什么要用js的强制等待。用time.sleep足够了啊
理论上这个js语法是OK的,但尝试了确实等待不了,可能selenium执行JavaScript不支持内部嵌套导致的,有时间我再研究一下;如果是要强等的话,AD老师的回复那样就好,你在js强等与在外面的time.sleep()效果是一致的
查了一下,setTimeout要传入的第一个参数应该是一个函数的引用,而不是函数的执行,所以你直接写了执行语句到那一句的时候会直接执行而不会等待,例如:
setTimeout(alert('aaaa'),1000)
# 这句在控制台执行的话,就会直接弹出alert 而不是等待一秒后弹出
setTimeout(function (){alert('aaaa')},1000)
# 而这句在控制台就会等待一秒后弹出,因为用了一个匿名函数定义来包裹,所以setTimeOut获得的参数是函数的引用,这样就能在等待时间后进行执行了
所以你的语句改为
self.driver.execute_script("setTimeout(function (){document.getElementById('train_date').value='2020-12-30'},3000)")
就能够正常的执行了
另外还有一点,因为js的等待是不会影响selenium的执行的,所以这个语句后面的sleep要3秒+ 不然的话上一句还没执行,你的获取信息的js就跑完了肯定拿不到对的值