?系列導(dǎo)讀
1. 為什么需要 JS
前面 3 篇文章講了 Selenium 的一些基本操作,利用這部分技能,大部分網(wǎng)站的自動(dòng)化都能順利完成逻悠。
但是,也有一些網(wǎng)站的網(wǎng)頁(yè)操作沒法利用 WebDriver API 來(lái)完成讯蒲,也有一些功能即使利用 WebDriver API 實(shí)現(xiàn)了,兼容性也不強(qiáng)乾翔,經(jīng)常需要去維護(hù)這套腳本爱葵,比如:瀏覽器的位置滑動(dòng)、元素點(diǎn)擊失效反浓、選擇日期等萌丈。
這時(shí)候,利用 JavaScript 直接操作網(wǎng)頁(yè)內(nèi)部元素雷则,能夠輔助我們完成 Selenium 自動(dòng)化測(cè)試中不能覆蓋的功能辆雾。
2. 怎么使用
Selenium 提供了下面這個(gè)方法:
driver.execute_script(js_code)
其中 js_code 是一段 JS 腳本,常見的 JS 腳本包含:設(shè)置元素屬性月劈、移除屬性度迂、設(shè)置元素值、設(shè)置窗口位置等
和 Selenium CSS Selector 類型猜揪,利用 JS 查找元素的方式包含下面這 6 種:
# 1惭墓、通過元素id屬性,獲取元素
document.getElementById('id');
# 2而姐、通過元素name屬性腊凶,獲取元素
document.getElementsByName('name');
# 3、通過標(biāo)簽名拴念,獲取元素列表
# 獲取的是一個(gè)列表
document.getElementsByTagName('tag_name');
# 4钧萍、通過類名,獲取元素列表
document.getElementsByClassName("class_name");
# 5政鼠、通過選擇器风瘦,獲取一個(gè)元素
document.querySelector("css selector")
# 6、通過CSS選擇器公般,獲取元素列表
document.querySelectorAll("css selector")
拿到元素之后万搔,就可以操作元素屬性了,比如:
?# 操作屬性值
# 設(shè)置元素某一個(gè)元素值
element.setAttribute('屬性名','屬性值')
# 設(shè)置元素值
element.value="element_value";
# 刪除屬性
element.removeAttribute('屬性名')
組合上面的 3 個(gè)操作官帘,即可以通過 JS 改變一個(gè)網(wǎng)頁(yè)元素的值了瞬雹。
# 待執(zhí)行的js語(yǔ)句
exec_js = 'document.getElementById(element_id).value="element_value";'
# 執(zhí)行js語(yǔ)句改變?cè)氐闹?driver.execute_script(exec_js)
3. 常見操作
以打開 12306 網(wǎng)站,選擇一個(gè)出發(fā)日期為例遏佣。
首先,利用常規(guī)模式編寫一波自動(dòng)化揽浙,利用 WebDriver 找到元素状婶,然后直接給元素設(shè)置一個(gè)日期值意敛。
運(yùn)行后會(huì)直接報(bào)錯(cuò),運(yùn)行日志會(huì)提示目標(biāo)元素存在一個(gè)不可以編輯的屬性 - readonly
這時(shí)候通過 JS 方法可以很方便地去掉這個(gè)屬性膛虫,然后再加上對(duì)元素的屬性操作草姻,就能正常的設(shè)置日期。
改寫后的代碼如下:
from time import sleep
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.12306.cn/index/')
# 去除掉元素的屬性
exec_js = 'document.getElementById("train_date").removeAttribute("readonly");'
driver.execute_script(exec_js)
# 輸入日期
element_train_date = driver.find_element_by_id("train_date")
element_train_date.clear()
element_train_date.send_keys("2012-12-12")
sleep(5)
driver.quit()
當(dāng)然稍刀,除了去掉元素屬性外撩独,也可以先利用 JS 查找元素的語(yǔ)法獲取目標(biāo)元素,然后直接對(duì)元素設(shè)置一個(gè)日期账月,也能滿足我們的需求综膀。
# 找到元素,直接設(shè)置一個(gè)容器
exec_js = 'document.getElementById("train_date").value="2012-12-12";'
# 執(zhí)行js代碼
driver.execute_script(exec_js)
4. 其他
Selenium 自動(dòng)化的很多操作都能轉(zhuǎn)換為 JS 語(yǔ)句局齿,然后利用 execute_script() 也能完成相同的功能剧劝。
但是,實(shí)際使用自動(dòng)化的過程中抓歼,JS 只是作為一個(gè)補(bǔ)充讥此,協(xié)助我們完成一些 WebDriver 沒法實(shí)現(xiàn)的功能。
更多自動(dòng)化相關(guān)的干貨可以關(guān)注微信公眾號(hào)【 Python 自動(dòng)化社區(qū) 】來(lái)解鎖谣妻。