在爬蟲採集數據的過程當中,如何定位及匹配數據是必須解決的一項任務。最經常使用的定位方式有三種: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 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。