xpath用于HTML文档通过元素,理解HTML和XPath
8種機(jī)械鍵盤軸體對(duì)比
本人程序員,要買一個(gè)寫代碼的鍵盤,請(qǐng)問紅軸和茶軸怎么選?
我們已經(jīng)知道HTML是文本標(biāo)記語言,那么HTML和瀏覽器有什么樣的關(guān)系呢?
當(dāng)我們?cè)跒g覽器中輸入U(xiǎn)RL到瀏覽器顯示出頁面的過程一般包括四個(gè)步驟:在瀏覽器輸入U(xiǎn)RL。URL的第一部分(域名,比如baidu.com)用于在網(wǎng)絡(luò)上找到合適的服務(wù)器,而URL以及cookie等其他數(shù)據(jù)則構(gòu)成了一個(gè)請(qǐng)求,用于發(fā)送到那臺(tái)服務(wù)器當(dāng)中。
服務(wù)器端回應(yīng),向?yàn)g覽器發(fā)送一個(gè)HTML頁面。(也有可能發(fā)送的是json或者XML格式)
將HTML轉(zhuǎn)換成為瀏覽器內(nèi)部的樹狀表示形式:文檔對(duì)象模型(Document Object Model,DOM)
基于一些布局規(guī)則渲染內(nèi)部表示,達(dá)到我們?cè)跒g覽器上看到的效果。
下面來看看這些步驟,以及他們所需要的文檔表示。
URL
URL剩余的部分對(duì)于服務(wù)器端理解請(qǐng)求是什么非常重要。它可能是一張圖片、一個(gè)文檔,或是需要觸發(fā)某個(gè)動(dòng)作的東西,比如向服務(wù)器發(fā)送郵件。
HTML文檔
服務(wù)器端讀取URL,理解我們的請(qǐng)求是什么,然后回應(yīng)一個(gè)HTML文檔。該文檔實(shí)質(zhì)上就是一個(gè)文本文件,我們可以使用編輯器打開它。和大多數(shù)文本文檔不同,HTML文檔具有萬維網(wǎng)聯(lián)盟指定的格式。當(dāng)我們?cè)跒g覽器訪問https://www.baidu.com的時(shí)候,可以右鍵選擇查看源代碼。
樹表示法(DOM)
每個(gè)瀏覽器都有其復(fù)雜的內(nèi)部數(shù)據(jù)結(jié)構(gòu),憑借它來渲染網(wǎng)頁。DOM表示法具有跨平臺(tái)、語言無關(guān)性等特點(diǎn),并且被大多數(shù)瀏覽器支持。
想要在Chrome中查看網(wǎng)頁的樹表示法,可以選擇一個(gè)元素然后右鍵檢查。
這個(gè)時(shí)候我們看到的這個(gè)東西就是HTML代碼的樹表示法。
HTML只是文本,而樹表示法是瀏覽器內(nèi)存里的對(duì)象。
瀏覽器
HTML文本表示和樹表示并不是向我們通常在瀏覽器上看到的那種視圖。那么,樹表示法是如何映射到我們?cè)跒g覽器上看到的東西呢?答案就是框模型。正如DOM樹元素可以包含其他元素或文本一樣,默認(rèn)情況下,擋在屏幕上渲染時(shí),每個(gè)元素的框白哦是同樣也都包含其嵌入元素的框表示。從某種意義上來說,我們?cè)跒g覽器上所看到的是原始HTML文檔的二維表示—-樹結(jié)構(gòu)也以一種隱藏的方式作為該表示的一部分。
使用XPath選擇HTML元素
前面已經(jīng)介紹過XPath的基本語法:鏈接 在這兒就復(fù)習(xí)一下:
XPath表達(dá)式://標(biāo)簽1[@屬性1 = “值”]//標(biāo)簽2[@屬性2 = “值”]/…/text()
//a[@href]用來選擇包含href屬性的所有鏈接,
不加text()[email?protected],可以對(duì)這個(gè)對(duì)象再次使用XPath,這也就是先抓大再抓小的策略。
提取文本使用text()
使用*符號(hào)來選擇指定層級(jí)的所有元素
而在Scrapy中,我們?cè)谧詈筮€要.extract這個(gè)屬性才能提取出來元素。
接下來我們學(xué)習(xí)常見的XPath
重點(diǎn):前面的XPath學(xué)習(xí)中我都不知道XPath還有這種語法:
對(duì)于大型文檔,可能需要編寫一個(gè)非常大的XPath表達(dá)式以訪問指定元素。為了避免這一問題,可以使用”//語法”,它可以讓你取得某一特定類型的元素,而無需考慮其所在的層次結(jié)構(gòu)。比如,//p將會(huì)選擇所有的p標(biāo)簽,而//a則會(huì)選擇所有的鏈接。
//語法可以在層次結(jié)構(gòu)中的任何地方使用,這非常有用。比如我們想找到div class = “test”下的p標(biāo)簽中的內(nèi)容,這個(gè)div class = “test”下可能還有很多子標(biāo)簽,但我們需要的只是p標(biāo)簽的內(nèi)容,就可以使用這個(gè)語法:
//div[@class=”test”]//p/text()
我們也可以選擇div test下的子div test1中的所有p標(biāo)簽中的內(nèi)容
//div[@class=”test”]/div[@class=”test1”]//p/text()
這個(gè)語法非常有用,有點(diǎn)相見恨晚的感覺,再寫爬蟲的時(shí)候,經(jīng)常需要使用XPath來提取有用的信息。這個(gè)XPath通常會(huì)費(fèi)好大勁才能分析出來該怎么寫,要搞清楚我們需要的信息屬于哪個(gè)標(biāo)簽,通常在網(wǎng)頁源代碼中,這種嵌套關(guān)系可能有很多層。現(xiàn)在有個(gè)這個(gè)語法,我們只需要找到包含我們需要的信息的標(biāo)簽,然后直接使用//語法來獲得我們需要的標(biāo)簽,這要省不少事。
更加有用的是,它還擁有找到href屬性中以一個(gè)特定子字符串起始或包含的能力。
//a[starts-with(@href,”http://www")]
//a[contains(@href,”baidu”)]
//a[not(contains(@href,”baidu”))]
這些就是XPath的函數(shù),starts-with()函數(shù)表示以特定值開頭,contains()函數(shù)表示屬性包含特定值,not(contains())表示不包含某特定值。XPath有很多像這樣的函數(shù),可以在百度上找到,不過這些函數(shù)不經(jīng)常使用,記清楚基礎(chǔ)的XPath語法才是重中之重。
常見XPath實(shí)例
有一些XPath表達(dá)式,我們將會(huì)將常遇到:獲取id為test的h1標(biāo)簽下的span中的text。
//h1[@id=”test”]/span/text()
獲取id為toc的div標(biāo)簽內(nèi)的無序列表中所有的鏈接
[email?protected]素內(nèi)所有h1標(biāo)簽下的文本,這兩個(gè)屬性可能在同一個(gè)class中,也可能在不同的class中
//*[contains(@class,”ltr”) and contains(@class,”ltr1”)]//h1/text()
XPath的contains函數(shù)可以讓你選擇包含指定類的所有元素。選擇class屬性值為infobox的表格中的第一張圖片的URL。
//table[@class=”infobox”]//img[1][email?protected]
//div[starts-with(@class,”reflist”)][email?protected]
//*[text()=”test”]/../following-sibling::div//a
請(qǐng)注意該表達(dá)式非常脆弱,并且很容易無法使用,因?yàn)樗麑?duì)文檔結(jié)果做了過多假設(shè)。
更穩(wěn)定的XPath
我們?cè)谧ト【W(wǎng)頁時(shí),網(wǎng)頁經(jīng)常會(huì)發(fā)生變化。有時(shí)網(wǎng)頁結(jié)果也會(huì)發(fā)生變化,因?yàn)榫W(wǎng)站有人在維護(hù)。如果他們的HTML已某種方式發(fā)生變化時(shí),我們要調(diào)整我們的XPath。我們?cè)趯慩Path時(shí)盡量遵循以下原則,幫助我們減少重寫XPath的可能性。避免使用數(shù)組索引,例如:
//*[@id=”posts”]/article/div/div[1]/p
我們從瀏覽器中copy出來的XPath中經(jīng)常會(huì)包含大量數(shù)字,解決辦法是找到一個(gè)最接近p標(biāo)簽的標(biāo)簽,找到一個(gè)可以使用的包含id或者class屬性的元素,如:
//div[@class=”post-body”]/p
類并沒有那么好用
使用class屬性可以更加容易的精確定位元素,不過這些屬性一般是用于通過css影響外觀的,新詞可能會(huì)由于網(wǎng)站布局的微小變更而產(chǎn)生變化。
有意義的面向數(shù)據(jù)的類要比具體的或者面向布局的類更好
我們?cè)谑褂妙愡x擇標(biāo)簽時(shí),首先要選擇與內(nèi)容相關(guān)的類,因?yàn)檫@樣的類更加可靠。
ID通常是最穩(wěn)定的
通常情況下,id屬性是針對(duì)一個(gè)目標(biāo)的最佳選擇,因?yàn)樵搶傩约扔幸饬x又與數(shù)據(jù)相關(guān)。
總結(jié)
以上是生活随笔為你收集整理的xpath用于HTML文档通过元素,理解HTML和XPath的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ORACLE MERGE INTO语句,
- 下一篇: Ubuntu杀死进程