01:什么是Xpath
Xpath是一門xml文檔中查找信息的語言,Xpath可用來在xml文檔中對元素和屬性進行遍歷,主流的瀏覽器都支持xpath,因為HTML頁面在DOM中表示xhtml文檔
xpath和css選擇器最重要的區別是Xpath可以向前和向后查詢DOM結構的元素,而css選擇器只能向前查詢,這意味着Xpath可以通過子元素來定位父元素
02:網上關於Xpath的教程比較少,可以看一下菜鳥教程和w3cshool的相關資料:
http://www.runoob.com/xpath/xpath-tutorial.html、http://www.w3school.com.cn/xpath/index.asp
03:下列列出了最有用的路徑表達式
表達式 描述 | |
nodename | 選取此節點所有子節點 |
/ | 從根節點選取 |
// | 從匹配選擇當前節點選擇文檔的節點,而不考慮它們的位置 |
. | 選取當前節點 |
.. | 選取當前節點的父節點 |
@ | 選取屬性 |
路徑表達式 | 結果 |
/bookstor/book[1] | 選取屬於bookstore子元素的第一個book元素 |
/bookstore/book[last()] | 選取屬於bookstore子元素的最后一個book元素 |
/bookstore/book[last()-1] | 選取屬於bookstore子元素的倒數第二個book元素 |
/bookstore/book[position()<3] | 選取最前面的兩個bookstore元素的子元素的book元素 |
//title[@lang] | 選取所有擁有名為lang的屬性為title元素 |
//title[@lang='eng'] | 選取所有title元素,且這些元素有值為eng的lang屬性 |
/bookstore/book[price>35] | 選取bookstore元素所有book元素,且其中的price元素的值須大於35 |
/bookstore/book[price>35]/title | 選取bookstore元素的book元素所有的title,且其中的price元素的值須大於35 |
xpath未知節點
* 匹配任何元素節點
@*匹配任何屬性節點
node()匹配任何類型的節點
04:xpath定位元素的幾種方式
1)絕對路徑
從DOM結構樹的開始一直寫到你需要定位的那個節點
2)相對路徑
eg:‘//span’
其中‘//’標識忽略前面的所有節點,直接定位當前節點(例子中的當前節點為:span)
3)切片引索定位:
eg:‘//span[0]’==or=='//span[-1]'
相對路徑獲取的節點往往不僅僅只存在一個,可能返回的是多個節點,使用下標【0】進行切片引索可以過濾部分節點或直接定位所需節點;
這里為什么用過濾這個詞,請自己實踐”://div[12]和//div
4)使用節點屬性索引定位
eg:‘//*[@name='name]’
*標識匹配任何元素節點,@標識選取屬性;name=‘name’表示選取節點屬性name的值為name的節點屬性
5)使用節點謂語引索定位
eg://*[text()=5使用節點謂語引索定位:]
text()是Xpath謂語之一,也是應用場景多的謂語之一,其表示選取節點text字段為:使用節點謂語引索定位的節點屬性
6)利用Xpath邏輯運算符進行定位節點
eg1://*div[@name='name' **and** @size='4' **and** @multiple='multiple']
and運算符組合節點屬性進行索引匹配,定位節點
eg2://*div[@type='displayed'** or ** @type='hidden']
or 運算符組合刷選多變節點進行匹配索引
(例子1利用三個節點屬性並存的條件進行精確定位節點,在xpath運算符中,會以Hash計算方式分成三次進行定位節點,可以說非常快的;
例子2中通常的應用場景是對某一按鈕的定位,通過選中和非選中兩種狀態定位同一節點,這樣可以省一些事)
7)運用xpath軸的節點集進行反向定位
eg:.//*[class='define']//ancestor::div
這個就是css做不到的地方;反向定位:定位class屬性value為define的節點他的所有長輩節點通過: ancestor::控制;並篩選出節點標簽為div所有的符合條件的節點
軸名稱 對應情況
ancestor 選取當前節點的所有先輩(父、祖父等)
ancestor-or-self 選取當前節點的所有先輩(父、祖父等)以及當前節點本身
attribute 選取當前節點的所有屬性
child 選取當前節點的所有子元素
descendant 選取當前節點的所有后代元素(子、孫等)
descendant-or-self 選取當前節點的所有后代元素(子、孫等)以及當前節點本身
following 選取文檔中當前節點的結束標簽之后的所有節點
namespace 選取當前節點的所有命名空間節點
parent 選取當前節點的父節點
preceding 選取文檔中當前節點的開始標簽之前的所有節點
preceding-sibling 選取當前節點之前的所有同級節點
self 選取當前節點
05:xpath使用思路
1)節點元素無Id,無唯一的name;請使用xpath
eg:
<link rel="preload" href="https://addasdasdator.js?domain=www.wqwrqqe1231l.com.cn" as="script">
//link[@rel='preload' and @as='script']
請注意這里不要使用//*開頭;請使用.//或//
*是匹配任何節點元素的屬性/謂語的意思,這么說吧,其實//*是==//[@*]==一種簡寫
2)節點元素需要集合或者包含多種可能性,請使用xpath
eg:需求-請定位一次性定位含字段的節點元素
<div class="show-pollution">
<span class="show-airParm polution-level-0">
<em class="show-polution-name">優</em>
<em class="show-polution-num">28</em>
</span><span class="show-vertical">|</span>
</div>
<div class="unknown-city">
<span class="unknown-icon"></span>
<span class="unknown-text">查看天氣信息,</span>
<span class="unknown-setting">設置城市</span>
</div> </div>
//*[@class='show-pollution' or class='unknown-city']//descendant::text()
3)節點元素是表格內部元素,使用xpath
<table class="dataintable">
<tbody>
<tr>
<th style="width:25%;">表達式</th>
<th>描述</th>
</tr>
<tr>
<td>nodename</td>
<td>選取此節點的所有子節點。</td>
</tr>
<tr>
<td>/</td>
<td>從根節點選取。</td>
</tr>
<tr>
<td>//</td>
<td>從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置。</td>
</tr>
<tr>
<td>.</td>
<td>選取當前節點。</td>
</tr>
<tr>
<td>..</td>
<td>選取當前節點的父節點。</td>
</tr>
<tr>
<td>@</td>
<td>選取屬性。</td>
</tr>
</tbody>
</table>
當節點元素謂語表單結構之內,使用xpath可以一次性定位所有節點,通過語句設置篩選條件達到獲取表格中的任意節點元素,方便后期維護;此處有遇到表單結構過於大的那種可以考慮使用迭代器和生成器結合使用,從而減小內存消耗
4)節點元素是非常規屬性,請使用xpath
<div>
<h2>定位下面的"span"標簽所代表的節點元素</h2>
<p>定位下面的"span"標簽所代表的節點元素</p>
<span><?xml version="1.0" encoding="ISO-8859-1"?><bookstore><book><titlelang="eng">HarryPotter</title><price>29.99</price></book><book><titlelang="eng">LearningXML</title><price>39.95</price></book></bookstore>
</span>
</div>
//*[text()="定位下面的"span"標簽所代表的節點元素"]//parent::*/pre