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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

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

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

Python3 爬蟲學習筆記第七章 —— 【解析庫 lxml】

文章目錄

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


【7.1】關于 lxml

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

【7.2】使用 XPath

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

XPath 常用規則

表達式描述
nodename選取此節點的所有子節點
/從當前節點選取直接子節點
//從當前節點選取子孫節點
.選取當前節點
選取當前節點的父節點
@選取屬性
*通配符,選擇所有元素節點與元素名
@*選取所有屬性
[@attrib]選取具有給定屬性的所有元素
[@attrib=‘value’]選取給定屬性具有給定值的所有元素
[tag]選取所有具有指定元素的直接子節點
[tag=‘text’]選取所有具有指定元素并且文本內容是text節點

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

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

【7.3】查找所有節點

新建一個 xpath.html 本地文件,內容如下:

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" /><title>xpath測試</title> </head> <body> <div class="song">火藥<b>指南針</b><b>印刷術</b>造紙術 </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">咋暖還寒時候,最難將息。</li><li class="lilei">三杯兩盞淡酒。</li><li>怎敵他晚來風急。</li><li>雁過也,正傷心,卻是舊時相識。</li><li>愛情三十六計</li><li>什么是愛情</li></ol> </div> </body> </html>

查找所有節點:

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

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

[<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】查找子節點

通過 /// 即可查找元素的子節點或子孫節點:

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

選擇 ul 節點的所有直接 li 子節點:

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

【7.5】查找父節點

知道了子節點,也可以用 或者 parent:: 查找其父節點

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 節點,隨后獲取其父節點以及其 class 屬性:

['tang']

【7.6】屬性匹配

有時候 HTML 包含多個相同名的節點,而節點的屬性是不一樣的,此時可以用 @ 符號進行屬性過濾

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

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

[<Element li at 0x16e53aa54c8>]

【7.7】文本獲取

使用 text() 方法即可提取節點中的文本:

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

輸出結果:

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

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

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

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

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

輸出結果:

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

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

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

輸出結果:

['\n ', '尋尋覓覓冷冷清清,凄凄慘慘戚戚。', '\n ', '咋暖還寒時候,最難將息。', '\n ', '三杯兩盞淡酒。', '\n ', '怎敵他晚來風急。', '\n ', '雁過也,正傷心,卻是舊時相識。', '\n ', '愛情三十六計', '\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】一個屬性包含多個值的匹配

某個節點的某個屬性可能有多個值,例如:

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

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

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)

輸出結果:

['first item']

【7.10】多個屬性匹配一個節點

XPath 還可以根據多個屬性來確定一個節點,這時就需要同時匹配多個屬性。此時可以使用運算符 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)

輸出結果:

['first item']

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

運算符描述實例返回值
orage=19 or age=20如果 age 是 19 或者 20,則返回 true。如果 age 是其他值,則返回 false
andage>19 and age<21如果 age 大于 19 且小于 21,則返回 true。如果 age 是其他值,則返回 false
mod計算除法的余數5 mod 21
|計算兩個節點集//book | //cd返回所有擁有 book 和 cd 元素的節點集
+加法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】按順序選擇節點

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

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 節點;
  • li[last()]:選取最后一個 li 節點;
  • position()< 3:選取位置小于 3 的 li 節點;
  • li[last()-2]:選取倒數第三個 li 節點

輸出結果:

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

【7.12】節點軸選擇

節點軸選擇:獲取子元素、兄弟元素、父元素、祖先元素等

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)

輸出結果:

[<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>]

基本語法:軸名稱::節點測試[謂語]

軸名稱對應的結果:

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

實例:

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。