巧妙利用selenium中的JS操作来处理特殊的文本框
在使用selenium对页面进行相关操作时,有时候会遇到以下三种情况:
1.日期框:无法直接输入文本,必须要选择某一天的日期并点击才会填入文本框;
2.检索框:可以直接输入文本,但必须要点击根据输入的文本检索出来的下拉列表的某一项;
3.置灰的文本框:无法直接输入文本
按照常规套路,我们通常都会采取各种元素定位方法按照操作步骤一步一步来实现,但是遇到上面三种奇葩,页面定位操作就显得有些捉襟见肘了,因此我们可以通过selenium中的javascript操作来处理它。
我们以12306铁路官网的查票系统来演示,先看看出发地文本框,这个就是典型的检索框,根据下面两张图的对比,当我们在出发地通过输入检索信息选择了“上海”之后,第一个input标签的value由空值变更为“SHH”(代表上海),第二个input标签的“class”由input变更为“input inp-txt_select”(虽然最终不需要通过js去改变这个值也能达到效果),另外第二个input标签的value改变了隐藏属性,由“简拼/全拼/汉字”变更为了“上海”,通过js可以获取到。
我们先来通过F12的Console来获取并改变它的文本框的值,具体步骤见下图:
通过js操作,我们知道它的初始值为空
当我们把第一个标签的value的值改变为“SHH”,第二个标签的value的值改变为“上海”时,文本框自动变更为“上海”,到达地检索框的操作方法一致。
针对日期框,跟上面的检索框处理方法略有差别,先看看日期框的页面元素属性
我们已经注意到它有两个关键属性value和readonly,通过js发现,readonly的属性值为true,表示禁止输入,那么我们可以直接通过修改readonly的值为false来达到我们的目的
置灰输入框操作方法跟上面大同小异,这里就不依依演示了,在selenium中,driver对象有一个方法可以专门操作js,这个方法名为:execute_script(),源代码如下:
使用方法通过以下代码来示例:
‘‘‘ 使用js完成12306的查票操作 ‘‘‘ from datetime import datetime from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.12306.cn/index/") # 打开12306官网 start_area_js = ‘‘‘ var a = document.getElementById("fromStation"); a.value = ‘NJH‘; ‘‘‘ driver.execute_script(start_area_js) start_input_js = ‘‘‘ var j = document.getElementById(‘fromStationText‘); j.className = ‘input inp-txt_select‘; j.value = ‘南京‘; ‘‘‘ driver.execute_script(start_input_js) # 修改到达地 end_area_js = ‘‘‘ var b = document.getElementById("toStation"); b.value = ‘SHH‘; ‘‘‘ driver.execute_script(end_area_js) end_input_js = ‘‘‘ var k = document.getElementById(‘toStationText‘); k.className = ‘input inp-txt_select‘; k.value = ‘上海‘; ‘‘‘ driver.execute_script(end_input_js) # 修改出发日期,利用f表达式使用datetime.now()动态获取当天日期(格式:年-月-日) # 方法一 # 通过操作js语句document下的getElementById()方法传入id值 train_date_js = f‘‘‘ var c = document.getElementById(‘train_date‘); c.readOnly = false; c.value = ‘{datetime.strftime(datetime.now(), "%Y-%m-%d")}‘ ‘‘‘ driver.execute_script(train_date_js) # 方法二 # 通过创建WebElement对象传入arguments中,方括号里面的索引值+1跟execute_script()里的参数索引保持对应 ele = driver.find_element_by_xpath("//input[@id=‘train_date‘]") train_date_js = f‘‘‘ var c = arguments[0]; c.readOnly = false; c.value = ‘{datetime.strftime(datetime.now(), "%Y-%m-%d")}‘ ‘‘‘ driver.execute_script(train_date_js, ele) # 点击查询 select_button_ele = driver.find_element_by_xpath( "//input[@id=‘train_date‘]/ancestor::div[@class=‘form-item‘]/following-sibling::div//a[contains(text(),‘查‘)]") select_button_js = ‘‘‘ var d = arguments[0]; d.click(); ‘‘‘ driver.execute_script(select_button_js, select_button_ele)