如何手寫xpath

江湖人稱007發表於2020-08-10

如何手寫xpath

  • 場景

通常情況下, 我們可以瀏覽器自帶的定位方式, Firefox的F12, Chrome的開發者工具, 找到元素右鍵copy-copy xpath即可。

  • 基本語法

XPath 使用路徑表示式在 XML 文件中選取節點。節點是透過沿著路徑或者 step 來選取的。 下面列出了最有用的路徑表示式:

在下面的表格中,我們已列出了一些路徑表示式以及表示式的結果:

  • 定位方式

絕對路徑定位(直接copy瀏覽器xpath)

使用絕對路徑的方式定位除非是其父級元素都沒有一個唯一識別的元素才使用該方式;假如要定位到輸入框,那麼使用絕對路徑的方式為:

xpath= /html/body/div/div/div/div/div/form/span/input

就是從根部開始找,一級一級往下走,如果有同級別的需要用[]標明序號,從1開

透過屬性查詢
  • xapth = //*[@id="wrap"]
  • xpath = //input[@id="wrap]
  • xpath = //input[@type="text"]
  • xpth = //input[@name="zs"]

//input表示要匹配所有的元素,//*表示匹配所有元素的標籤

注意:要保證這些元素可以是唯一的標識

組合定位

如果input標籤中 id不是唯一的,type也不是唯一的,但在該頁面中包含該id和type的只有這個元素時,那麼我們可以用組合的方式定位

  • xpath = //input[@id="wrap and @name="zs"]
找父級屬性

如果自己沒有唯一的標誌,那麼就找自己的上級(父級),或者上級的上級,以此類推。

  • 找父級:xpath=//span[@class="s_ipt_wr"]/input
  • 找父級的父級:xpath=//form[@id="form"]/span[1]/input
跳級

如果需要定位的元素在該頁面不是唯一,但在某個容器內是唯一的,當然那個容器必須要有唯一的標誌; 跳級的話要用兩個//

謂語(Predicates)

謂語用來查詢某個特定的節點或者包含某個指定的值的節點。

其他
  • contains: xpath =//input[contains(@id,"w")], 表示選擇id中包含"w"的input節點
  • text(): xpath= //a[text()="地圖"]. 由於一個節點的文字值不屬於屬性, ,所以,用text()函式來匹配節點
  • 特殊情況列舉

1.列表有id屬性

接著複製列表的xpath會有問題,需要個別分析,如下:

分析:可以看到列表li上面有id屬性,所有就不能直接寫xpath=//*[@id="line_u8_0"],需要找他的父級,可以有兩種寫法

  • xpath=/html/body/div[4]/div[2]/div[2]/ul "找到父級ul的xpath"
  • xpath=//*[@class="linsdd"]//li "手寫xpath,透過找他父級的唯一標識,這裡注意跳級了所以用的是//"
2.列表有其他無關元素參入

其他無關的元素也在其中不好取,附上地址可以練習一下。這裡需要用到 position用來查詢某個特定的節點或者包含某個指定的值的節點。如下:

分析:這裡需要擷取中間一部分,按這個頁面舉例,可以看到是重第三條table開始,到倒數3條table結束,才是真正的列表。要確保xpath精準,只有列表。

  • xpath=/html/body/table[position()>3 and position()<last()-3]
last() 選擇最後一個,也就是倒數第一個
last()-1 選擇倒數第二個
last()-2 選擇倒數第三個
...依次類推
3.無法定位到正確列表,需要透過屬性尋找

毫無規律,也找不到對應的class,id等等,分析發現這裡看到他們的父級有valign屬性,變並且有無關元入參入,這裡需要用[@valign="top"]定位到元素,在配合擷取,就完美解決了。

  • xpath=//td[@valign="top"]/table[position()>1 and position()<last()-2]//tr