xpath無法定位tbody標(biāo)簽解決方法示例
引言
你用 selenium
抓取,必定有 body
你用 requests
抓取,不一定有 body
瀏覽器會(huì)對(duì)不存在 body
的情況自動(dòng)加上 body
所以,你用 requests
抓取就去分析 html tree
用 selenium
就去分析 render tree
html tree
就是 networks
標(biāo)簽中的 html
內(nèi)容;render tree
就是 Elements
標(biāo)簽頁(yè)中的內(nèi)容
以前的講法有點(diǎn)問題,所以再次更新一下,也算是填坑
定位不到tbody是因?yàn)闃?biāo)準(zhǔn)差異,tbody不是必須存在的
chrome的Elements標(biāo)簽頁(yè)的tbody是肯定存在的
但是程序員寫的網(wǎng)頁(yè)不一定會(huì)有tbody
但是在chrome的Elements標(biāo)簽頁(yè)不管返回的html有沒有tbody,chrome都會(huì)有(有就不加,沒有就自動(dòng)加上)
所以用selenium請(qǐng)求網(wǎng)頁(yè)數(shù)據(jù),就加上tbody標(biāo)簽,因?yàn)閟elenium返回的必定是包含tbody的(因?yàn)榉祷氐氖莄hrome的Elements標(biāo)簽頁(yè)的內(nèi)容)
用requests請(qǐng)求的時(shí)候,就自己看看源html內(nèi)是否真的包含tbody標(biāo)簽(可以在chrome的network標(biāo)簽頁(yè)下查看)
總結(jié):服務(wù)器返回的html不一定有tbody標(biāo)簽(具體看網(wǎng)站前端程序員有沒有加tbody標(biāo)簽),但是經(jīng)過chrome渲染的render html必定包含tbody標(biāo)簽(服務(wù)器返回沒有的話,瀏覽器就給你自動(dòng)加上)
以下是原文:
寫于2019.10.29日
測(cè)試庫(kù):lxml庫(kù);鏈接鏈接:http://www.sxchxx.com/index-13-1075-1.html
問題發(fā)現(xiàn)
個(gè)人比較喜歡用xpath解析網(wǎng)頁(yè),但時(shí)常得到的結(jié)果卻是一個(gè)空列表。
1.1 etree.HTML
from lxml import etree import requests url = 'http://www.sxchxx.com/index-13-1075-1.html' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36', } resposne = requests.get(url, headers=headers) parser = etree.HTMLParser(encoding="utf-8") html = etree.HTML(resposne.text, parser=parser) resu=html.xpath('//*[@id="large_mid"]/table[2]/tr[3]/td/p//text()') print(resu)
當(dāng)用如上代碼解析如下網(wǎng)頁(yè)時(shí),可以獲取正文
但發(fā)現(xiàn)我們并沒有在rule里面加入tbody標(biāo)簽。相反,加入tbody標(biāo)簽會(huì)使的解析結(jié)果變成一個(gè)空列表
html.xpath('//*[@id="large_mid"]/table[2]/tbody/tr[3]/td/p//text()') # 這樣會(huì)得到空列表
1.2 etree.parse
使用etree.parse和etree.HTML恰好相反
from lxml import etree import requests parser = etree.HTMLParser(encoding="utf-8") html = etree.parse('test.html', parser=parser) content = html.xpath('//*[@id="large_mid"]/table[2]/tbody/tr[3]/td/p//text()') print(content)
將網(wǎng)頁(yè)保存成test.html,再用etree.parse加載,發(fā)現(xiàn)rule中加入tbody標(biāo)簽才能獲得預(yù)期的結(jié)果;不加tbody標(biāo)簽會(huì)獲得一個(gè)空列表
1.3 代碼對(duì)比
from lxml import etree import requests parser = etree.HTMLParser(encoding="utf-8") html = etree.parse('test.html', parser=parser) content = html.xpath('//*[@id="large_mid"]/table[2]/tbody/tr[3]/td/p//text()') print(content) print('----------------分割線-------------------') url = 'http://www.sxchxx.com/index-13-1075-1.html' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36', } resposne = requests.get(url, headers=headers) parser = etree.HTMLParser(encoding="utf-8") html = etree.HTML(resposne.text, parser=parser) content = html.xpath('//*[@id="large_mid"]/table[2]/tr[3]/td/p//text()') print(content)
解決問題
2.1曲線救國(guó)
如果解析在線網(wǎng)頁(yè),不要添加tbody標(biāo)簽反則解析本地(離線)網(wǎng)頁(yè),添加tbody標(biāo)簽
2.2其他方法
請(qǐng)看下面的原因分析
問題發(fā)生的原因
對(duì)比上面兩種方法,差異在于html = etree.parse('test.html', parser=parser)
html = etree.HTML(resposne.text)
這兩行代碼
而解析器是相同的parser = etree.HTMLParser(encoding="utf-8")
因此,我猜測(cè),可能是parse或者HTML對(duì)代碼做了某種“格式化”調(diào)整。
貌似lxml這個(gè)庫(kù)使用其他語言編寫,看不到源代碼,無法從源代碼下手檢查
以上就是xpath無法定位tbody標(biāo)簽解決方法示例的詳細(xì)內(nèi)容,更多關(guān)于xpath定位tbody標(biāo)簽的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python自動(dòng)12306搶票軟件實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了python自動(dòng)12306搶票軟件的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02python編程的核心知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理的是一篇關(guān)于python編程的核心知識(shí)點(diǎn)總結(jié)內(nèi)容,對(duì)此有興趣的朋友們可以學(xué)習(xí)參考下。2021-02-02Python selenium實(shí)現(xiàn)斷言3種方法解析
這篇文章主要介紹了Python selenium實(shí)現(xiàn)斷言3種方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09python中string模塊各屬性以及函數(shù)的用法介紹
下面小編就為大家?guī)硪黄猵ython中string模塊各屬性以及函數(shù)的用法介紹。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-05-05解決PyCharm 中寫 Turtle代碼沒提示以及標(biāo)黃的問題
這篇文章主要介紹了解決PyCharm 中寫 Turtle代碼沒提示以及標(biāo)黃的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03