selenium+Python(定位 單選、復選框,多層定位)


1、定位一組元素
webdriver 可以很方便的使用 findElement 方法來定位某個特定的對象,不過有時
候我們卻需要定位一組對象,這時候就需要使用 findElements 方法。
定位一組對象一般用於以下場景:

  • 批量操作對象,比如將頁面上所有的 checkbox 都勾上
  • 先獲取一組對象,再在這組對象中過濾出需要具體定位的一些對象。比如定位出頁面上所有的 checkbox,然后選擇最后一個

checkbox.html

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>Checkbox</title>
<script type="text/javascript" async=""
src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link
href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined
.min.css" rel="stylesheet" />
<script
src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></
script>
</head>
<body>
<h3>checkbox</h3>
<div class="well">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="c1">checkbox1</label>
<div class="controls">
<input type="checkbox" id="c1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c2">checkbox2</label>
<div class="controls">
<input type="checkbox" id="c2" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c3">checkbox3</label>
<div class="controls">
<input type="checkbox" id="c3" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio</label>
<div class="controls">
<input type="radio" id="r1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio</label>
<div class="controls">
<input type="radio" id="r2" />
</div>
</div>
</form>
</div>
</body>
</html>

將這段代碼保存復制到記事本中,將保存成 checkbox.html 文件。(注意,這個頁面需要和我們的自動化腳本放在同一個目錄下)

通過瀏覽器打開,得到下列頁面:

1.1 、第一種定位方法

通過瀏覽器打個這個頁面我們看到三個復選框和兩個單選框。下面我們就來定位這三個復選框。

# -*- coding: utf-8 -*-
from selenium import webdriver
import time
import os
dr = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('checkbox.html')
dr.get(file_path)
# 選擇頁面上所有的 input,然后從中過濾出所有的 checkbox 並勾選之
inputs = dr.find_elements_by_tag_name('input')
for input in inputs:
if input.get_attribute('type') == 'checkbox':
input.click()
time.sleep(2)
dr.quit()

注意:因為我們調用的是本地文件, 所以要導入 os 包。

1.2 、第二種定位方法

第二種寫法與第一種寫法差別不大,都是通過一個循環來勾選控件。
# -*- coding: utf-8 -*-
from selenium import webdriver
import time
import os
dr = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('checkbox.html')
dr.get(file_path)
# 選擇所有的 checkbox 並全部勾上
checkboxes = dr.find_elements_by_css_selector('input[type=checkbox]')
for checkbox in checkboxes:
checkbox.click()
time.sleep(2)
# 打印當前頁面上有多少個 checkbox
print len(dr.find_elements_by_css_selector('input[type=checkbox]'))
time.sleep(2)
dr.quit()

1.3 、去掉最后一個勾選

有時候我們並不想勾選頁面的所有的復選框(checkbox),可以通 過下面辦法把最后一個被勾選的框去掉。

可以進行如下修改:

# -*- coding: utf-8 -*-
from selenium import webdriver import time
import os
dr = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('checkbox.html')
dr.get(file_path) # 選擇所有的 checkbox 並全部勾上
checkboxes = dr.find_elements_by_css_selector('input[type=checkbox]')
for checkbox in checkboxes:
checkbox.click()
time.sleep(2)
# 把頁面上最后1個 checkbox 的勾給去掉
dr.find_elements_by_css_selector('input[type=checkbox]').pop().click()
time.sleep(2)
dr.quit() 

其實,去掉勾選表也邏輯也非常簡單,就是再次點擊勾選的按鈕。可能我們比較迷惑的是如何找到“最后一個”按鈕。pop() 可以實現這個功能。

pop()pop(-1):默認獲取一組元素的最后一個

pop(0):默認獲取一組元素的第一個

pop(1):默認獲取一組元素的第二個

。。。

1.4、判斷是否選中:is_selected()

1.有時候這個選項框,本身就是選中狀態,如果我再點擊一下,它就反選了,這可不是我期望的結果,那么可不可以當它是沒選中的時候,我去點擊下;
當它已經是選中狀態,我就不點擊呢?那么問題來了:如何判斷選項框是選中狀態?
2.判斷元素是否選中這一步才是本文的核心內容,點擊選項框對於大家來說沒什么難度。獲取元素是否為選中狀態
3.返回結果為 bool 類型,沒點擊時候返回 False,點擊后返回 True,接下來就很容易判斷了,既可以作為操作前的判斷,也可以作為測試結果的判斷

2、多層框架/ 窗口定位
本節知識點:
多層框架或窗口的定位:

  •   switch_to_frame()
  •   switch_to_window()

對於一個現代的 web 應用,經常會出現框架(frame) 或窗口(window)的應用,這也就給我們的定位帶來了一個難題。有時候我們定位一個元素,定位器沒有問題,但一直定位不了,這時候就要檢查這
個元素是否在一個 frame 中,seelnium webdriver 提供了一個 switch_to_frame 方法,可以很輕松的來解決這個問題。

2.1 、多層框架定位

frame.html

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>frame</title>
<script type="text/javascript"
async=""src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
"></script>
<link
href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstra
p-combined.min.css" rel="stylesheet" />
<script type="text/javascript">$(document).ready(function(){
});
</script>
</head>
<body>
<div class="row-fluid">
<div class="span10 well">
<h3>frame</h3>
<iframe id="f1" src="inner.html" width="800",
height="600"></iframe>
</div>
</div>
</body>
<script
src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.
min.js"></script>
</html>

 

 inner.html

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>inner</title>
</head>
<body>
<div class="row-fluid">
<div class="span6 well">
<h3>inner</h3>
<iframe id="f2" src="http://www.baidu.com"
width="700"height="500"></iframe>
<a href="javascript:alert('watir-webdriver better than
selenium webdriver;')">click</a>
</div>
</div>
</body>
</html>

frame.html 中嵌套 inner.html ,兩個文件和我們的腳本文件放同一個目錄下,通過瀏覽器打開,得到下列頁面:

下面通過 switch_to_frame() 方法來進行定位:

#coding=utf-8
from selenium import webdriver
import time
import os
browser = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('frame.html')
browser.get(file_path)
browser.implicitly_wait(30)
#先找到到 ifrome1(id = f1)
browser.switch_to_frame("f1")
#再找到其下面的 ifrome2(id =f2)
browser.switch_to_frame("f2")
#下面就可以正常的操作元素了
browser.find_element_by_id("kw").send_keys("selenium")
browser.find_element_by_id("su").click()
time.sleep(3)
browser.quit()

2.2 、多層窗口定位

(詳細例子可以參考后面的,多窗口切換
有可能嵌套的不是框架,而是窗口,還有真對窗口的方法:switch_to_window用法與 switch_to_frame 相同:
driver.switch_to_window("windowName")

2.3、層級定位

假如兩個控件,他們長的一模樣,還都叫“張三”,唯一的不同是一個在北京,一個在上海,那我們就可以通過,他們的城市,區,街道,來找到他們。
在實際的測試中也經常會遇到這種問題:頁面上有很多個屬性基本相同的元素,現在需要具體定位到其中的一個。由於屬性基本相當,所以在定位的時候會有些麻煩,這
時候就需要用到層級定位。先定位父元素,然后再通過父元素定位子孫元素。
level_locate.html

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>Level Locate</title>
<script type="text/javascript" async=""
src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></scri
pt>
<link
href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-c
ombined.min.css" rel="stylesheet" />
</head>
<body>
<h3>Level locate</h3>
<div class="span3">
<div class="well">
<div class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown"
href="#">Link1</a>
<ul class="dropdown-menu" role="menu"
aria-labelledby="dLabel" id="dropdown1" >
<li><a tabindex="-1" href="#">Action</a></li>
<li><a tabindex="-1" href="#">Another action</a></li>
<li><a tabindex="-1" href="#">Something else here</a></li>
<li class="divider"></li>
<li><a tabindex="-1" href="#">Separated link</a></li>
</ul>
</div>
</div>
</div>
<div class="span3">
<div class="well">
<div class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown"
href="#">Link2</a>
<ul class="dropdown-menu" role="menu"
aria-labelledby="dLabel" >
<li><a tabindex="-1" href="#">Action</a></li>
<li><a tabindex="-1" href="#">Another action</a></li>
<li><a tabindex="-1" href="#">Something else here</a></li>
<li class="divider"></li>
<li><a tabindex="-1" href="#">Separated link</a></li>
</ul>
</div>
</div>
</div>
</body>
<script
src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min
.js"></script>
</html>

上面的 html 代碼比較亂,請復制到編輯器中查看,如 nodepad ++ 編輯器。

(注意,這個頁面需要和我們的自動化腳本放在同一個目錄下)通過瀏覽器打開:
定位思路:
具體思路是:先點擊顯示出1個下拉菜單,然后再定位到該下拉菜單所在的 ul,再定位這個 ul 下的某個具體的 link。在這里,我們定位第1個下拉菜單中的 Action 這個選項。
腳本如下:

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import time
import os
dr = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('level_locate.html')
dr.get(file_path)
#點擊 Link1鏈接(彈出下拉列表)
dr.find_element_by_link_text('Link1').click()
#找到 id 為 dropdown1的父元素
WebDriverWait(dr, 10).until(lambda the_driver:
the_driver.find_element_by_id('dropdown1').is_displayed())
#在父親元件下找到 link 為 Action 的子元素
menu = dr.find_element_by_id('dropdown1').find_element_by_link_text('Action')
#鼠標定位到子元素上
webdriver.ActionChains(dr).move_to_element(menu).perform()
time.sleep(2)
dr.quit()

WebDriverWait(dr, 10)

10秒內每隔500毫秒掃描1次頁面變化,當出現指定的元素后結束。
is_displayed() :該元素是否用戶可以見
driver: 執行用戶操作實例 webdriver
class ActionChains(driver):生成用戶的行為。所有的行動都存儲在 actionchains 對象。通過 perform()存儲的行為。
move_to_element(menu):移動鼠標到一個元素中,menu 上面已經定義了他所指向的哪一個元素
to_element:元件移動到
perform():執行所有存儲的行為


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM