Python selenium中添加JS并执行JS语句

Posted NewJune

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python selenium中添加JS并执行JS语句相关的知识,希望对你有一定的参考价值。

  众所周知,Python通常结合selenium模块来完成一些web的自动化测试以及RPA(Robotic Process Automation)工作。事实上,Selenium还可以支持插入js语句、执行js语句、返回js语句的执行结果到python程序中。这对于那些已经习惯了Javascript语法的程序员们,简直是一大神器。

  举个简单的例子,我们用selenium原生的方法对页面的一个input元素执行输入时,通常需要用到selenium中的send_keys以及clear方法,

 

代码类似于:

driver.find_element_by_xpath(\'//*[@id="dataList"]//input\').clear()
driver.find_element_by_xpath(\'//*[@id="dataList"]//input\').send_keys("Your contents")

  该方法大多数时候已经足够好用,但是仔细分析,send_keys方法主要是模拟的用户键盘操作,程序执行时必须要保证该元素始终获取焦点,页面执行过程中尽量不能动页面,否则send_keys方法可能会失效。而且我们每次send_keys之前需要对input元素已有的text进行清空,即初始化。笔者推荐使用JS注入selenium的方法来达到更好的效果,在selenium中写JS语句往往是如下形式:

js="document.getElementsByClassName(\'form-control\')[0].value=\'%s\';"%(requestCode[i][0].value)
driver.execute_script(js)

  该方法,相当于是直接调用页面元素的value方法来进行赋值,不用考虑变量初始化问题,它属于网页后台功能,类似于F12直接在console中执行代码,不需要光标停留在该input元素上。

使用JS后,我们就可以使用诸如document.getElementsByClassName、QuerySelector、QuerySelectorAll等JS方法定位元素,玩儿法大大丰富;

近日,笔者在一个具体的项目中,需要提取页面某表格的某一列值,该表格虽然最多支持100行来分页,但是用户可视区域只能显示15行。笔者需要提取该列的每一个值做后续判断。开始的方法是用的原生的selenium写法:

elements=driver.find_elements_by_xpath("//tr[contains(@id,\'datagrid-row-r1-1\')]") 
for element1 in elements:
    textList1=element1.text
    value2=re.search(r"(H\\d{13})",textList1)
    slaStatus=re.search(r"(aa|bb|cc)",textList1)
    statusList.append(slaStatus.group(1)) 
    value2List.append(value2.group(1))    

奇怪的事情发生了,该elements对象是一个列表,尽管它超过15个元素,但是每次遍历过程中,始终只能读取到前15个元素的text属性,之后的element元素,其text始终为空。笔者过程中换用了正则表达式、cssSelector、xpath等多种方法来提取该属性,总是只能提取到前15个元素的text属性。但是笔者将鼠标悬停在elements中,可以看到VSCode已经捕获到了所有对应元素的text,百思不得其解:

最后,笔者使用JS注入的方法完美避开了此问题,达到同样效果。

js=r"""
var ss="";
for(var i= 1; i< document.querySelectorAll(\'[field="x"]\').length; i ++)
{
ss=ss+document.querySelectorAll(\'[field="x"]\')[i].innerText;
ss=ss.replace(/[\\r\\n]/g,"")+"|";
};
return ss;
"""
value2
=driver.execute_script(js)
value2List=value2.split("|")

  该方法中,笔者使用document.querySelectorAll方法获取到field属性="x"的所有元素的合集,遍历过程中,取其innerText并最终借助“|”拼接成字符串。最后在python环境下通过字符串的split方法基于“|”拆分成列表,相当于编码再解码。笔者之所以这样操作是因为,如果js语句执行结果返回的是一个数组,该数组如何与python中的列表直接对接?

无论如何,使用JS的方法完美地提取到了页面元素的属性,达到同样的效果。程序员尤其是新手,在编程过程中难免遇到这样那样的问题。但是一旦你掌握了足够多的方法,就总能在不断尝试过程中接近想要的答案!

 

以上是关于Python selenium中添加JS并执行JS语句的主要内容,如果未能解决你的问题,请参考以下文章

12 Python+selenium对日期控件进行处理(采用执行JS脚本)

python和selenium怎么判断进度条

python使用selenium执行JS快速完成超长字符串的输入

python selenium --调用js

selenium python 针对js生成的下拉列表,如何选择隐藏的选项

python+selenium十一:jQuery和js语法js处理iframe