python爬蟲指南之xpath實(shí)例解析(附實(shí)戰(zhàn))
前言
XPath,全稱XML Path Language,即XML路徑語言,它是一門在XML文檔中查找信息的語言,它最初是用來搜尋XML文檔的,但是它同樣適用于HTML文檔的搜索
XPath的選擇功能十分強(qiáng)大,它提供了非常簡明的路徑選擇表達(dá)式,另外,它還提供了超過100個(gè)內(nèi)建函數(shù),用于字符串、數(shù)值、時(shí)間的匹配以及節(jié)點(diǎn)、序列的處理等,幾乎所有我們想要定位的節(jié)點(diǎn),都可以用XPath來選擇
xpath解析原理:
1.實(shí)現(xiàn)標(biāo)簽的定位:實(shí)例化一個(gè)etree的對象,且需要將被解析的頁面源碼數(shù)據(jù)加載到該對象中。
2.調(diào)用etree對象中的xpath方法結(jié)合著xpath表達(dá)式實(shí)現(xiàn)標(biāo)簽的定位和內(nèi)容的捕獲。
環(huán)境的安裝
pip install lxml
lxml是python的一個(gè)解析庫,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高
如何實(shí)例化一個(gè)etree對象
1.將本地的html文檔中的源碼數(shù)據(jù)加載到etree對象中:
etree. parse(filePath)#你的文件路徑
2.可以將從互聯(lián)網(wǎng)上獲取的源碼數(shù)據(jù)加載到該對象中
etree.HtML('page_ text')#page_ text互聯(lián)網(wǎng)中響應(yīng)的數(shù)據(jù)
xpath 表達(dá)式
表達(dá)式 | 描述 |
---|---|
nodename | 選取此節(jié)點(diǎn)的所有子節(jié)點(diǎn) |
/ | 表示的是從根節(jié)點(diǎn)開始定位。表示的是一個(gè)層級。 |
// | 表示的是多個(gè)層級??梢员硎緩娜我馕恢瞄_始定位。 |
. | 選取當(dāng)前節(jié)點(diǎn) |
… | 選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn) |
@ | 選取屬性 |
* | 通配符,選擇所有元素節(jié)點(diǎn)與元素名 |
@* | 選取所有屬性 |
[@attrib] | 選取具有給定屬性的所有元素 |
[@attrib=‘value’] | 選取給定屬性具有給定值的所有元素 |
[tag] | 選取所有具有指定元素的直接子節(jié)點(diǎn) |
[tag=‘text’] | 選取所有具有指定元素并且文本內(nèi)容是text節(jié)點(diǎn) |
對上面表達(dá)式的實(shí)例詳解
這是一個(gè)HTML的文檔
<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 title="趙匡胤" target="_self"> <span>this is span</span> 宋朝是最強(qiáng)大的王朝,不是軍隊(duì)的強(qiáng)大,而是經(jīng)濟(jì)很強(qiáng)大,國民都很有錢</a> <a href="" class="du">總為浮云能蔽日,長安不見使人愁</a> <img src="http://www.baidu.com/meinv.jpg" alt="" /> </div> <div class="tang"> <ul> <li><a title="qing">清明時(shí)節(jié)雨紛紛,路上行人欲斷魂,借問酒家何處有,牧童遙指杏花村</a></li> <li><a title="qin">秦時(shí)明月漢時(shí)關(guān),萬里長征人未還,但使龍城飛將在,不教胡馬度陰山</a></li> <li><a alt="qi">岐王宅里尋常見,崔九堂前幾度聞,正是江南好風(fēng)景,落花時(shí)節(jié)又逢君</a></li> <li><a class="du">杜甫</a></li> <li><a class="du">杜牧</a></li> <li><b>杜小月</b></li> <li><i>度蜜月</i></li> <li><a id="feng">鳳凰臺(tái)上鳳凰游,鳳去臺(tái)空江自流,吳宮花草埋幽徑,晉代衣冠成古丘</a></li> </ul> </div> </body> </html>
從瀏覽器中打開是這樣的
為了方便直觀,我們對寫個(gè)HTML文件進(jìn)行本地讀取進(jìn)行測試
子節(jié)點(diǎn)和子孫節(jié)點(diǎn)的定位 / 和 //
先來看子節(jié)點(diǎn)和子孫節(jié)點(diǎn),我們從上往下找div這個(gè)節(jié)點(diǎn),可以看到div的父節(jié)點(diǎn)是body,body父節(jié)點(diǎn)是html
定位到這個(gè)HTML的div對象中,看上面html源碼,可以知道有三個(gè)div對象
我們通過三種不同的方法來輸出這個(gè)節(jié)點(diǎn)的信息,可以看到輸出的是三個(gè)一樣的Element,也就是這三種方法實(shí)現(xiàn)的功能是一樣的。
import requests from lxml import etree tree = etree.parse('test.html') r1=tree.xpath('/html/body/div') #直接從上往下挨著找節(jié)點(diǎn) r2=tree.xpath('/html//div')#跳躍了一個(gè)節(jié)點(diǎn)來找到這個(gè)div節(jié)點(diǎn)的對象 r3=tree.xpath('//div')##跳躍上面所有節(jié)點(diǎn)來尋找div節(jié)點(diǎn)的對象 r1,r2,r3 >> ([<Element div at 0x19d44765108>, <Element div at 0x19d447658c8>, <Element div at 0x19d44765588>], [<Element div at 0x19d44765108>, <Element div at 0x19d447658c8>, <Element div at 0x19d44765588>], [<Element div at 0x19d44765108>, <Element div at 0x19d447658c8>, <Element div at 0x19d44765588>])
屬性定位
如果我只想要div里面song這一個(gè)標(biāo)簽,就可以對其屬性定位
當(dāng)然返回的還是一個(gè)element
r4=tree.xpath('//div[@class="song"]') r4 >> >[<Element div at 0x19d447658c8>]
索引定位
如果我只想獲得song里面的蘇軾的這個(gè)標(biāo)簽
我們找到了song,/p可以返回里面的所有標(biāo)簽,
tree.xpath('//div[@class="song"]/p') >> [<Element p at 0x19d4469a648>, <Element p at 0x19d4469a4c8>, <Element p at 0x19d4469af88>, <Element p at 0x19d4469a148>]
這個(gè)單獨(dú)返回的蘇軾的p標(biāo)簽,要注意的是這里的索引不是從0開始的,而是1
tree.xpath('//div[@class="song"]/p[3]') [<Element p at 0x19d4469af88>]
取文本
比如我想取杜牧這個(gè)文本內(nèi)容
和上面一樣,我們要定位到杜牧的這個(gè)a標(biāo)簽,首先要找到他的上一級 li ,這是第五個(gè) li 里面的a所以就有了下面的寫法,text()是把element轉(zhuǎn)化為文本,當(dāng)然上面的在后面加個(gè)text()都可以展示文本內(nèi)容。
tree.xpath('//div[@class="tang"]//li[5]/a/text()') >> ['杜牧']
可以看到這個(gè)返回的是一個(gè)列表,如果我們想取里面的字符串,可以這樣
tree.xpath('//div[@class="tang"]//li[5]/a/text()')[0] 杜牧
看一個(gè)更直接的,//li 直接定位到 li這個(gè)標(biāo)簽,//text()直接將這個(gè)標(biāo)簽下的文本提取出來。但要注意,這樣會(huì)把所有的li標(biāo)簽下面的文本提取出來,有時(shí)候你并不想要的文本也會(huì)提取出來,所以最好還是寫詳細(xì)一點(diǎn),如具體到哪個(gè)div里的li。
tree.xpath('//li//text()') ['清明時(shí)節(jié)雨紛紛,路上行人欲斷魂,借問酒家何處有,牧童遙指杏花村', '秦時(shí)明月漢時(shí)關(guān),萬里長征人未還,但使龍城飛將在,不教胡馬度陰山', '岐王宅里尋常見,崔九堂前幾度聞,正是江南好風(fēng)景,落花時(shí)節(jié)又逢君', '杜甫', '杜牧', '杜小月', '度蜜月', '鳳凰臺(tái)上鳳凰游,鳳去臺(tái)空江自流,吳宮花草埋幽徑,晉代衣冠成古丘']
取屬性
比如我想取下面這個(gè)屬性
可以直接用@取屬性
tree.xpath('//div[@class="song"]/img/@src') ['http://www.baidu.com/meinv.jpg']
或者如果我想取所有的href這個(gè)屬性,可以看到tang和song的所有href屬性
tree.xpath('//@href') ['http://www.song.com/', '', 'http://www.baidu.com', 'http://www.163.com', 'http://www.126.com', 'http://www.sina.com', 'http://www.dudu.com', 'http://www.haha.com']
爬蟲實(shí)戰(zhàn)之58同城房源信息
#導(dǎo)入必要的庫 import requests from lxml import etree #URL就是網(wǎng)址,headers看圖一 url='https://sh.58.com/ershoufang/' headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.7 Safari/537.36'} #對網(wǎng)站發(fā)起請求 page_test=requests.get(url=url,headers=headers).text # 這里是將從互聯(lián)網(wǎng)上獲取的源碼數(shù)據(jù)加載到該對象中 tree=etree.HTML(page_test) #先看圖二的解釋,這里li有多個(gè),所里返回的li_list是一個(gè)列表 li_list=tree.xpath('//ul[@class="house-list-wrap"]/li') #這里我們打開一個(gè)58.txt文件來保存我們的信息 fp=open('58.txt','w',encoding='utf-8') #li遍歷li_list for li in li_list: #這里 ./是對前面li的繼承,相當(dāng)于li/div... title=li.xpath('./div[2]/h2/a/text()')[0] print(title+'\n') #把文件寫入文件 fp.write(title+'\n') fp.close()
圖一:
圖二:.
這里我們要提取所有的房源信息,可以看到每個(gè)小節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)都是一樣的,我們要提取的是h2節(jié)點(diǎn)a里的房源信息,看圖三
這里每個(gè) /li 節(jié)點(diǎn)里面的子節(jié)點(diǎn)都是一樣的,所以我們可以先找到所有的li節(jié)點(diǎn),再往下找我們想要的信息
總結(jié)
到此這篇關(guān)于python爬蟲指南之xpath實(shí)例解析的文章就介紹到這了,更多相關(guān)python爬蟲之xpath內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python將unicode和str互相轉(zhuǎn)化的實(shí)現(xiàn)
這篇文章主要介紹了python將unicode和str互相轉(zhuǎn)化的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05Python免登錄實(shí)現(xiàn)域名解析的示例詳解
這篇文章主要介紹了如何利用編寫python腳本,實(shí)現(xiàn)通過dnspod api獲取個(gè)人域名內(nèi)的dns解析記錄,從而實(shí)現(xiàn)域名的解析、修改和刪除,需要的可以參考一下2023-03-03python中的try except與R語言中的tryCatch異常解決
這篇文章主要為大家介紹了python中的try except與R語言中的tryCatch異常解決的方式及分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11Python sqlparse 解析庫的基礎(chǔ)使用過程解析
sqlparse 是一個(gè) Python 庫,是一個(gè)用于 Python 的非驗(yàn)證 SQL 解析器, 用于解析 SQL 語句并提供一個(gè)簡單的 API 來訪問解析后的 SQL 結(jié)構(gòu),這篇文章主要介紹了Python sqlparse 解析庫的基礎(chǔ)使用,需要的朋友可以參考下2024-08-08七個(gè)非常實(shí)用的Python工具包總結(jié)
Python 擁有海量的包,無論是普通任務(wù)還是復(fù)雜任務(wù),我們經(jīng)常在應(yīng)用程序中使用大量的工具包.本文我將討論一些常被低估的數(shù)據(jù)科學(xué)包,包括:數(shù)據(jù)清理、應(yīng)用程序開發(fā)和調(diào)試方面,需要的朋友可以參考下2021-06-06