Selenium(九):Xpath選擇器

1. Xpath選擇器

1.1 Xpath語法簡介

前面咱們學習了CSS選擇元素。css

你們能夠發現很是靈活、強大。html

還有一種靈活、強大的選擇元素的方式,就是使用Xpath表達式。web

XPath (XML Path Language) 是由國際標準化組織W3C指定的,用來在XML和HTML文檔中選擇節點的語言。chrome

目前主流瀏覽器 (chrome、firefox,edge,safari) 都支持XPath語法,xpath有1和2兩個版本,目前瀏覽器支持的是xpath 1的語法。api

既然已經有了CSS,爲何還要學習Xpath呢?由於瀏覽器

有些場景用 css選擇web元素很麻煩,而xpath卻比較方便。框架

另外Xpath還有其餘領域會使用到,好比爬蟲框架Scrapy,手機App框架Appium。學習

html代碼:spa

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h3 style="color: brown">select框</h3>

        <h4 style="color: rgb(22, 118, 173)">單選</h4>

        <p>姓名:</p>
        <select class="single_choice" >
            <option value="小江老師">小江老師</option>
            <option value="小雷老師">小雷老師</option>
            <option value="小凱老師" selected="selected">小凱老師</option>
        </select>

        <hr>

        <h4 style="color: rgb(22, 118, 173)">多選</h4>
        <p>課程:</p>
        <select  class="multi_choice" multiple>
              <option value="小江老師">小江老師</option>
              <option value="小雷老師">小雷老師</option>
              <option value="小王老師">小王老師</option>
              <option value="小凱老師" selected="selected">小凱老師</option>
        </select> 

        <hr>

        <div>

            <p style="color: brown; font-weight: bold;">
            城市選擇    
            </p>

            <div id="china">
        
                <p id="beijing" class='capital huge-city'>
                    北京    
                </p>
                <p id="shanghai" class='huge-city'>
                    上海    
                </p>       
            </div>

            <div id="us">
                <span id="west" style="color:darkgreen">
                    <p id="newyork">
                    紐約   
                    </p>
                    <p id="huston">
                        休斯頓    
                    </p>     
                </span>
                <span id="east" style="color:darkred">
                    <p id="chigaco">
                        芝加哥   
                    </p>
                </span>
            </div>
        </div>
    </body>
</html>

按F12打開調試窗口,點擊 Elements標籤。firefox

要驗證Xpath語法是否能成功選擇元素,也能夠像驗證CSS語法那樣,按組合鍵Ctrl + F ,就會出現搜索框。

xpath語法中,整個HTML文檔根節點用‘/’表示,若是咱們想選擇的是根節點下面的html節點,則能夠在搜索框輸入。 

/html

若是輸入下面的表達式:

/html/body/div

這個表達式表示選擇html下面的body下面的div元素。

注意/有點像CSS中的> , 表示直接子節點關係。

1.1.1 絕對路徑選擇

從根節點開始的,到某個節點,每層都依次寫下來,每層之間用/分隔的表達式,就是某元素的絕對路徑。

上面的xpath表達式/html/body/div,就是一個絕對路徑的xpath表達式, 等價於 css表達式html > body > div。

自動化程序要使用Xpath來選擇web元素,應該調用WebDriver對象的方法find_element_by_xpath或者find_elements_by_xpath,像這樣:

elements = driver.find_elements_by_xpath("/html/body/div")

1.1.2 相對路徑選擇

有的時候,咱們須要選擇網頁中某個元素,無論它在什麼位置。

好比,選擇示例頁面的全部標籤名爲div的元素,若是使用css表達式,直接寫一個div就好了。

那xpath怎麼實現一樣的功能呢? xpath須要前面加//,表示從當前節點往下小趙全部的後代元素,無論它在上面位置。

因此xpath表達式,應該這樣寫://div。

’//’ 符號也能夠繼續加在後面,好比,要選擇全部的div元素裏面的全部的p元素,無論div在什麼位置,也無論p元素在div下面的什麼位置,則能夠這樣寫//div//p

對應的自動化程序以下:

elements = driver.find_elements_by_xpath("//div//p")

若是使用CSS選擇器,對應代碼以下:

elements = driver.find_elements_by_css_selector("div p")

若是,要選擇全部的div元素裏面的直接子節點p,xpath,就應該這樣寫了//div/p

若是使用CSS選擇器,則爲div > p>。

1.1.3 通配符

若是要選擇全部div節點的全部直接子節點,可使用表達式//div/*。

* 是一個通配符,對應任意節點名的元素,等價於CSS選擇器div > *。

代碼以下:

elements = driver.find_elements_by_xpath("//div/*")
for element in elements:
    print(element.get_attribute('outerHTML'))

1.2 根據元素選擇

Xpath能夠根據屬性來選擇元素。

根據屬性來選擇元素是經過這種格式來的[@屬性名='屬性值']

注意:

 

屬性名注意前面有個@

 

屬性值必定要用引號, 能夠是單引號,也能夠是雙引號

1.2.1 根據id屬性選擇

選擇id爲west的元素,能夠這樣//*[id='west'] 。

1.2.2 根據class屬性選擇

選擇全部 select 元素中 class爲 single_choice 的元素,能夠這樣//select[@class='single_choice']。

若是一個元素class 有多個,好比:

<p id="beijing" class='capital huge-city'>
    北京    
</p>

若是要選它,對應的xpath就應該是//p[@class="capital huge-city"]。

不能只寫一個屬性,像這樣//p[@class="capital"]則不行。

1.2.3 根據其餘屬性

一樣的道理,咱們也能夠利用其它的屬性選擇。

好比選擇具備multiple屬性的全部頁面元素,能夠這樣//*[@multiple]。

1.2.4 屬性值包含字符串

要選擇style屬性值包含color字符串的頁面元素,能夠這樣//*[@contains(@style,'color')]。

要選擇style屬性值以color字符串開頭的頁面元素,能夠這樣//*[@starts-with(@style,'color')]

要選擇style屬性值以某個字符串結尾的頁面元素,你們能夠推測是//*[@ends-with(@style,'color')], 可是,很遺憾,這是xpath 2.0的語法,目前瀏覽器都不支持。

1.3 按次序選擇

前面學過css表達式能夠根據元素在父節點中的次序選擇,很是實用。

xpath也能夠根據次序選擇元素。語法比css更簡潔,直接在方括號中使用數字表示次序。

1.3.1 某類型第幾個子元素

要選擇p類型第2個的子元素,就是

//p[2]

注意,選擇的是p類型第2個的子元素,不是第2個子元素,而且是p類型。

還有,要選擇父元素的div中的p類型第2個子元素。

//div/p[2]

1.3.2 第幾個子元素

也能夠選擇第2個子元素,無論是什麼類型,採用通配符。

好比選擇父元素爲div的第2個子元素,無論是什麼類型。

//div/*[2]

1.3.3 某類型倒數第幾個子元素

固然也能夠選取倒數第幾個子元素

例如:

選取p類型倒數第1個子元素

//p[last()]

選取p類型倒數第2個子元素

//p[last()-1]

選擇父元素爲div中p類型倒數第二個子元素

//div/p[last()-2]

1.3.4 範圍選擇

xpath還能夠選擇子元素的次序範圍。

例如:

選取option類型第1到2個子元素

//option[position()<=2]

或者

//option[position()<3]

選擇class屬性爲multi_choice的前3個子元素

//*[@class='multi_choice']/*[position()<=3]

選擇class屬性爲multi_choice的後3個子元素

//*[@class='multi_choice']/*[position()>=last()-2]

爲何不是last()-3呢?由於 

last() 自己表明最後一個元素

last()-1 自己表明倒數第2個元素

last()-2 自己表明倒數第3個元素

1.4 組選擇、父節點、兄弟節點

1.4.1 組選擇

css有組選擇,能夠同時使用多個表達式,多個表達式選擇的結果都是要選擇的元素。

css 組選擇,表達式之間用逗號隔開。

xpath也有組選擇,是用豎線隔開多個表達式。

好比,要選全部的option元素和全部的h4元素,可使用

//option | //h4

等同於CSS選擇器

option , h4

好比,要選全部的class爲single_choice和class爲multi_choice的元素,可使用

//*[@class='single_choice'] | //*[@class='multi_choice']

等同於CSS選擇器

.single_choice , .multi_choice

1.4.2 選擇父節點

xpath能夠選擇父節點,這是css作不到的。

某個元素的父節點用/..表示

好比,要選擇id爲china的節點的父節點,能夠這樣寫//*[@id='china']/..。

當某個元素沒有特徵能夠直接選擇,可是它的子節點有特徵,就能夠採用這種方法,先選擇子節點,在指定父節點。

還能夠繼續找上層父節點,好比//*[@id='china']/../../..。

1.4.3 兄弟節點選擇

前面學過css選擇器,要選擇某個節點的後續兄弟節點,用波浪線。

xpath也能夠選擇後續兄弟節點,用這樣的語法forllowing-sibling::。

好比,要選擇class爲single_choice的元素的全部後續兄弟節點//*[@class='single_choice']/forllowing-sibling::*。

等同於CSS選擇器.single_choice ~ *

若是,要選擇後續節點中的div節點,就應該這樣寫//*[@class='single_choice']/forllowing-sibling::div。

xpath還能夠選擇前面的兄弟節點,用這樣的語法preceding-sibling::。

好比,要選擇class爲single_choice的元素的全部後續兄弟節點//*[@class='single_choice']/preceding-sibling::*。

而CSS選擇器目前尚未選擇前面的兄弟節點。

要了解更多Xpath選擇語法,能夠這裏,打開Xpath選擇器參考手冊

1.5 selenium注意點

咱們來看一個例子

咱們的代碼:

 先選擇示例網頁中,id是china的元素。

 

而後經過這個元素的WebElement對象,使用find_elements_by_xpath,選擇裏面的p元素。

# 先尋找id是china的元素
china = wd.find_element_by_id('china')

# 再選擇該元素內部的p元素
elements = china.find_elements_by_xpath('//p')

# 打印結果
for element in elements:
    print('----------------')
    print(element.get_attribute('outerHTML'))

運行發現,打印的 不單單是china內部的p元素,而是全部的p元素。

要在某個元素內部使用xpath選擇元素,須要在xpath表達式最前面加個點。

像這樣

 

elements = china.find_elements_by_xpath('.//p')
相關文章
相關標籤/搜索