Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
一節,我們介紹一下頁面元素定位的八種方式和如何通過火狐和谷歌瀏覽器獲取元素定位信息.
html頁面是有一個個的標簽組成的,我們定位元素其實就是定位這些標簽。
首先來看一下有哪兒幾種定位方式:
id
name
class name
tag name
link text
partial link text
xpath
css selector
一共八種定位方式,其實常用的定位方式也有:xpath、css selector,至少要熟練掌握一種......
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_id("wd1").send_keys("python")
id定位
代碼的意思就是定位id為:“wd1”的輸入框并輸入了“python”這個數據
<input id="wd1" class="search_ipt search_inp_border j_search_input tb_header_search_input" name="kw1" value="" autocomplete="off" size="42" tabindex="1" maxlength="100" x-webkit-grammar="builtin:search" x-webkit-speech="true" type="text">
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_name("kw1").send_keys("python")
我們通過觀察這個<input>標簽的屬性,通過name也可以成功定位這個元素
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_class_name("search_ipt.search_inp_border.j_search_input.tb_header_search_input").send_keys("python")
結果我們發現系統報錯了,由于這個輸入框的class中有四個class,
所以當我們同點來分割時,報錯:Unable to locate element:;當我們用空格分割時,報錯: Compound class names not permitted
而當我們用其中一個class時,比如:search_ipt
這時我們才可以成功的定位元素(一般不建議用這個class name來定位)
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_tag_name("input").send_keys("python")
我們直接定位這個元素的標簽名,可以成功定位,但是由于實際中tag name有很多相同的標簽,可能會在運行時定位不準確,所以不建議使用這個
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_link_text("地圖").click()
然后我們通過鏈接的名字找到元素,并進行click()點擊操作,進入到了地圖頁
第6種:Partial link text定位
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_partial_link_text("地").click()
同樣的,我們通過鏈接的部分文字信息來定位到這個元素,依舊可以成功定位
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_xpath(".//*[@id='wd1']").send_keys("python")
xpath定位
xpath是比較常用的定位,由于定位比較準確,一般是百發百中,但是缺點是絕對路徑的xpath根據元素標簽的相對位置來定位,如果頁面的UI元素有所改動,結構路徑變化的話,也會導致我們無法定位元素,不過這是針對我們用firepath自動獲取時的定位,我們完全可以根據層級關系和元素屬性自己來寫xpath路徑,這樣的話,即使其他路徑結構變化,對于xpath定位的準確度還有一定的保障
比如:
1.我們把xpath的父級路徑添加上
//form/input[@id='wd1']
2.我們還可以對所查找元素標簽里的屬性進行組合
//form/input[@id='wd1' and @name='kw1']
3.我們對文本進行匹配
driver.find_element_by_xpath("//*[contains(text(),'網頁')]").click()
可以看出xpath簡直是神器啊,有沒有,可以通過標簽的各種屬性來定位,等于說是包含了class name、name、id、link_text這些定位的方法。
from selenium import webdriver
driver=webdriver.Chrome()
driver.get("https://tieba.baidu.com/")
driver.find_element_by_css_selector("#wd1").send_keys("python")
通過css selector 定位
其實這個css selector定位的強悍和xpath不相上下,也非常之強大,比如在css selector里:
我用class來定位:driver.find_element_by_css_selector(".search_ipt")
用id來定位:driver.find_element_by_css_selector("#wd1")
用標簽名來定位(tag name):driver.find_element_by_css_selector("input")
用父子關系來定位:driver.find_element_by_css_selector("form>input")
用標簽和屬性來定位:driver.find_element_by_css_selector("input[id='wd1']")
以及綜合上邊的超級組合查詢:driver.find_element_by_css_selector("form.clearfix>input[id='wd1']") #代表著class為clearfix的父級標簽和自己id屬性為wd1的input標簽.
這些就是定位元素的方法,很常用也非常重要,值得收藏!
ebDriver API提供了內置方法來查找基于不同屬性的WebElement,例如ID,Name,Class,XPath,CSS Selectors,鏈接Text等。下面我們就針對這些方法進行元素查找定位。
打開Chrome瀏覽器,按F12出現開發者工具選項,選擇Elements,優先選擇Chrome的原因就是因為瀏覽器比較好用。
1. 鼠標點擊下圖彈框中左上角的箭頭,再點擊頁面上要定位的元素
2. 對應的html頁面上會顯示對應的數據,并顯示灰色背景
3. 按Ctrl+F顯示出來搜索框,此處手寫元素標簽定位
如果你手寫元素技能還有待提高的話,可以使用輔助工具來幫助你,Chrome有一個神器插件,可代替你手寫元素的困擾
ChpoPath插件下載地址:
https://pan.baidu.com/s/1FCoSQHC1YdBBpETF71Ldfw ; 99tk
ID定位
driver.find_element_by_id("kw").send_keys('你好')
NAME定位
driver.find_element_by_name("wd").send_keys('name')
CLASS_NAME定位
driver.find_element_by_class_name("s_ipt").send_keys('class_name')
TAG_NAME定位
這個是行不通的,因為重復的標簽太多了,無法定位準確
from selenium import webdriver
from selenium.webdriver.common.by import By
driver=webdriver.Chrome()
driver.get('https://www.baidu.com/')
try:
driver.find_element_by_tag_name("input").send_keys('tag——name')
print('找到了')
except Exception as e:
print(f'么找到{e}')
我們使用tag_name定位,加了異常捕獲,運行結果如下:
F:\virtualEnvironment\venv\Scripts\python.exe F:/git/AuomationTest/AuomationTestProject/webTestAuomation/element_localization.py
么找到Message: element not interactable
(Session info: chrome=89.0.4389.72)
Process finished with exit code 0
實踐檢驗了使用tag_name來定位是不靠譜的。
文本定位,link_text只針對含a標簽的,不含a標簽的使用,會拋錯。
driver.find_element_by_link_text("新聞").click()
部分文本定位,partial_link_text也是只針對含a標簽的使用,元素的部分文本內容定位,不含a標簽的使用,會拋錯
driver.find_element_by_partial_link_text("吃喝").click()
萬能元素定位,也就是xpath和css定位,css定位后的代碼運行起來的速度相對來說比xpath代碼運行起來要快很多。
XPATH用法:
driver.find_element_by_xpath("xpath表達式")
xpath表達式有絕對路徑和相對路徑,通常我們都是使用相對路徑
1. 絕對路徑:/html/body/div[3]/div[1]/div[1]/div[1]/ul/li[9]/a
2. 相對路徑://*[text()="吃喝玩樂"]
我們不推薦絕對路徑,因為前端代碼稍微更改就會影響到定位,推薦使用相對路徑
xpath 基本語法 | 注釋信息 |
/ | 絕對定位,如果是選擇當前p標簽下的子級的話,可以使用 |
// | 相對定位,當前p標簽下的所有節點,不考慮它們的位置 |
@ | 選取屬性,//*[@id="xxx"],//*[@class="xxx"] |
* | 通配符,匹配所有 //* |
@* | 通配符,匹配所有屬性 //input[@*="xxx"] |
//a[@class="header-title"]
//ul[@class="api-main"][1]/li/a[@class="list-con"]
盡量能不使用下標就不要使用下標定位,前端稍微修改代碼也會影響頗大
//ul[@class="api-main"]/li/a[contains(@class, "list-con")]
當然模糊定位還有一些表達式:
//*[contains(text(), 文本元素屬性)] | 獲取含文本信息的元素 |
//*[contains(@id, 元素屬性)] | id也可以是class、name |
//*[starts-with(@id, 元素屬性)] | 匹配什么開頭 |
//*[ends-with(@id, 元素屬性)] | 匹配什么結尾 |
//*[matchs(text(), 文本元素屬性)] | 正則匹配含文本的元素 |
//*[text()="吃喝玩樂"]
//ul[@class="api-main"]//*[@class="list-con" and text()="金融科技"]
//ul[@class="api-main"]//*[text()="交通地理"]/parent::li//following-sibling::li//a
CSS用法:
driver.find_element_by_css_selector("css表達式")
.api-main-list
#password-o
[class="api-main"]
[id="s-top-left"]>[target="_blank"]
a[href^="https"]
a[href$="com"]
a[href*="baidu"]
[target~="_blank"]
.api-main:first-child:父級元素下第一個元素
.api-main:last-child:父級元素下最后一個元素
.api-main:only-child:父級元素下唯一一個子元素
.api-main:nth-child(下標):父級元素下第幾個元素
關于css的元素定位,后面實操后再給補上,以上總結或許能幫助到你,或許幫助不到你,但還是希望能幫助到你,如有疑問、歧義,評論區留言會及時修正發布,謝謝
未完,待續...
一直都在努力,希望您也是!
.id定位
HTML規定id屬性在HTML文檔中必須是唯一的。
如:
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
find_element_by_id("kw")
2.name定位
HTML規定name屬性指定元素名稱,在當前頁面可以不唯一。
如:
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
find_element_by_name("wd")
3.class定位
HTML規定class指定元素類名。
如:
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
find_element_by_class_name("s_ipt")
4.tag定位
HTML本質是通過tag來定義實現不同的功能,每個元素本質是一個tag。因tag用來定義一類功能,所以通過tag識別某個元素概率很低。
find_element_by_tag_name("input")
find_element_by_tag_name("div")
find_element_by_tag_name("a")
5.link定位
專門用來定位文本鏈接。如:
find_element_by_link_text("新聞")
find_element_by_link_text("hao123")
find_element_by_link_text("地圖")
6.partial link定位
是對link定位的補充,有些鏈接很長,我們可以通過這個定位取文本鏈接的一部分。
如:
<a class="aaa" name="bbb" href="#">你好啊,我有一條很長名稱的文本鏈接</a>
find_element_by_partial_link_text("你好啊")
find_element_by_partial_link_text("很長名稱")
find_element_by_partial_link_text("文本鏈接")
7.XPath定位
XPath是一種在XML文檔中定位元素的語言。HTML可看作XML的一種實現。
7.1絕對路徑定位
黏貼:/html/body/div[1]/div[2]/div[5]/div[1]/div/form/span[1]/input
find_element_by_xpath("/html/body/div[1]/div[2]/div[5]/div[1]/div/form/span[1]/input")
7.2元素屬性定位
如:
<input type="text" class="s_ipt" name="wd" id="kw" maxlength="100" autocomplete="off">
find_element_by_xpath("//input[@id='kw']")
//表示當前頁面某個目錄下
input表示定位元素的標簽名
[@id='kw']表示這個元素的id屬性值等于kw
---還可以通過name和class屬性來定位,其他任意屬性都可以使用。
find_element_by_xpath("//input[@name='wd']")
find_element_by_xpath("//input[@class='s_ipt']")
find_element_by_xpath("//*[@name='wd']")
注:不想指定標簽名,可以用*號代替。
7.3層級與屬性結合定位
如果一個元素沒有唯一標識的屬性值,可以找上一級元素可以唯一標識的屬性值使用。
假設輸入框沒有唯一標識的屬性值,我們可以查找它上一級屬性。
find_element_by_xpath("//span[@id='s_kw_wrap']/input")
find_element_by_xpath("//span[@class='bg s_ipt_wr new-pmd quickdelete-wrap']/input")
或者再往上級找:
find_element_by_xpath("//form[@id='form']/span/input")
或者找第二個span的input(百度一下按鈕):
find_element_by_xpath("//form[@id='form']/span[2]/input")
7.4使用邏輯運算符
......
<input id="kw" class="su" name="ie">
<input id="kw" class="aa" name="ie">
<input id="bb" class="su" name="ie">
........
如上代碼通過id或class屬性去定位元素都會存在重復。
如果一個屬性不能唯一區分一個元素,我們可以使用邏輯運算符“and”來連接兩個條件去定位元素。
find_element_by_xpath("//input[@id='kw' and class='su']/span/input")
8.CSS定位
CSS(Cascading Style Sheets)是一種語言,用來描述HTML和XML文檔的表現。CSS使用選擇器來為頁面元素綁定屬性。
8.1通過class屬性定位
.號表示通過class屬性來定位元素
find_element_by_css_selector(".s_ipt")
*請認真填寫需求信息,我們會在24小時內與您取得聯系。