XPATH、CSS選擇器及正則表達式

在爬蟲採集數據的過程當中,如何定位及匹配數據是必須解決的一項任務。最經常使用的定位方式有三種:XPATH,CSS選擇器及正則表達式。如下咱們來系統的學習他們。css

1、XPATH 語法html

參考文檔:XPATH教程 from runoobnode

1. Xpath是什麼正則表達式

XPath是一個W3C標準,能夠供XSLT、XPointer以及其餘XML解析軟件使用;它包含一個標準函數庫;使用路徑表達式在XML文檔中進行導航。在爬蟲學習中,咱們最須要了解的就是最後一項:如何使用XPath路徑表達式進行導航。在此以前,首先讓咱們學習下XPath的基本概念之一:節點。緩存

2. XPath節點及相關函數

XPath中有七種類型的節點:元素,屬性,文本,命名空間,處理指令,註釋以及文檔(根)節點。除了節點以外,還有基本值(Atomic value)的概念。學習

基本值:無父或無子的節點。從定義上看,基本值是一種特殊節點,常見於文本。spa

項目(Item):基本值或者節點。.net

XML是被做爲文檔樹來對待的,也所以會涉及根節點、父子節點等概念,下面讓咱們總結下節點關係。ssr

3. XPath節點關係

父(Parent): 每一個元素或屬性都有一個父,即其直接上級節點。

子(Children):元素節點能夠有0、1或多個子,即其直接下級節點。

兄弟(Sibling):擁有相同的父的節點或節點集合。

先輩(Ancestor):某節點的父,父的父,以此類推十八代(虛指)。

後代(Descendant):某節點的子,子的子,以此類推。

瞭解了基本概念,接下來是語法。

4. XPath語法

4.1 節點選取

nodename 選取當前節點的全部nodename子節點;

/ 從根節點選取,即絕對路徑;

// 從當前節點選取,即相對路徑;

. 選取當前節點;

.. 選取當前節點的父節點;

@ 選取屬性。

4.2 謂語(Predicates)

結合實例解釋以下:

/bookstore/book[1] 選取bookstore子元素的第一個book元素;

/bookstore/book[last()] 選取bookstore子元素的最後一個book元素;

/bookstore/book[position()<3] 選取bookstore元素的前兩個book元素;

*以前提到XPath中包含一個標準函數庫;last()和position()就是其中常見的例子。

//title[@lang] 選取擁有lang屬性的title元素;

//title[@lang='eng'] 選取lang屬性爲'eng'的title元素;

/bookstore/book[price>35.00] 選取bookstore元素中的全部book元素,且其中的price元素大於35.00。

4.3 通配符

* 匹配任何元素節點; @*匹配任何屬性節點;node()匹配任何類型的節點。

4.4 路徑組合

//book/title | //book/price 選取book元素的全部title和price元素。

以前咱們介紹了節點關係的概念,那麼如何利用節點關係來定位節點呢,請看XPath軸。

5. XPath軸(Axes)

ancestor 選取當前節點的全部先輩;

ancestor-or-self 選取當前節點及其全部先輩;

descendant 選取當前節點的全部後輩;

descendant-or-self 選取當前節點及其全部後輩;

parent 選取當前節點的父節點;

child 選取當前節點的子節點;

following 選取當前節點以後的全部節點;

following-sibling 選取當前節點以後的全部兄弟節點;

preceding 選取當前節點以前的全部節點;

preceding-sibling 選取當前節點以前的全部兄弟節點;

self 選取當前節點;

attribute 選取當前節點全部屬性;

namespace 選取當前節點的全部命名空間節點。

用法,好比要查找<a>元素以後的<span>元素,使用'//a/following::span'。

6. XPath運算符

| 計算兩個節點集;

+ - * div mod加減乘除求餘;

= != < <= > >= 比較;

or and 或與。

2、CSS選擇器語法

參考資料:CSS選擇器 from w3school

在定位元素時,CSS選擇器和XPath常常能夠相互替代。經常使用的CSS選擇器以下:

.class 根據class屬性選擇元素;

#id 根據id屬性選擇元素;

* 選擇全部元素;

element 選擇全部element元素;

element,element1 選擇全部element及element1元素;

element element1 選擇element內部的全部element1元素;

element>element1 選擇element的element1子元素;

element+element1 選擇緊接在element以後的element1元素;

[attribute] 選擇帶有attribute屬性的全部元素;

[attribute=value] 選擇attribute屬性值爲value的全部元素;

[attribute~=value] 選擇attribute屬性值包含value的全部元素;

[attribute|=value] 選擇attribute屬性值以value開頭的全部元素;

a:link 選擇全部未被訪問的連接;a:visited 選擇全部已被訪問連接;a:hover 選擇活動連接;

element:focus 選擇得到焦點的element元素;

element:first-letter 選擇element元素首字母;element:first-line 選擇element元素首行;

element:first-child 選擇屬於element父元素的第一個子元素的每一個element元素;

element:lang(language) 選擇帶有以language開頭的lang屬性值得每一個element元素;

ele1~ele2 選擇前面有ele1元素的每一個ele2元素;

ele[attribute^=value] 選擇attribute屬性值以value開頭的每一個ele元素;

ele[attribute$=value] 選擇attribute屬性值以value結尾的每一個ele元素;

ele[attribute*=value] 選擇attribute屬性值包含value的每一個ele元素;

ele:first-of-type 選擇屬於其父元素的首個ele元素的每一個ele元素;

ele:last-of-type 選擇屬於其父元素的最後ele元素的每一個ele元素;

ele:only-of-type 選擇屬於其父元素惟一的ele元素的每一個ele元素;

ele:only-child 選擇屬於其父元素的惟一子元素的每一個ele元素;

ele:nth-child(n) 選擇屬於其父元素的第n個子元素的每一個ele元素;

ele:nth-last-child(n) 選擇屬於其父元素的倒數第n個子元素的每一個ele元素;

ele:nth-of-type(n) 選擇屬於其父元素的第n個元素的每一個ele元素;

ele:nth-last-of-type(n) 選擇屬於其父元素的倒數第n個元素的每一個ele元素;

ele:last-child 選擇屬於其父元素最後一個子元素的每一個ele元素;

:root 選擇文檔根元素;

ele:empty 選擇沒有子元素的每一個ele元素;

ele:target 選擇當前活動的ele元素;

ele:enabled 選擇每一個啓用的ele元素;ele:disabled 選擇每一個禁用的ele元素;

ele:checked 選擇每一個被選中的ele元素;

:not(selector) 選擇非selector的每一個元素;

::selection 選擇被用戶選取的元素部分。

3、正則表達式語法

參考教程:正則表達式 from runoob

當咱們使用word或text之類的辦公軟件時,常常用到搜索和篩選來定位查找詞語。這個功能很便利,可是它的不足之處也很明顯。其中之一就是:做爲過濾器的模式很是有限。相比之下,正則表達式能夠實現前者的全部工做,並且更增強大和靈活。下面讓我來看看,它是如何作到這一點的。

1. 正則表達式記號

普通字符 大小寫字母,全部數字,全部標點和一些其餘字符(如非打印字符)。

非打印字符 

\cx 匹配由x指明的控制字符;x的值必須爲A-Za-z之一;不然c將被視爲字母c;

\f 匹配換頁符;\n 匹配換行符;\r 匹配回車符; \s 匹配任何空白字符,包括空格、製表符、換頁符等;\S 匹配任何非空白字符;\t 匹配任何製表符;\v 匹配垂直製表符。

特殊字符

^ 匹配開始位置,在方括號中時,表示否認,即不接受該字符集合;$ 匹配結尾位置;

* 匹配前面的子表達式0或屢次; + 匹配前面的子表達式1或屢次;

? 匹配前面的子表達式0或1次,或指定一個非貪婪限定符;

. 匹配除換行符\n以外的任何單字符;

\ 轉義字符;

| 指明兩項之間的其中一個。

() 標記一個子表達式的開始和結束位置。子表達式能夠得到,供之後使用;

[] 標記一箇中括號表達式的開始;

{ } 標記限定符表達式的開始;

限定符

* + ? 見特殊字符

{n} 匹配肯定的n次;{n,} 至少匹配n次;{n,m} 匹配n到m次。

定位符

^ $ 見特殊字符

\b 匹配字邊界(字與空格間的位置);\B 非字符邊界

子表達式

前面提到,()能夠標記一個子表達式,且該表達式能夠被捕獲緩存。若是這並非你想要的,那麼可使用?:消除這種反作用,即將子表達式標記爲非捕獲元。

除此以外,還有另外兩個很重要的非捕獲元?=和?!,前者稱爲正向預查,後者稱爲反向預查。二者還常常被稱爲零寬斷言(正向、反向);此外還有逆序正向預查和逆序反向預查。

正向預查(?=exp) a. 當單詞同時知足前部匹配條件和exp時,返回前部匹配; b. exp非捕獲

舉例: \b\w+(?=ing\b)  輸入 singing and dancing 輸出 sing和danc

反向預查(?!exp) a. 當單詞知足前部匹配條件且不知足exp時,返回前部匹配,b. exp非捕獲

逆序正向預查(?<=exp) a. 當單詞同時知足exp和後部匹配條件時,返回後部匹配;b. exp非捕獲;

逆序反向預查(?<!exp) a. 當單詞不知足exp且知足後部匹配條件時,返回後部匹配;b. exp非捕獲;

*名字很拗口,能夠這麼理解:正向、反向指的是要匹配的字符是在前面仍是後面;正序、逆序指的是確定仍是否認子表達式。

引用

每一個被捕獲的子表達式都會存儲在緩衝區,且被編號爲1-99。每一個緩衝區能夠經過\n來訪問,其中n爲標識特定緩衝區的一位或兩位十進制數。最簡單,最有用的應用爲查找文本中兩個相同的相鄰單詞。

2. 元字符

\ ^ $ * + ? {n} {n,} {n,m} (pattern) (?:pattern) (?=pattern) (?!pattern) x|y [xyz] [^xyz] [a-z] [^a-z]

\b \B \cx \f \n \r \s \S \t \v

以上這些已經介紹過了,下面再看些經常使用的元字符。

\d 匹配一個數字字符,即[0-9];\D 匹配一個非數字字符;

\w 匹配包括下劃線的任何單詞字符,即[A-Za-z0-9];

\W 匹配任何非單詞字符;

\xn 匹配n,其中n爲十六進制,必須爲肯定的兩個數字;

\num 若是前面至少num個被捕獲子表達式,則表示引用;不然,若是num爲0-7的數字,則匹配八進制;

\un 匹配n,其中n是四個十六進制數字表示的字符。

瞭解了這麼多的符號和運算,很容易想到一個問題,這些運算符的優先級是怎麼樣的?

3. 運算符優先級

優先級從高到低爲:

\ 轉義符;

(),[] 子表達式和中括號表達式;

*,+,?,{} 限定符;

^,$,\任何元字符,任何字符 定位點和普通字符;

| 選擇。

做者:han0710 連接:https://www.jianshu.com/p/9b7eed50e653 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

相關文章
相關標籤/搜索