<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          快速入門(mén)XPath語(yǔ)法,輕松解析爬蟲(chóng)時(shí)的HTML內(nèi)容

          共 5891字,需瀏覽 12分鐘

           ·

          2022-08-11 22:21

          爬蟲(chóng)時(shí),很多網(wǎng)站返回的是HTML文件,可以用正則表達(dá)式(re庫(kù))或XPath語(yǔ)法來(lái)匹配目標(biāo)內(nèi)容,這兩種方法屬于爬蟲(chóng)的基本技能,實(shí)戰(zhàn)中要會(huì)靈活運(yùn)用。


          對(duì)于一些結(jié)構(gòu)和內(nèi)容復(fù)雜的HTML,用re匹配會(huì)感覺(jué)力不從心,XPath可以解決我們的煩惱。


          本文的內(nèi)容可以幫助你快速入門(mén)XPath語(yǔ)法,當(dāng)需要使用時(shí),對(duì)照本文的語(yǔ)法和偽代碼,可以快速寫(xiě)出正確的XPath代碼,提取到目標(biāo)內(nèi)容。


          HTML、XML、XPath簡(jiǎn)介



          • HTML是Hyper Text Markup Language(超文本標(biāo)記語(yǔ)言)的縮寫(xiě),我們?cè)跒g覽器中看到的內(nèi)容都是HTML代碼經(jīng)過(guò)瀏覽器渲染的結(jié)果。


          • XML是EXtensible Markup Language(可擴(kuò)展標(biāo)記語(yǔ)言)的縮寫(xiě),XML是一種很類(lèi)似HTML的標(biāo)記語(yǔ)言,不過(guò)XML的設(shè)計(jì)宗旨是傳輸數(shù)據(jù),而非顯示數(shù)據(jù)。


          XML的標(biāo)簽我們可以自行定義,具有自我描述性。我們可以根據(jù)XML中的標(biāo)簽來(lái)獲取對(duì)應(yīng)的數(shù)據(jù)。


          • XPath是XML Path Language(XML路徑語(yǔ)言)的縮寫(xiě),是一門(mén)在XML文檔中查找信息的語(yǔ)言,用來(lái)提取XML文檔中的元素和屬性。


          用XPath語(yǔ)言獲取HTML中的內(nèi)容時(shí),先將HTML轉(zhuǎn)換成XML文檔,然后根據(jù)XML的樹(shù)形結(jié)構(gòu)來(lái)定位到指定的元素和屬性,提取數(shù)據(jù)。如果有數(shù)據(jù)結(jié)構(gòu)樹(shù)的基礎(chǔ)知識(shí),理解起來(lái)很容易。


          本文只分別用了一句話簡(jiǎn)短介紹,HTML、XML和樹(shù)的知識(shí)可以自己擴(kuò)展。


          XPath語(yǔ)法介紹



          XPath使用路徑表達(dá)式來(lái)選取XML文檔中的節(jié)點(diǎn)或者節(jié)點(diǎn)集。


          路徑表達(dá)式:


          nodename   選取此節(jié)點(diǎn)的所有子節(jié)點(diǎn)。
          /   從根節(jié)點(diǎn)選取。正斜杠也是路徑分隔符。
          //  從任意位置選取文檔中的節(jié)點(diǎn)。
          .   選取當(dāng)前節(jié)點(diǎn)。
          ..  選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)。
          @   選取當(dāng)前節(jié)點(diǎn)的屬性


          這些路徑表達(dá)式和我們?cè)诔R?guī)的電腦文件系統(tǒng)中看到的表達(dá)式非常相似。


          假如路徑起始于正斜杠( / ),則此路徑代表到某元素的絕對(duì)路徑。


          通配符:


          *    任意元素。
          @*   任意屬性。
          node()  任意子節(jié)點(diǎn)(元素,屬性,內(nèi)容)。


          XPath的通配符可用來(lái)選取未知的XML元素。


          謂語(yǔ):


          //a[n] n為1開(kāi)始的整數(shù),選取排在第n個(gè)位置的<a>元素。
          //a[last()] last()表示選取排在最后位置的<a>元素。
          //a[last()-1] 和上面同理,表示選取倒數(shù)第二個(gè)<a>元素。
          //a[position()<3] 選取第一個(gè)和第二個(gè)<a>元素。
          //a[@href] 選取擁有href屬性的<a>元素。
          //a[@href='www.baidu.com'] 選取href屬性值為'www.baidu.com'的<a>元素。
          //a[@price>10] 選取price屬性值大于10的<a>元素。
          //a[@price>10]/span  選取price屬性值大于10的<a>元素下的<span>元素。


          謂語(yǔ)用來(lái)查找某個(gè)特定的節(jié)點(diǎn),或包含某個(gè)指定值的節(jié)點(diǎn),語(yǔ)法寫(xiě)在元素名后的方括號(hào)中,可以寫(xiě)元素的位置編號(hào)、函數(shù)、用@選取屬性等。


          選取多個(gè)路徑:


          //book/title | //book/price  選取<book>元素的所有<title>和<price>元素。
          //title | //price  選取所有<title>和<price>元素。
          /bookstore/book/title | //price  選取屬于<bookstore>元素的<book>元素的所有<title>元素,以及所有的<price>元素。


          選取多個(gè)路徑時(shí),使用“|”運(yùn)算符表示“或”的關(guān)系。


          運(yùn)算符:


          + - * div 加減乘除。
          = != 等于,不等于。
          < <= 小于,小于等于。
          > >= 大于,大于等于。
          or and  或,與
          mod   計(jì)算余數(shù)


          運(yùn)算符基本都是運(yùn)用在謂語(yǔ)中,幫助我們選取指定元素。


          常用函數(shù):


          contains(@屬性,string) 選取屬性里包含字符串string的元素。
          text()  獲取元素中的內(nèi)容。
          last()  選取最后一個(gè)元素。
          position() 用于選取多個(gè)元素中某些位置(數(shù)字編號(hào))的元素。
          count()  返回元素的數(shù)量。
          max() 返回最大的元素,min(),avg(),sum()同理。


          函數(shù)也基本都是運(yùn)用在謂語(yǔ)中,幫助我們選取指定元素。


          lxml庫(kù)使用



          lxml是Python中用來(lái)解析HTML/XML的第三方庫(kù),lxml的主要功能是生成一個(gè)解析器,解析和提取HTML/XML中的數(shù)據(jù)。


          先用lxml生成解析器,然后用XPath語(yǔ)法從解析器中提取HTML/XML中的內(nèi)容。


          • 安裝命令:


          pip install lxml


          • 實(shí)戰(zhàn)演練:


          # coding=utf-8
          from lxml import etree

          text = '''
          <!DOCTYPE html>
          <html>
          <head>
              <title>XPath Test(公眾號(hào):小斌哥ge)</title>
          </head>
          <body>
          <div>
              <ul>
                   <li id="1" class="item"><a href="link1.html">first item</a></li>
                   <li id="2" class="item"><a href="link2.html">second item</a></li>
                   <li id="3" class="item-inactive"><a href="link3.html">third item</a></li>
                   <li id="4" class="project"><a href="link4.html">first project</a></li>
                   <li id="5" class="project"><a href="link5.html">second project</a></li>
              </ul>
          </div>
          </body>
          </html>
          '''

          # 利用etree.HTML,將字符串解析為HTML文檔
          html = etree.HTML(text)
          # 讀取html文件
          # html = etree.parse('test.html')
          print(html)
          # 按字符串序列化HTML文檔
          result = etree.tostring(html, pretty_print=True)
          print(result)
          <Element html at 0x1c3be4c9740>
          b'<html>\n
          <head>\n<title>XPath Test</title>\n</head>\n
          <body>\n<div>\n
          <ul>\n
          <li id="1" class="item"><a href="link1.html">first item</a></li>\n
          <li id="2" class="item"><a href="link2.html">second item</a></li>\n
          <li id="3" class="item-inactive"><a href="link3.html">third item</a></li>\n
          <li id="4" class="project"><a href="link4.html">first project</a></li>\n
          <li id="5" class="project"><a href="link5.html">second project</a></li>\n
          </ul>\n
          </div>\n</body>\n
          </html>\n'


          使用from lxml import etree從lxml庫(kù)中導(dǎo)入etree解析器,利用etree.HTML將HTML格式的字符串解析成樹(shù)狀的結(jié)構(gòu),然后用XPath語(yǔ)法從中提取數(shù)據(jù)。


          爬蟲(chóng)獲取到的HTML內(nèi)容一般是response.text中返回的,可以用etree.HTML解析,也可以用etree.parse解析本地的HTML文件。


          直接打印etree.HTML或etree.parse解析的結(jié)果是一個(gè)Element對(duì)象,可以用etree.tostring將Element中的內(nèi)容序列化,打印出來(lái)。


          • 用XPath從解析器中提取數(shù)據(jù):


          # 獲取所有class屬性值為'item'的<li>元素
          infos = html.xpath("http://li[@class='item']")
          print(infos)
          [<Element li at 0x25951272840>, <Element li at 0x25951272780>]


          # 獲取所有class屬性中包含'pro'字符串的<li>元素
          infos = html.xpath("http://li[contains(@class, 'pro')]")
          for info in infos:
              # 獲取<li>元素中<a>元素的文本內(nèi)容
              print(info.xpath("a/text()"))
          ['first project']
          ['second project']


          # 獲取倒數(shù)第二個(gè)<li>元素下的最后一個(gè)<a>元素
          info = html.xpath("http://li[last()-1]/a[last()]")
          # 打印<a>元素的內(nèi)容
          print(info[0].text)
          first project


          # 獲取前三個(gè)<li>元素下的<a>元素的內(nèi)容
          infos = html.xpath("http://li[position()<4]/a/text()")
          for info in infos:
              # 打印<a>元素的文本內(nèi)容
              print(info)
          first item
          second item
          third item


          以上就是本文的全部?jī)?nèi)容,如果本文可以幫助你快速入門(mén)XPath語(yǔ)法,歡迎點(diǎn)贊、收藏、在看,也可以關(guān)注和聯(lián)系我一起交流討論。


          參考文檔: 

          [1] XML W3School官方文檔:http://www.w3school.com.cn/xml/index.asp

          [2] XPath W3School官方文檔:http://www.w3school.com.cn/xpath/index.asp

          [3] lxml Python官方文檔:http://lxml.de/index.html

          瀏覽 23
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天噜天天射天天日 | 五月婷婷人人操 | 操逼操逼操逼操逼 | а中文在线天堂 | www.骚 |