1. 程式人生 > >Python selenium中添加JS並執行JS語句

Python selenium中添加JS並執行JS語句

sselect all css sta col http 形式 屬性 tor

  眾所周知,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語句