關于 Selenium 的一些小點

難以想象,來到新崗位上做的事情竟然還可以用老套路去極大地提高效率,甚至在某些層面上,工作方式都是相似的,讓人有種似曾相識的怪異感。尤其是這次,竟然是用腳本抓自己內(nèi)部的網(wǎng)站了……誰讓現(xiàn)有的系統(tǒng)不能自動做這些統(tǒng)計呢,連 SQL 也不暴露出來,手動做實在是太累了。

本文不成體系,說一些零碎的小點。

1. 如何修改只讀控件的內(nèi)容?

網(wǎng)頁邏輯是,選擇日期的文本框,點擊之后由彈出的日期選擇控件來完成日期輸入,禁止用戶修改日期文本框內(nèi)容。于是通過 element.send_keys() 方法發(fā)送字符串時,會提示錯誤,無法修改只讀屬性的內(nèi)容。

查了三四種解決方法,說什么的都有,甚至還有說模擬整個鼠標點擊過程的……

簡單有效的方法是,通過在頁面內(nèi)執(zhí)行 JS 代碼,將控件的只讀屬性取消。使用 webdriverexecute_script() 方法來在當前頁面上執(zhí)行 JS 腳本。核心是網(wǎng)頁對象的 removeAttribute() 方法,指定移除 readonly 屬性,不管他本來是 true 還是 false。具體如何定位到想要取消屬性的對象,有很多種方法,最方便的情況是這個控件有全局唯一的 ID,這樣直接按照 ID 搜索即可。否則的話可能需要從一個可以被唯一確定的父級節(jié)點向下一步步查找。下例將一個 ID 為 targetElement 對象的只讀屬性移除。

# Python Code
from selenium import webdriver

# Settings
URL = "http://www.targetURL.com"
targetXPath = '//*[@id="targetElement"]'

# Browse page
driver = webdriver.Chrome()
driver.get(URL)

# Disable readonly attribute
driver.execute_script("document.getElementById('targetElement').removeAttribute('readonly')")

注意,由于 JS 里是單引號,這里的文本使用雙引號。另外,引號內(nèi)的語句正確性要手動檢查。

這樣取消掉屬性之后就可以正常使用 send_key() 方法了,不過這個操作需要在每次頁面發(fā)生刷新之后都要進行一次,執(zhí)行結(jié)果是不會被緩存的。

2. 無法使用 element.clear() 方法?

有一個情況違反直覺:將控件的只讀屬性取消之后,仍然不能通過 element.clear() 方法清空這個文本框,錯誤提示大概是“無法對只讀控件使用 clear() 方法”,但是實際上可以用 send_keys() 發(fā)送文本啊。

因為我很笨,所以我用的解決方法也很簡單粗暴——把退格符當做按鍵通過 send_keys() 方法直接發(fā)給文本框,向左刪除一個字符。

# Python Code
from selenium.webdriver.common.keys import Keys

...

element = driver.find_element_by_xpath(targetXPath)
element.send_keys(Keys.BACKSPACE)

字符太多怎么辦?——辦!

for i in range(0, 100):
    element.send_keys(Keys.BACKSPACE)

沒辦法,我就會這樣了。或者可以通過 JS 腳本來清空文本框內(nèi)容?一定可以的,但是我不會 JS 啊……目前第一階段,先解決問題是主要的。

3. 如何解決登錄問題?

抓取目標是后臺管理系統(tǒng)的一些統(tǒng)計數(shù)據(jù),需要身份驗證,一直是使用用戶名和密碼登錄的。然后我就很天真地用 Selenium 去自動填寫兩項內(nèi)容,點擊登錄。然后發(fā)現(xiàn)多彈出一個文本框要求輸入驗證碼,看來是程序化登錄被識別出來了。

然后就想著怎么解決這個二維碼,以其復雜程度,開源的 OCR 不大可能有很大成功率識別出來。而登錄系統(tǒng)有最多錯誤次數(shù)限制,不能貿(mào)然反復嘗試。

然后就想著我先登錄一次,然后保存下來 cookie,下次登陸的時候自動取用。試了一下,但因為每次啟動瀏覽器驅(qū)動器,都是一個新進程,老的 cookie 沒法用,還是過不了登錄界面。

網(wǎng)上有文章說,很多工程師會在系統(tǒng)身份驗證中留下后門,在保證安全的同時盡量讓自動化測試更方便。問題在于,雖然我是我司的員工,但沒有相關權限,也不認識搞這個系統(tǒng)的工程師,更有可能即便認識了人家也不希望我這么用。所以到頭來還是得我自己解決這個問題。

咋辦呢?——辦!

那么我就手動登錄然后自動抓數(shù)據(jù)好了。

# Pyhon Code
import time

...

driver.get(URL)
time.sleep(30)

...

打開網(wǎng)頁后,先給我 30 秒時間登錄系統(tǒng),手動輸入用戶名和密碼,然后如果遇到驗證碼的話,再手動輸入一下,點擊登錄。此后等待計時器到時,再自動去扒數(shù)據(jù)。

??!我覺得這個想法實在是太野蠻了,一點都不專業(yè),也不優(yōu)美,但是真能解決問題啊……太山寨了。有機會一定去學習如何用正經(jīng)的辦法去處理這樣的情況,可能需要很多技術,很多技巧,很多工具,需要很多的學習。

大體上就是這樣,我覺得自己雖然很業(yè)余,但是處理這些事情的思路是在是太亮了。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,326評論 25 708
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 15,667評論 4 61
  • 周一:米飯日 運動1小時 周二:輕斷食日 吃兩餐 運動半小時 周三:學習日/土豆日 周四:米飯日 運動一小時 周五...
    Emma_Morley閱讀 274評論 0 0

友情鏈接更多精彩內(nèi)容