• Python selenium中注入并执行Javascript语句


      众所周知,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"(Hd{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(/[ ]/g,"")+"|";
    };
    return ss;
    """
    value2
    =driver.execute_script(js)
    value2List=value2.split("|")

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

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

  • 相关阅读:
    Linux Shell常用技巧(一)
    使用Native API 创建进程
    Windows操作系统下创建进程的过程
    Windows操作系统下创建进程的过程
    windows运行打开服务命令
    windows运行打开服务命令
    出错提示:“Could not flush the DNS Resolver Cache: 执行期间,函数出了问题”的解决方法
    出错提示:“Could not flush the DNS Resolver Cache: 执行期间,函数出了问题”的解决方法
    对XP上的KiFastSystemCall进行浅析
    对XP上的KiFastSystemCall进行浅析
  • 原文地址:https://www.cnblogs.com/new-june/p/9665364.html
Copyright © 2020-2023  润新知