html
XPath即爲XML路徑語言(XML Path Language),它是一種用來肯定XML文檔中某部分位置的語言。用於在 XML 文檔中經過元素和屬性進行導航。node
XPath基於XML的樹狀結構,提供在數據結構樹中找尋節點的能力。起初XPath的提出的初衷是將其做爲一個通用的、介於XPointer與XSL間的語法模型。可是XPath很快的被開發者採用來看成小型查詢語言。python
在 XPath 中,有七種類型的節點:元素、屬性、文本、命名空間、處理指令、註釋以及文檔(根)節點。XML 文檔是被做爲節點樹來對待的。樹的根被稱爲文檔節點或者根節點。數據結構
每一個元素以及屬性都有一個父。python爬蟲
在下面的例子中,book 元素是 title、author、year 以及 price 元素的父:ide
<book> <title>Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book>
元素節點可有零個、一個或多個子。測試
在下面的例子中,title、author、year 以及 price 元素都是 book 元素的子:this
<book> <title>Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book>
擁有相同的父的節點url
在下面的例子中,title、author、year 以及 price 元素都是同胞:spa
<book> <title>Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book>
某節點的父、父的父,等等。
在下面的例子中,title 元素的先輩是 book 元素和 bookstore 元素:
<bookstore> <book> <title>Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> </bookstore>
某個節點的子,子的子,等等。
在下面的例子中,bookstore 的後代是 book、title、author、year 以及 price 元素:
<bookstore> <book> <title>Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> </bookstore>
選取節點 XPath 使用路徑表達式在 XML 文檔中選取節點。節點是經過沿着路徑或者 step 來選取的。
下面列出了最有用的路徑表達式:
表達式 | 描述 |
---|---|
nodename | 選取此節點的全部子節點 |
/ | 從根節點選取 |
// | 從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置 |
. | 選取當前節點。 |
.. | 選取當前節點的父節點。 |
@ | 選取屬性。 |
實例:
路徑表達式 | 結果 |
---|---|
bookstore | 選取 bookstore 元素的全部子節點。 |
/bookstore | 選取根元素 bookstore。註釋:假如路徑起始於正斜槓( / ),則此路徑始終表明到某元素的絕對路徑! |
bookstore/book | 選取屬於 bookstore 的子元素的全部 book 元素。 |
//book | 選取全部 book 子元素,而無論它們在文檔中的位置。 |
bookstore//book | 選擇屬於 bookstore 元素的後代的全部 book 元素,而無論它們位於 bookstore 之下的什麼位置。 |
//@lang | 選取名爲 lang 的全部屬性。 |
謂語用來查找某個特定的節點或者包含某個指定的值的節點。
謂語被嵌在方括號中。
在下面的表格中,咱們列出了帶有謂語的一些路徑表達式,以及表達式的結果:
路徑表達式 | 結果 |
---|---|
/bookstore/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.00] | 選取 bookstore 元素的全部 book 元素,且其中的 price 元素的值須大於 35.00。 |
/bookstore/book[price>35.00]/title | 選取 bookstore 元素中的 book 元素的全部 title 元素,且其中的 price 元素的值須大於 35.00。 |
XPath 通配符可用來選取未知的 XML 元素。
通配符 | 描述 |
---|---|
* | 匹配任何元素節點。 |
@* | 匹配任何屬性節點。 |
node() | 匹配任何類型的節點。 |
在下面的表格中,咱們列出了一些路徑表達式,以及這些表達式的結果:
路徑表達式 | 結果 |
---|---|
/bookstore/* | 選取 bookstore 元素的全部子元素。 |
//* | 選取文檔中的全部元素。 |
//title[@*] | 選取全部帶有屬性的 title 元素。 |
經過在路徑表達式中使用「|」運算符,您能夠選取若干個路徑。
在下面的表格中,咱們列出了一些路徑表達式,以及這些表達式的結果:
路徑表達式 | 結果 |
---|---|
//book/title | //book/price | 選取 book 元素的全部 title 和 price 元素。 |
//title | //price | 選取文檔中的全部 title 和 price 元素。 |
/bookstore/book/title | //price | 選取屬於 bookstore 元素的 book 元素的全部 title 元素,以及文檔中全部的 price 元素。 |
環境安裝: pip install lxml
解析原理:
實例化一個etree類型的對象,且將即將被解析的頁面源碼數據加載到該對象中
調用該對象的xpath方法結合着不一樣的xpath表達式進行標籤訂位和數據提取
實例化對象: etree.parse(fileName) etree.HTML(page_text)
使用方法:xpath返回的必定是一個列表
表達式最左側/和//區別
非最左側的/和//區別
屬性定位://div[@class="name"]
索引定位://div[2]
/text()和//text()
div/a/@href
<html lang="en"> <head> <meta charset="UTF-8" /> <title>測試bs4</title> </head> <body> <div> <p>百里守約</p> </div> <div class="song"> <p>李清照</p> <p>王安石</p> <p>蘇軾</p> <p>柳宗元</p> <a href="http://www.song.com/" title="趙匡胤" target="_self"> <span>this is span</span> 宋朝是最強大的王朝,不是軍隊的強大,而是經濟很強大,國民都頗有錢</a> <a href="" class="du">總爲浮雲能蔽日,長安不見令人愁</a> <img src="http://www.baidu.com/meinv.jpg" alt="" /> </div> <div class="tang"> <ul> <li><a href="http://www.baidu.com" title="qing">清明時節雨紛紛,路上行人慾斷魂,借問酒家何處有,牧童遙指杏花村</a></li> <li><a href="http://www.163.com" title="qin">秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山</a></li> <li><a href="http://www.126.com" alt="qi">岐王宅裏尋常見,崔九堂前幾度聞,正是江南好風景,落花時節又逢君</a></li> <li><a href="http://www.sina.com" class="du">杜甫</a></li> <li><a href="http://www.dudu.com" class="du">杜牧</a></li> <li><b>杜小月</b></li> <li><i>度蜜月</i></li> <li><a href="http://www.haha.com" id="feng">鳳凰臺上鳳凰遊,鳳去臺空江自流,吳宮花草埋幽徑,晉代衣冠成古丘</a></li> </ul> </div> </body> </html>
實例化一個tree對象
from lxml import etree tree = etree.parse("test.html")
1.基於標籤訂位的xpath表達式
xpath方法返回值永遠是一個列表
xpath表達式中最左側的/和//的區別
/表示咱們必須從根標籤進行定位
//表示咱們能夠定義任意位置的標籤
tree.xpath("/html/head/meta") # [<Element meta at 0x1bd33576f08>] tree.xpath("//meta") # [<Element meta at 0x1bd33576f08>]
查找到多個
tree.xpath("//div")
輸出
[<Element div at 0x1bd3223c048>, <Element div at 0x1bd33584148>, <Element div at 0x1bd33584ac8>]
2.屬性定位
tree.xpath("//div[@class='song']") # [<Element div at 0x1bd33584148>]
3.索引定位
索引值是從1開始
在xpath表達式中非最左側的/和//的區別
/表示一個層級
//表示多個層級
tree.xpath("//div[@class='tang']/ul/li[3]") # [<Element li at 0x1bd335849c8>] tree.xpath("//div[@class='tang']//li[3]")
4.取文本
/text():獲取的是標籤下直系的文本數據
//text():獲取的標籤下全部的文本數據
tree.xpath("//div[@class='tang']//li[5]/a/text()") # ['杜牧']
獲取多個文本
string_list = tree.xpath("//div[@class='tang']//text()") "".join(string_list).replace("\n","").replace("\t","") # '清明時節雨紛紛,路上行人慾斷魂,借問酒家何處有,牧童遙指杏花村秦時明月漢時關,萬里長征人未還,但使龍城飛將在,不教胡馬度陰山岐王宅裏尋常見,崔九堂前幾度聞,正是江南好風景,落花時節又逢君杜甫杜牧杜小月度蜜月鳳凰臺上鳳凰遊,鳳去臺空江自流,吳宮花草埋幽徑,晉代衣冠成古丘'
5.取屬性
獲取的也是一個列表
tree.xpath("//div[@class='tang']//li[5]/a/@href") # ['http://www.dudu.com']
url = "https://www.zhipin.com/job_detail/?query=python爬蟲&page=%d" f = open("boss.txt","w",encoding="utf-8") for page in range(1,2): new_url = format(url%page) page_text = requests.get(url=new_url,headers=headers).text # xpath的數據解析 tree = etree.HTML(page_text) # tree中存儲的是整張頁面中對應的頁面源代碼 li_list = tree.xpath("//div[@id='main']//div[@class='job-list']//li") # 遍歷每一個職位信息所在的li標籤 for li in li_list: job_name = li.xpath("./div/div[1]//a/div[@class='job-title']/text()")[0] salary = li.xpath("./div/div[1]//a/span/text()")[0] detail_url ='https://www.zhipin.com' + li.xpath("./div/div[1]//a/@href")[0] company_name = li.xpath("./div/div[2]/div[@class='company-text']/h3/a/text()")[0] print(job_name,salary,detail_url,company_name) # 獲取職位詳細要求 detail_page_text = requests.get(url=detail_url,headers=headers).text detail_tree = etree.HTML(detail_page_text) job_desc = detail_tree.xpath('//*[@id="main"]/div[3]/div/div[2]/div[2]/div[1]/div/text()') job_desc = ''.join(job_desc) f.write(job_name+":"+salary+":"+company_name+":"+job_desc+"\n\n") f.close()