日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python3 爬虫学习笔记 C07 【解析库 lxml】

發(fā)布時(shí)間:2023/12/10 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python3 爬虫学习笔记 C07 【解析库 lxml】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Python3 爬蟲學(xué)習(xí)筆記第七章 —— 【解析庫 lxml】

文章目錄

  • 【7.1】關(guān)于 lxml
  • 【7.2】使用 XPath
  • 【7.3】查找所有節(jié)點(diǎn)
  • 【7.4】查找子節(jié)點(diǎn)
  • 【7.5】查找父節(jié)點(diǎn)
  • 【7.6】屬性匹配
  • 【7.7】文本獲取
  • 【7.8】屬性獲取
  • 【7.9】一個屬性包含多個值的匹配
  • 【7.10】多個屬性匹配一個節(jié)點(diǎn)
  • 【7.11】按順序選擇節(jié)點(diǎn)
  • 【7.12】節(jié)點(diǎn)軸選擇


【7.1】關(guān)于 lxml

lxml 是 Python 的一個解析庫,支持 HTML 和 XML 的解析,支持 XPath 解析方式,解析效率非常高,使用前需要用命令 pip3 install lxml 安裝 lxml 庫

【7.2】使用 XPath

XPath(XML Path Language)即 XML 路徑語言, lxml 解析庫使用的正是 XPath 語法,最初是用來搜尋 XML 文檔的,是一門在 XML 文檔中查找信息的語言,它同樣適用于 HTML 文檔的搜索

XPath 常用規(guī)則

表達(dá)式描述
nodename選取此節(jié)點(diǎn)的所有子節(jié)點(diǎn)
/從當(dāng)前節(jié)點(diǎn)選取直接子節(jié)點(diǎn)
//從當(dāng)前節(jié)點(diǎn)選取子孫節(jié)點(diǎn)
.選取當(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)

瀏覽器插件 XPath Helper,在線驗(yàn)證 XPath,谷歌商店下載地址:https://chrome.google.com/webstore/detail/hgimnogjllphhhkhlmebbmlgjoejdpjl

XPath 基本使用方法:首先使用代碼 from lxml import etree導(dǎo)入庫,然后將 HTML 文檔變成一個對象,再調(diào)用對象的方法去查找指定的節(jié)點(diǎn),方法有兩種:tree = etree.parse() 為本地文件查找,tree = etree.HTML() 為網(wǎng)絡(luò)文件查找,再使用語句 tree.xpath() 查找指定節(jié)點(diǎn)。

【7.3】查找所有節(jié)點(diǎn)

新建一個 xpath.html 本地文件,內(nèi)容如下:

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" /><title>xpath測試</title> </head> <body> <div class="song">火藥<b>指南針</b><b>印刷術(shù)</b>造紙術(shù) </div> <div class="tang"><ul><li class="balove">停車坐愛楓林晚,霜葉紅于二月花。</li><li id="hua">商女不知亡國恨,隔江猶唱后庭花。</li><li class="love" name="yang">一騎紅塵妃子笑,無人知是荔枝來。</li><li id="bei">葡萄美酒夜光杯,欲飲琵琶馬上催。</li><li><a href="http://www.baidu.com/">百度一下</a> </li></ul><ol><li class="balucy">尋尋覓覓冷冷清清,凄凄慘慘戚戚。</li><li class="lily">咋暖還寒時(shí)候,最難將息。</li><li class="lilei">三杯兩盞淡酒。</li><li>怎敵他晚來風(fēng)急。</li><li>雁過也,正傷心,卻是舊時(shí)相識。</li><li>愛情三十六計(jì)</li><li>什么是愛情</li></ol> </div> </body> </html>

查找所有節(jié)點(diǎn):

from lxml import etreehtml = etree.parse('./xpath.html') result = html.xpath('//*') print(result)

使用 * 代表匹配所有節(jié)點(diǎn),整個 xpath.html 文件中的所有節(jié)點(diǎn)都會被獲取到,返回形式是一個列表,每個元素是 Element 類型,其后跟了節(jié)點(diǎn)的名稱,如 html、body、div、ul、li、a 等,所有節(jié)點(diǎn)都包含在列表中,輸出結(jié)果如下:

[<Element html at 0x1a836a34508>, <Element head at 0x1a836a344c8>, <Element meta at 0x1a836a345c8>, <Element title at 0x1a836a34608>, <Element body at 0x1a836a34648>, <Element div at 0x1a836a346c8>, <Element b at 0x1a836a34708>, <Element b at 0x1a836a34748>, <Element div at 0x1a836a34788>, <Element ul at 0x1a836a34688>, <Element li at 0x1a836a347c8>, <Element li at 0x1a836a34808>, <Element li at 0x1a836a34848>, <Element li at 0x1a836a34888>, <Element li at 0x1a836a348c8>, <Element a at 0x1a836a34908>, <Element ol at 0x1a836a34948>, <Element li at 0x1a836a34988>, <Element li at 0x1a836a349c8>, <Element li at 0x1a836a34a08>, <Element li at 0x1a836a34a48>, <Element li at 0x1a836a34a88>, <Element li at 0x1a836a34ac8>, <Element li at 0x1a836a34b08>]

【7.4】查找子節(jié)點(diǎn)

通過 /// 即可查找元素的子節(jié)點(diǎn)或子孫節(jié)點(diǎn):

from lxml import etreehtml = etree.parse('./xpath.html') result = html.xpath('//ul/li') print(result)

選擇 ul 節(jié)點(diǎn)的所有直接 li 子節(jié)點(diǎn):

[<Element li at 0x2a094d044c8>, <Element li at 0x2a094d045c8>, <Element li at 0x2a094d04608>, <Element li at 0x2a094d04648>, <Element li at 0x2a094d04688>]

【7.5】查找父節(jié)點(diǎn)

知道了子節(jié)點(diǎn),也可以用 或者 parent:: 查找其父節(jié)點(diǎn)

from lxml import etreehtml = etree.parse('./xpath.html') result = html.xpath('//ol/../@class') print(result) from lxml import etreehtml = etree.parse('./xpath.html') result = html.xpath('//ol/parent::*/@class') print(result)

先查找到 ol 節(jié)點(diǎn),隨后獲取其父節(jié)點(diǎn)以及其 class 屬性:

['tang']

【7.6】屬性匹配

有時(shí)候 HTML 包含多個相同名的節(jié)點(diǎn),而節(jié)點(diǎn)的屬性是不一樣的,此時(shí)可以用 @ 符號進(jìn)行屬性過濾

from lxml import etreehtml = etree.parse('./xpath.html') result = html.xpath('//li[@class="balucy"]') print(result)

xpath.html 文件中,只有一個 class 為 balucy 的節(jié)點(diǎn):<li class="balucy">尋尋覓覓冷冷清清,凄凄慘慘戚戚。</li>,運(yùn)行以上代碼將返回一個該元素:

[<Element li at 0x16e53aa54c8>]

【7.7】文本獲取

使用 text() 方法即可提取節(jié)點(diǎn)中的文本:

from lxml import etreehtml = etree.parse('./xpath.html') result = html.xpath('//li[@class="balucy"]/text()') print(result)

輸出結(jié)果:

['尋尋覓覓冷冷清清,凄凄慘慘戚戚。']

再次觀察 xpath.html 文件中的 <ol></ol>這一部分:

<ol><li class="balucy">尋尋覓覓冷冷清清,凄凄慘慘戚戚。</li><li class="lily">咋暖還寒時(shí)候,最難將息。</li><li class="lilei">三杯兩盞淡酒。</li><li>怎敵他晚來風(fēng)急。</li><li>雁過也,正傷心,卻是舊時(shí)相識。</li><li>愛情三十六計(jì)</li><li>什么是愛情</li> </ol>

如果我們想要提取 <li> 節(jié)點(diǎn)里面所有的文本,就可以使用 html.xpath('//ol/li/text()') 語句:

from lxml import etreehtml = etree.parse('./xpath.html') result = html.xpath('//ol/li/text()') print(result)

輸出結(jié)果:

['尋尋覓覓冷冷清清,凄凄慘慘戚戚。', '咋暖還寒時(shí)候,最難將息。', '三杯兩盞淡酒。', '怎敵他晚來風(fēng)急。', '雁過也,正傷心,卻是舊時(shí)相識。', '愛情三十六計(jì)', '什么是愛情']

同樣還有另一種方法,使用 html.xpath('//ol//text()') 語句,// 將會選取所有子孫節(jié)點(diǎn)的文本,<ol> 和 <li> 節(jié)點(diǎn)下的換行符也將被提取出來:

from lxml import etreehtml = etree.parse('./xpath.html') result = html.xpath('//ol//text()') print(result)

輸出結(jié)果:

['\n ', '尋尋覓覓冷冷清清,凄凄慘慘戚戚。', '\n ', '咋暖還寒時(shí)候,最難將息。', '\n ', '三杯兩盞淡酒。', '\n ', '怎敵他晚來風(fēng)急。', '\n ', '雁過也,正傷心,卻是舊時(shí)相識。', '\n ', '愛情三十六計(jì)', '\n ', '什么是愛情', '\n ']

【7.8】屬性獲取

與屬性匹配一樣,屬性獲取仍然使用 @

from lxml import etreehtml = etree.parse('./xpath.html') result = html.xpath('//ul/li[5]/a/@href') print(result)

獲取 href 屬性:

['http://www.baidu.com/']

【7.9】一個屬性包含多個值的匹配

某個節(jié)點(diǎn)的某個屬性可能有多個值,例如:

<li class="li li-first"><a href="link.html">first item</a></li>

li 節(jié)點(diǎn)的 class 屬性有 li 和 li-first 兩個值,如果使用 html.xpath('//li[@class="li"] 語句,將無法成功匹配,這時(shí)就需要使用 contains 方法了,第一個參數(shù)傳入屬性名稱,第二個參數(shù)傳入屬性值,只要此屬性包含所傳入的屬性值,就可以完成匹配了

from lxml import etree text = ''' <li class="li li-first"><a href="link.html">first item</a></li> ''' html = etree.HTML(text) result = html.xpath('//li[contains(@class, "li")]/a/text()') print(result)

輸出結(jié)果:

['first item']

【7.10】多個屬性匹配一個節(jié)點(diǎn)

XPath 還可以根據(jù)多個屬性來確定一個節(jié)點(diǎn),這時(shí)就需要同時(shí)匹配多個屬性。此時(shí)可以使用運(yùn)算符 and 來連接:

from lxml import etree text = ''' <li class="li" name="item"><a href="link.html">first item</a></li> ''' html = etree.HTML(text) result = html.xpath('//li[@class="li" and @name="item"]/a/text()') print(result)

輸出結(jié)果:

['first item']

示例中運(yùn)用了運(yùn)算符 and 來連接,此外常見的運(yùn)算符如下:

運(yùn)算符描述實(shí)例返回值
orage=19 or age=20如果 age 是 19 或者 20,則返回 true。如果 age 是其他值,則返回 false
andage>19 and age<21如果 age 大于 19 且小于 21,則返回 true。如果 age 是其他值,則返回 false
mod計(jì)算除法的余數(shù)5 mod 21
|計(jì)算兩個節(jié)點(diǎn)集//book | //cd返回所有擁有 book 和 cd 元素的節(jié)點(diǎn)集
+加法10 + 515
-減法10 - 55
*乘法10 * 550
div除法10 div 52
=等于age=19如果 age 是 19,則返回 true。如果 age 不是 19,則返回 false
!=不等于age!=19如果 age 不是 19,則返回 true。如果 age 是 19,則返回 false
<小于age<19如果 age 小于 19,則返回 true。如果 age 不小于 19,則返回 false
<=小于或等于age<=19如果 age 小于等于 19,則返回 true。如果 age 大于 19,則返回 false
>大于age>19如果 age 大于 19,則返回 true。如果 age 不大于 19,則返回 false
>=大于或等于age>=19如果 age 大于等于 19,則返回 true。如果 age 小于 19,則返回 false

【7.11】按順序選擇節(jié)點(diǎn)

某些屬性可能同時(shí)匹配了多個節(jié)點(diǎn),如果要選擇其中幾個節(jié)點(diǎn),可以利用中括號傳入索引的方法獲取特定次序的節(jié)點(diǎn)

from lxml import etreetext = ''' <div><ul><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></ul></div> ''' html = etree.HTML(text) result = html.xpath('//li[1]/a/text()') print(result) result = html.xpath('//li[last()]/a/text()') print(result) result = html.xpath('//li[position()<3]/a/text()') print(result) result = html.xpath('//li[last()-2]/a/text()') print(result)
  • li[1]:選取第一個 li 節(jié)點(diǎn);
  • li[last()]:選取最后一個 li 節(jié)點(diǎn);
  • position()< 3:選取位置小于 3 的 li 節(jié)點(diǎn);
  • li[last()-2]:選取倒數(shù)第三個 li 節(jié)點(diǎn)

輸出結(jié)果:

['first item'] ['fifth item'] ['first item', 'second item'] ['third item']

【7.12】節(jié)點(diǎn)軸選擇

節(jié)點(diǎn)軸選擇:獲取子元素、兄弟元素、父元素、祖先元素等

from lxml import etreetext = ''' <div><ul><li class="item-0"><a href="link1.html"><span>first item</span></a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></ul></div> ''' html = etree.HTML(text) result = html.xpath('//li[1]/ancestor::*') print(result) result = html.xpath('//li[1]/ancestor::div') print(result) result = html.xpath('//li[1]/attribute::*') print(result) result = html.xpath('//li[1]/child::a[@href="link1.html"]') print(result) result = html.xpath('//li[1]/descendant::span') print(result) result = html.xpath('//li[1]/following::*[2]') print(result) result = html.xpath('//li[1]/following-sibling::*') print(result)

輸出結(jié)果:

[<Element html at 0x1d3749e9548>, <Element body at 0x1d3749e94c8>, <Element div at 0x1d3749e9488>, <Element ul at 0x1d3749e9588>] [<Element div at 0x1d3749e9488>] ['item-0'] [<Element a at 0x1d3749e9588>] [<Element span at 0x1d3749e9488>] [<Element a at 0x1d3749e9588>] [<Element li at 0x1d3749e94c8>, <Element li at 0x1d3749e95c8>, <Element li at 0x1d3749e9608>, <Element li at 0x1d3749e9648>]

基本語法:軸名稱::節(jié)點(diǎn)測試[謂語]

軸名稱對應(yīng)的結(jié)果:

軸名稱結(jié)果
ancestor選取當(dāng)前節(jié)點(diǎn)的所有先輩(父、祖父等)
ancestor-or-self選取當(dāng)前節(jié)點(diǎn)的所有先輩(父、祖父等)以及當(dāng)前節(jié)點(diǎn)本身
attribute選取當(dāng)前節(jié)點(diǎn)的所有屬性
child選取當(dāng)前節(jié)點(diǎn)的所有子元素
descendant選取當(dāng)前節(jié)點(diǎn)的所有后代元素(子、孫等)
descendant-or-self選取當(dāng)前節(jié)點(diǎn)的所有后代元素(子、孫等)以及當(dāng)前節(jié)點(diǎn)本身
following選取文檔中當(dāng)前節(jié)點(diǎn)的結(jié)束標(biāo)簽之后的所有節(jié)點(diǎn)
namespace選取當(dāng)前節(jié)點(diǎn)的所有命名空間節(jié)點(diǎn)
parent選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)
preceding選取文檔中當(dāng)前節(jié)點(diǎn)的開始標(biāo)簽之前的所有節(jié)點(diǎn)
preceding-sibling選取當(dāng)前節(jié)點(diǎn)之前的所有同級節(jié)點(diǎn)
self選取當(dāng)前節(jié)點(diǎn)

實(shí)例:

例子結(jié)果
child::book選取所有屬于當(dāng)前節(jié)點(diǎn)的子元素的 book 節(jié)點(diǎn)
attribute::lang選取當(dāng)前節(jié)點(diǎn)的 lang 屬性
child:: *選取當(dāng)前節(jié)點(diǎn)的所有子元素
attribute:: *選取當(dāng)前節(jié)點(diǎn)的所有屬性
child::text()選取當(dāng)前節(jié)點(diǎn)的所有文本子節(jié)點(diǎn)
child::node()選取當(dāng)前節(jié)點(diǎn)的所有子節(jié)點(diǎn)
descendant::book選取當(dāng)前節(jié)點(diǎn)的所有 book 后代
ancestor::book選擇當(dāng)前節(jié)點(diǎn)的所有 book 先輩
ancestor-or-self::book選取當(dāng)前節(jié)點(diǎn)的所有 book 先輩以及當(dāng)前節(jié)點(diǎn)(如果此節(jié)點(diǎn)是 book 節(jié)點(diǎn))
child:: */child::price選取當(dāng)前節(jié)點(diǎn)的所有 price 孫節(jié)點(diǎn)

總結(jié)

以上是生活随笔為你收集整理的Python3 爬虫学习笔记 C07 【解析库 lxml】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。