通過前面的文章,我們已經知道了如何獲取網頁和下載文件,但是前面我們獲取的網頁都是未經處理的,冗余的信息太多,無法進行分析和利用
這一節我們就來學習怎么從網頁中篩選自己需要的信息,順便給大家推薦一個資源很全的python學習免非解答.裙 :七衣衣九七七巴而五(數字的諧音)轉換下可以找到了,這里有資深程序員分享以前學習心得,學習筆記,還有一線企業的工作經驗,且給大家精心整理一份python零基礎到項目實戰的資料,每天給大家講解python最新的技術,前景,學習需要留言的小細節
說到信息篩選我們立馬就會想到正則表達式,不過今天我們不講正則表達式。因為對於爬蟲來講,正則表達式太復雜對新手十分不友好,而且正則表達式的容錯率差,網頁有稍微的改動就得重新寫匹配表達式,另外正則表達式可讀性幾乎沒有。
當然,這並不是說正則不好,只是正則不適合爬蟲和新手。其實正則是十分強大的,在后面的數據清洗里我們會用到正則。
既然正則不能用,那該用什么呢?別擔心,python為我們提供了很多解析 html頁面的庫,其中常用的有:
- bs4中的 BeautifulSoup
- lxml中的 etree(一個 xpath解析庫)
BeautifulSoup類似 jQuery的選擇器,通過 id、css選擇器和標簽來查找元素,xpath主要通過 html節點的嵌套關系來查找元素,和文件的路徑有點像,比如:
#獲取 id為 tab的 table標簽下所有 tr標簽 path = '//table[@id="tab"]//tr' #和文件路徑對比 path = 'D:\Github\hexo\source\_posts'
BeautifulSoup和 xpath沒有好壞優劣之分,講 xpath是因為個人覺得 xpath更好用一些,后面如果時間允許的話再講 BeautifulSoup。
現在,讓我們先從 xpath開始!
二、xpath的安裝和使用
-
安裝 lxml庫
pip install lxml
-
簡單的使用
在使用 xpath之前,先導入 etree類,對原始的 html頁面進行處理獲得一個_Element對象
我們可以通過_Element對象來使用 xpath
#導入 etree類 from lxml import etree #作為示例的 html文本 html = '''<div class="container"> <div class="row"> <div class="col"> <div class="card"> <div class="card-content"> <a href="#123333" class="box"> 點擊我 </a> </div> </div> </div> </div> </div>''' #對 html文本進行處理 獲得一個_Element對象 dom = etree.HTML(html) #獲取 a標簽下的文本 a_text = dom.xpath('//div/div/div/div/div/a/text()') print(a_text)
打印結果:
result-1熟悉 html的朋友都知道在 html中所有的標簽都是節點。一個 html文檔是一個文檔節點,一個文檔節點包含一個節點樹,也叫做 dom樹。
節點樹中的節點彼此擁有層級關系。
父(parent)、子(child)和同胞(sibling)等術語用於描述這些關系。父節點擁有子節點。同級的子節點被稱為同胞(兄弟或姐妹)。
- 在節點樹中,頂端節點被稱為根(root)
- 每個節點都有父節點、除了根(它沒有父節點)
- 一個節點可擁有任意數量的子
- 同胞是擁有相同父節點的節點
from w3school:http://www.w3school.com.cn/htmldom/dom_nodes.asp
另外,我們把距離某個節點最近的子節點叫做它的直接子節點,如下圖所示的 body和 head就是 html的直接子節點
dom樹 w3school了解了 html結構之后我們再來看 xpath的使用。
首先,我們通過 etree.HTML( )來生成一個_Element對象,etree.HTML() 會將傳入的文本處理成一個 html文檔節點。這樣就能保證我們總是能獲得一個包含文檔節點的_Element對象。
-
xpath語法
-
a / b :‘/’在 xpath里表示層級關系,左邊的 a是父節點,右邊的 b是子節點,這里的 b是 a的直接子節點
-
a // b:兩個 / 表示選擇所有 a節點下的 b節點(可以是直接子節點,也可以不是),在上面的例子中我們要選擇 a標簽是這樣寫的
a_text = dom.xpath('//div/div/div/div/div/a/text()') #用 // a_text = dom.xpath('//div//a/text()') #如果 div標簽下有兩個 a標簽,那么這兩個 a標簽都會被選擇(注意兩個 a標簽並不一定是兄弟節點) #比如下面的例子中的兩個 a標簽都會被選擇 因為這兩個 a標簽都是 div的子節點 '''<div class="container"> <div class="row"> <div class="col"> <div class="card"> <a href="#123332" class="box"> 點擊我 </a> <div class="card-content"> <a href="#123333" class="box"> 點擊我 </a> </div> </div> </div> </div> </div>'''
-
[@]:選擇具有某個屬性的節點
- //div[@classs], //a[@x]:選擇具有 class屬性的 div節點、選擇具有 x屬性的 a節點
- //div[@class="container"]:選擇具有 class屬性的值為 container的 div節點
-
//a[contains(text(), "點")]:選擇文本內容里含有 “點” 的 a標簽,比如上面例子中的兩個 a標簽
-
//a[contains(@id, "abc")]:選擇 id屬性里有 abc的 a標簽,如
#這兩條 xpath規則都可以選取到例子中的兩個 a標簽 path = '//a[contains(@href, "#123")]' path = '//a[contains(@href, "#1233")]'
-
//a[contains(@y, "x")]:選擇有 y屬性且 y屬性包含 x值的 a標簽
-
總結
- 使用 xpath之前必須先對 html文檔進行處理
- html dom樹中所有的對象都是節點,包括文本,所以 text()其實就是獲取某個標簽下的文本節點
- 通過_Element對象的 xpath方法來使用 xpath
- 注意!!!_Element.xpath( path) 總是返回一個列表
有問題歡迎評論 ,順便給大家推薦一個資源很全的python學習免非解答.裙 :七衣衣九七七巴而五(數字的諧音)轉換下可以找到了,這里有資深程序員分享以前學習心得,學習筆記,還有一線企業的工作經驗,且給大家精心整理一份python零基礎到項目實戰的資料,每天給大家講解python最新的技術,前景,學習需要留言的小細節
本文的文字及圖片來源於網絡加上自己的想法,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理。