1. 程式人生 > >Python selenium巧用Javascript指令碼注入解決按鈕點選問題

Python selenium巧用Javascript指令碼注入解決按鈕點選問題

  前段時間,筆者忙於應付公司組織的雅思考試,白天、晚上但凡有空,筆者都是埋頭伏案,啃劍橋雅思(劍4~劍12)的官方模擬題或者做著與雅思考試相關的準備工作,這個過程持續了40余天。最近總算鼓起勇氣走進考場,跟那些尚未畢業、懷揣出國夢想的小年輕同場競爭,雖然結果還未出來,但是至少短時間不用再高強度複習英語了,筆者工作重心得以迴歸到Python +Selenium的自動化中。

  言歸正傳,筆者這次準備利用JavaScript來修改頁面節點的屬性,方便selenium傳參。具體案例是這樣的:

下圖所示的頁面中需要輸入日期:

  這是一個Bootstrap框架生成的模態窗,“開始時間”和“結束時間

”對應的input按鈕,它的html文字:<input value="" name="startDateSel" type="text" class="form-control" readonly="readonly">,這個readonly屬性決定了,使用者無法直接輸入日期引數(網站考慮的是:使用者輸入的日期格式不規範,導致無法檢索,故以這種方式控制輸入),需要通過滑鼠點選年月日來生成最後的日期。

 

具體操作見下圖筆者錄製的GIF動畫:

如果出現“年、月、日”都要選擇非預設值,則點選的操作略複雜,其易用性極端情況下不如手輸;

當然,python+selenium完全可以操作這些“年、月、日、確定按鈕”頁面元素,比如,“月份”的html標籤程式碼長這樣:

<td colspan="7">
    <span class="month"></span>
    <span class="month"></span>
    <span class="month"></span>
    <span class="month"></span>
    <span class="month"></span>
    <span class="month"></span>
    <
span class="month"></span> <span class="month active"></span> <span class="month"></span> <span class="month"></span> <span class="month">十一</span> <span class="month">十二</span> </td>

 年份的程式碼長這樣:

<td colspan="7">
    <span class="year old">2009</span>
    <span class="year">2010</span>
    <span class="year">2011</span>
    <span class="year">2012</span>
    <span class="year">2013</span>
    <span class="year">2014</span>
    <span class="year">2015</span>
    <span class="year">2016</span>
    <span class="year">2017</span>
    <span class="year active">2018</span>
    <span class="year">2019</span>
    <span class="year old">2020</span>
</td>

  不過,通過selenium模擬滑鼠實現“點點點”,步驟略繁瑣,執行效率低。筆者建議通過js修改html表情的readonly屬性為false,達到input元素可編輯的狀態。通過網頁F12進入開發者模式,在控制檯中編寫JS指令碼,通過querySelectorAll方法遍歷input元素,刪除特定節點屬性(attribute)方法如下:

var rs = document.querySelectorAll("input[readonly='readonly']");
for(var i = 0; i < rs.length; i++)
    {
        rs[i].readOnly = false;
    }

這段程式碼想要在python selenium中執行很簡單,只用把這段js腳本當成字串載入就可以了,唯一需要注意的是,上面的js指令碼中已經有了單引號、雙引號,所以,必須使用三引號"""  """模式將這段文字括起來,具體程式碼如下:

js="""var rs = document.querySelectorAll("input[readonly='readonly']");for(var i = 0; i < rs.length; i++){rs[i].readOnly = false;}"""
driver.execute_script(js)

執行完程式碼後,可以看到游標可以正常在input框內閃爍,可以手動寫入日期:

後面可以通過js的方法直接對input元素賦值,也可以先定位元素,然後用經典的send_keys()方法,根據實際情況任選一種方法即可,非常方便!

driver.find_element_by_name("startDateSel").send_keys("2018-09-01")
driver.find_element_by_name("endDateSel").send_keys("2018-11-09")
driver.find_element_by_css_selector("button.btn.btn-primary").click()  #點選確定