小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

python爬蟲(chóng)系列之 xpath:html解析神器

 看見(jiàn)就非常 2020-05-08

一、前言

通過(guò)前面的文章,我們已經(jīng)知道了如何獲取網(wǎng)頁(yè)和下載文件,但是前面我們獲取的網(wǎng)頁(yè)都是未經(jīng)處理的,冗余的信息太多,無(wú)法進(jìn)行分析和利用

這一節(jié)我們就來(lái)學(xué)習(xí)怎么從網(wǎng)頁(yè)中篩選自己需要的信息

說(shuō)到信息篩選我們立馬就會(huì)想到正則表達(dá)式,不過(guò)今天我們不講正則表達(dá)式。因?yàn)閷?duì)于爬蟲(chóng)來(lái)講,正則表達(dá)式太復(fù)雜對(duì)新手十分不友好,而且正則表達(dá)式的容錯(cuò)率差,網(wǎng)頁(yè)有稍微的改動(dòng)就得重新寫(xiě)匹配表達(dá)式,另外正則表達(dá)式可讀性幾乎沒(méi)有。

當(dāng)然,這并不是說(shuō)正則不好,只是正則不適合爬蟲(chóng)和新手。其實(shí)正則是十分強(qiáng)大的,在后面的數(shù)據(jù)清洗里我們會(huì)用到正則。

既然正則不能用,那該用什么呢?別擔(dān)心,python為我們提供了很多解析 html頁(yè)面的庫(kù),其中常用的有:

  • bs4中的 BeautifulSoup

  • lxml中的 etree(一個(gè) xpath解析庫(kù))

BeautifulSoup類似 jQuery的選擇器,通過(guò) id、css選擇器和標(biāo)簽來(lái)查找元素,xpath主要通過(guò) html節(jié)點(diǎn)的嵌套關(guān)系來(lái)查找元素,和文件的路徑有點(diǎn)像,比如:

#獲取 id為 tab的 table標(biāo)簽下所有 tr標(biāo)簽
path = '//table[@id="tab"]//tr'
#和文件路徑對(duì)比
path = 'D:\Github\hexo\source\_posts'

BeautifulSoup和 xpath沒(méi)有好壞優(yōu)劣之分,講 xpath是因?yàn)閭€(gè)人覺(jué)得 xpath更好用一些,后面如果時(shí)間允許的話再講 BeautifulSoup。

現(xiàn)在,讓我們先從 xpath開(kāi)始!

二、xpath的安裝和使用

  1. 安裝 lxml庫(kù)
    pip install lxml
  2. 簡(jiǎn)單的使用

    在使用 xpath之前,先導(dǎo)入 etree類,對(duì)原始的 html頁(yè)面進(jìn)行處理獲得一個(gè)_Element對(duì)象

    我們可以通過(guò)_Element對(duì)象來(lái)使用 xpath

    #導(dǎo)入 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">
                                        點(diǎn)擊我
                                    </a>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>'''
    
    #對(duì) html文本進(jìn)行處理 獲得一個(gè)_Element對(duì)象
    dom = etree.HTML(html)
    
    #獲取 a標(biāo)簽下的文本
    a_text = dom.xpath('//div/div/div/div/div/a/text()')
    
    print(a_text)

    打印結(jié)果:

    result-1

    熟悉 html的朋友都知道在 html中所有的標(biāo)簽都是節(jié)點(diǎn)。一個(gè) html文檔是一個(gè)文檔節(jié)點(diǎn),一個(gè)文檔節(jié)點(diǎn)包含一個(gè)節(jié)點(diǎn)樹(shù),也叫做 dom樹(shù)。

    節(jié)點(diǎn)樹(shù)中的節(jié)點(diǎn)彼此擁有層級(jí)關(guān)系。

    父(parent)、子(child)和同胞(sibling)等術(shù)語(yǔ)用于描述這些關(guān)系。父節(jié)點(diǎn)擁有子節(jié)點(diǎn)。同級(jí)的子節(jié)點(diǎn)被稱為同胞(兄弟或姐妹)。

    from w3school:http://www.w3school.com.cn/htmldom/dom_nodes.asp

    另外,我們把距離某個(gè)節(jié)點(diǎn)最近的子節(jié)點(diǎn)叫做它的直接子節(jié)點(diǎn),如下圖所示的 body和 head就是 html的直接子節(jié)點(diǎn)

    dom樹(shù) w3school

    了解了 html結(jié)構(gòu)之后我們?cè)賮?lái)看 xpath的使用。

    首先,我們通過(guò) etree.HTML( )來(lái)生成一個(gè)_Element對(duì)象,etree.HTML() 會(huì)將傳入的文本處理成一個(gè) html文檔節(jié)點(diǎn)。這樣就能保證我們總是能獲得一個(gè)包含文檔節(jié)點(diǎn)的_Element對(duì)象。

    • 在節(jié)點(diǎn)樹(shù)中,頂端節(jié)點(diǎn)被稱為根(root)

    • 每個(gè)節(jié)點(diǎn)都有父節(jié)點(diǎn)、除了根(它沒(méi)有父節(jié)點(diǎn))

    • 一個(gè)節(jié)點(diǎn)可擁有任意數(shù)量的子

    • 同胞是擁有相同父節(jié)點(diǎn)的節(jié)點(diǎn)

  3. xpath語(yǔ)法
    • //div[@classs], //a[@x]:選擇具有 class屬性的 div節(jié)點(diǎn)、選擇具有 x屬性的 a節(jié)點(diǎn)

    • //div[@class="container"]:選擇具有 class屬性的值為 container的 div節(jié)點(diǎn)

    • a / b :‘/’在 xpath里表示層級(jí)關(guān)系,左邊的 a是父節(jié)點(diǎn),右邊的 b是子節(jié)點(diǎn),這里的 b是 a的直接子節(jié)點(diǎn)

    • a // b:兩個(gè) / 表示選擇所有 a節(jié)點(diǎn)下的 b節(jié)點(diǎn)(可以是直接子節(jié)點(diǎn),也可以不是),在上面的例子中我們要選擇 a標(biāo)簽是這樣寫(xiě)的

      a_text = dom.xpath('//div/div/div/div/div/a/text()')
      #用 //
      a_text = dom.xpath('//div//a/text()')
      #如果 div標(biāo)簽下有兩個(gè) a標(biāo)簽,那么這兩個(gè) a標(biāo)簽都會(huì)被選擇(注意兩個(gè) a標(biāo)簽并不一定是兄弟節(jié)點(diǎn))
      #比如下面的例子中的兩個(gè) a標(biāo)簽都會(huì)被選擇 因?yàn)檫@兩個(gè) a標(biāo)簽都是 div的子節(jié)點(diǎn)
             '''<div class="container">
                      <div class="row">
                          <div class="col">
                              <div class="card">
                                 <a href="#123332" class="box">
                                          點(diǎn)擊我
                                  </a>
                                  <div class="card-content">
                                      <a href="#123333" class="box">
                                          點(diǎn)擊我
                                      </a>
                                  </div>
                              </div>
                          </div>
                      </div>
                  </div>'''
    • [@]:選擇具有某個(gè)屬性的節(jié)點(diǎn)

    • //a[contains(text(), "點(diǎn)")]:選擇文本內(nèi)容里含有 “點(diǎn)” 的 a標(biāo)簽,比如上面例子中的兩個(gè) a標(biāo)簽

    • //a[contains(@id, "abc")]:選擇 id屬性里有 abc的 a標(biāo)簽,如

      #這兩條 xpath規(guī)則都可以選取到例子中的兩個(gè) a標(biāo)簽
      path = '//a[contains(@href, "#123")]'
      path = '//a[contains(@href, "#1233")]'
    • //a[contains(@y, "x")]:選擇有 y屬性且 y屬性包含 x值的 a標(biāo)簽

總結(jié)

  1. 使用 xpath之前必須先對(duì) html文檔進(jìn)行處理

  2. html dom樹(shù)中所有的對(duì)象都是節(jié)點(diǎn),包括文本,所以 text()其實(shí)就是獲取某個(gè)標(biāo)簽下的文本節(jié)點(diǎn)

  3. 通過(guò)_Element對(duì)象的 xpath方法來(lái)使用 xpath

  4. 注意!?。Element.xpath( path) 總是返回一個(gè)列表

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多