整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          實戰python爬蟲(三):XPath解析庫

          實戰python爬蟲(三):XPath解析庫

          上?章中, 我們基本上掌握了抓取整個??的基本技能。 但是呢, ?多數情況下, 我們并不需要整個??的內容, 只是需要那么??部分。怎么辦呢? 這就涉及到了數據提取的問題。

          本課程中, 提供三種解析?式:

          1. xpath解析
          2. bs4解析
          3. re解析

          這三種?式可以混合進?使?, 完全以結果做導向, 只要能拿到你想要的數據。 ?什么?案并不重要。 當你掌握了這些之后。 再考慮性能的問題。

          XPath是??在 XML ?檔中查找信息的語?, XPath可?來在 XML?檔中對元素和屬性進?遍歷,?我們熟知的HTML恰巧屬于XML的?個?集,所以完全可以?xpath去查找html中的內容。

          ?先, 先了解?個概念:

          在上述html中,

          1. book, id, name, price....都被稱為節點.

          2. Id, name, price, author被稱為book的?節點

          3. book被稱為id, name, price, author的?節點

          4. id, name, price,author被稱為同胞節點

          OK~ 有了這些基礎知識后, 我們就可以開始了解xpath的基本語法了

          在python中想要使?xpath,需要安裝lxml模塊。

          pip install lxml

          ?法:

          1. 將要解析的html內容構造出etree對象.

          2. 使?etree對象的xpath()?法配合xpath表達式來完成對數據的提取

          from lxml import etree
          html="""
          <book>
              <id>1</id>
              <name>野花遍地?</name>
              <price>1.23</price>
              <nick>臭?腐</nick>
              <author>
                  <nick id="10086">周?強</nick>
                  <nick id="10010">周芷若</nick>
                  <nick class="joy">周杰倫</nick>
                  <nick class="jolin">蔡依林</nick>
                  <div>
                      <nick>惹了</nick>
                  </div>
              </author>
              <partner>
              <nick id="ppc">胖胖陳</nick>
              <nick id="ppbc">胖胖不陳</nick>
              </partner>
          </book>
          """
          et=etree.XML(html)
          # 根據節點進?搜索
          # result=et.xpath("/book")
          # result=et.xpath("/book/id") # /在開頭表示?檔最開始, /在中間表示??
          # result=et.xpath("/book//nick") # //表示后代
          result=et.xpath("/book/*/nick") # *表示通配符
          print(result)

          xpath如何提取屬性信息. 我們上?段真實的HTML來給各位講解?下:

          <!DOCTYPE html>
          <html lang="en">
              <head>
                  <meta charset="UTF-8" />
                  <title>Title</title>
              </head>
              <body>
                  <ul>
                      <li><a href="http://www.baidu.com">百度
                      </a></li>
                      <li><a href="http://www.google.com">?
                      歌</a></li>
                      <li><a href="http://www.sogou.com">搜狗
                      </a></li>
                  </ul>
                  <ol>
                      <li><a href="feiji">?機</a></li>
                      <li><a href="dapao">?炮</a></li>
                      <li><a href="huoche">??</a></li>
                  </ol>
                  <div class="job">李嘉誠</div>
                  <div class="common">胡辣湯</div>
              </body>
          </html>


          from lxml import etree
          tree=etree.parse("1.html")
          result=tree.xpath("/html/body/ul/li/a/@href")
          print(result)
          result=tree.xpath("/html/body/ul/li")
          for li in result:
          print(li.xpath("./a/@href")) # 局部解析
          result=tree.xpath("//div[@class='job']/text()")
          # [@class='xxx']屬性選取 text()獲取?本
          print(result)

          實戰案例:

          一、58二手房標題

          #!/usr/bin/env python
          # -*- coding:utf-8 -*-
          from lxml import etree
          import requests
          if __name__=="__main__":
              headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3884.400 QQBrowser/10.8.4560.400'}
              url="https://bj.58.com/ershoufang/"
              page_text=requests.get(url,headers=headers).text
              tree=etree.HTML(page_text)
              titles=tree.xpath("//h3/text()")
              for title in titles:
                  print(title)
          
          

          ?

          二:彼岸壁紙下載

          #!/usr/bin/env python
          # -*- coding:utf-8 -*-
          from lxml import etree
          import requests
          import os
          if __name__=="__main__":
              headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3884.400 QQBrowser/10.8.4560.400'}
              url="https://pic.netbian.com/4kfengjing/"
              page_text=requests.get(url,headers=headers).text.encode("ISO-8859-1")
          
              tree=etree.HTML(page_text)
              li_list=tree.xpath('//div[@class="slist"]//li')
          
              if not os.path.exists("./piclibs"):
                  os.mkdir('./piclibs')
          
              for li in li_list:
                  img_src='https://pic.netbian.com/'+li.xpath('./a/img/@src')[0]
                  # print()
                  img_name=li.xpath('./a/img/@alt')[0]+'.jpg'
                  # print(img_name,img_src)
                  img_data=requests.get(url=img_src,headers=headers).content
                  img_path="piclibs/"+img_name
                  with open(img_path,"wb") as fp:
                      fp.write(img_data)
                      print(img_name,"下載成功")

          ?

          三、全國城市名稱爬取

          #!/usr/bin/env python
          # -*- coding:utf-8 -*-
          from lxml import etree
          import requests
          import os
          if __name__=="__main__":
              headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3884.400 QQBrowser/10.8.4560.400'}
              url="https://www.aqistudy.cn/historydata/"
              page_text=requests.get(url,headers=headers).text
          
              tree=etree.HTML(page_text)
              #全部城市
              all_city_list=tree.xpath('//div[@class="bottom"]//li')
              all_city_names=[]
              for li in all_city_list:
                  city_name=li.xpath("./a/text()")[0]
                  all_city_names.append(city_name)
                  for city in all_city_names:
                      print(city)
              # print(all_city_names)
          
              #熱門城市
              # hot_city_names=[]
              # hot_city_list=tree.xpath('//div[@class="hot"]//li')
              # for li in hot_city_list:
              #     city_name=li.xpath("./a/text()")[0]
              #
              #     hot_city_names.append(city_name)
              # print(hot_city_names)

          ?

          關注我:帶你從零開始學爬蟲。

          語言是一種古老且廣泛使用的編程語言,它擁有眾多第三方庫,為開發者提供了各種功能,從數據處理到網絡通信,再到圖形界面等。以下是一些流行的C語言第三方庫的詳細介紹:

          1. GLib - GLib是一個跨平臺的、用C語言編寫的實用工具庫。它提供了一系列的數據結構、算法、內存管理、文件操作等基礎功能。GLib是GTK+圖形用戶界面工具包的基礎,廣泛應用于Linux和其他類Unix系統的軟件開發中。GLib提供的主要功能包括:事件循環、動態數組、哈希表、字符串處理、時間操作、內存分配等。
          2. GNU Scientific Library (GSL) - GSL是一個用于數值計算的C語言庫,提供了廣泛的數學函數,如線性代數、特殊函數、隨機數生成等。GSL適用于科學和工程計算,其API設計注重數值穩定性和準確性。GSL提供的主要功能包括:線性代數(向量、矩陣運算)、數值積分、隨機數生成、統計運算、特殊函數(如伽瑪函數、貝塞爾函數)等。
          3. OpenSSL - OpenSSL是一個強大的加密庫,它為應用程序提供了一系列的加密和SSL/TLS功能。OpenSSL廣泛應用于網絡通信的安全,支持多種加密算法、密鑰交換協議和摘要算法。它還提供了命令行工具,用于生成密鑰、創建證書請求和證書等。OpenSSL的主要組件包括:加密庫(libcrypto)、SSL/TLS庫(libssl)、命令行工具(如openssl)等。
          4. SQLite - SQLite是一個輕量級的、嵌入式的數據庫引擎,它是一個C語言庫,提供了不需要服務器的、零配置的數據庫管理系統。SQLite支持標準的SQL語法,適用于移動應用、網站、桌面應用等場景。SQLite的主要特點包括:輕量級、單文件數據庫、無需獨立的服務器進程、支持事務、支持多種數據類型等。
          5. PCRE (Perl Compatible Regular Expressions) - PCRE是一個C語言編寫的正則表達式庫,它與Perl的正則表達式非常相似。PCRE被許多應用和編程語言用作正則表達式的處理引擎,支持多種字符編碼和正則表達式語法。PCRE的主要功能包括:正則表達式匹配、替換、分割等。
          6. FFmpeg - FFmpeg是一套可以用來記錄、轉換數字音視頻,并進行流媒體播放的完整的解決方案。它提供了多個庫,包括libavcodec、libavformat、libavutil等,用于處理多媒體數據。FFmpeg支持多種音視頻格式,可以用于開發媒體播放器、視頻編輯器等應用。FFmpeg的主要功能包括:編解碼(音視頻編解碼、圖像編解碼)、容器格式處理(如MP4、AVI、MKV等)、流媒體協議處理(如RTMP、HLS等)。
          7. cJSON - cJSON是一個輕量級的JSON解析庫,它用C語言編寫,易于使用和理解。cJSON適用于需要JSON數據交換的嵌入式系統,可以解析和生成JSON數據結構。cJSON的主要功能包括:JSON解析、JSON生成、JSON遍歷等。
          8. libxml2 - libxml2是一個用于解析和構建XML和HTML文檔的C語言庫,它提供了API用于處理XML數據,包括SAX、DOM和XPath等功能。libxml2廣泛應用于Web開發、文檔處理等領域。libxml2的主要功能包括:XML解析、XML生成、XPath查詢、XSLT轉換等。
          9. zlib - zlib是一個廣泛使用的壓縮和解壓縮庫,它提供了一種用于數據壓縮的DEFLATE算法的實現。zlib常用于網絡傳輸和文件壓縮,如HTTP協議中的deflate編碼、gzip文件格式等。zlib的主要功能包括:壓縮數據、解壓縮數據、流處理等。
          10. libpng - libpng是一個讀寫PNG圖像文件的C語言庫,它是PNG文件格式官方參考庫。與zlib一起使用,可以實現PNG圖像的壓縮和解壓縮。libpng廣泛應用于圖像處理、Web開發和游戲開發等領域。libpng的主要功能包括:PNG圖像讀取、PNG圖像寫入、PNG圖像處理等。
          11. FreeType - FreeType是一個用于渲染字體的高級庫,它支持多種字體格式,如TrueType、Type 1等。FreeType提供了API用于字體管理和文本渲染,廣泛應用于圖形界面、游戲開發、PDF文檔處理等領域。FreeType的主要功能包括:字體加載、字形渲染、字形變換等。
          12. SDL (Simple DirectMedia Layer) - SDL是一個跨平臺的C語言庫,用于開發游戲和多媒體應用程序。它提供了低層次的訪問音頻、鍵盤、鼠標、操縱桿和圖形硬件的接口。SDL廣泛應用于游戲開發、模擬器、多媒體工具等領域。SDL的主要功能包括:音頻播放、鍵盤輸入、鼠標輸入、圖形渲染等。

          這些庫只是C語言生態中的一部分,每個庫都有其特定的用途和優勢,為C語言開發者提供了強大的工具來創建高效、可靠的應用程序。這些庫的源代碼通常都是開放的,可以自由地使用、修改和分發,為C語言開發者提供了豐富的資源。

          除了上述的庫,還有許多其他的C語言第三方庫,如用于網絡編程的libcurl、用于圖像處理的OpenCV、用于數學計算的GNU MP等。這些庫各自都有其特點和用途,可以根據具體的應用場景選擇合適的庫。

          在C語言編程中,選擇合適的第三方庫可以幫助開發者提高開發效率,減少重復造輪子的工作,同時也可以提高應用程序的性能和可靠性。使用第三方庫還可以使應用程序更加模塊化,便于維護和升級。

          然而,使用第三方庫也需要考慮到一些問題,如庫的兼容性、穩定性、安全性等。因此,在選擇第三方庫時,應該盡量選擇成熟、活躍、社區支持良好的庫,并對其進行充分的測試和驗證。

          總之,C語言擁有豐富的第三方庫資源,這些庫為C語言開發者提供了強大的支持和便利。掌握這些庫的使用方法和技巧,可以幫助開發者更好地應對各種編程挑戰,提高開發效率和應用程序質量。

          xml是基于 libxml2解析庫的Python封裝。libxml2是使用C語言編寫的,解析速度很好,不過安裝起來稍微有點復雜。安裝說明可以參考(http: //Lxml.de/installation.html),在CentOS7上中文安裝說明(http://www.cjavapy.com/article/64/),使用lxml庫來解析網絡爬蟲抓取到的HTML是一種非常高效的方式。lxml的html模塊特別適合處理HTML內容,它可以快速解析大型HTML文件,并提供XPath和CSS選擇器來查詢和提取數據。

          參考文檔:https://www.cjavapy.com/article/65/

          一、可能不合法的html標簽解析

          從網絡上抓取到的html的內容,有可能都是標準寫法,標簽什么的都閉合,屬性也是標準寫法,但是有可能有的網站的程序員不專業,這樣抓到的html解析就有可能有問題,因此,解析時先將有可能不合法的html解析為統一的格式。避免為后續的解析造成困擾。

          1、lxml.html

          lxml.html是專門用于解析和處理HTML文檔的模塊。它基于lxml.etree,但是為HTML文檔的特點做了優化。lxml.html能夠處理不良形式的HTML代碼,這對于解析和爬取網頁尤其有用。

          >>> import lxml.html
          >>> broken_html='<ul class="body"><li>header<li>item</ul>'
          >>> tree=lxml.html.fromstring(broken_html) #解析html
          >>> fixed_html=lxml.html.tostring(tree,pretty_print=True)
          >>> print fixed_html
          <ul class="body">
          <li>header</li>
          <li>item</li>
          </ul>

          2、lxml.etree

          lxml.etree是lxml庫中用于處理XML文檔的模塊。它基于非常快的XML解析庫libxml2,提供了一個類似于標準庫xml.etree.ElementTreeAPI的接口,但是在性能和功能性方面要更加強大。lxml.etree支持XPath、XSLT、和Schema驗證等高級XML特性。

          >>> import lxml.etree
          >>> broken_html='<ul class="body"><li>header<li>item</ul>'
          >>> tree=lxml.etree.fromstring(broken_html) #解析html
          >>> fixed_html=lxml.etree.tostring(tree,pretty_print=True)
          >>> print fixed_html
          <ul class="body">
          <li>header</li>
          <li>item</li>
          </ul>

          通過以上可以看出,lxml可以正確解析兩側缺失的括號,并閉合標簽,但不會額外增加<html>和<body>標簽。

          二、處理lxml解析出來的html內容

          若在html中找到我們想要的內容,用lxml有幾種不同的方法,XPath選擇器類似Beautiful Soup的find()方法。CSS選擇器用法和jQuery中的選擇器類似。兩種選擇器都可以用來查找文檔中的元素,但它們各有特點和適用場景。XPath是一種在XML文檔中查找信息的語言。它可以用來遍歷XML文檔的元素和屬性。CSS選擇器通常用于選擇和操作HTML文檔中的元素。

          1、XPath選擇器(/單斜杠表示絕對查找,//雙斜杠表示相對查找)

          from lxml import etree
          source_html="""
                   <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(source_html)
          print(html)
          result=etree.tostring(html)#會對的html標簽進行補全
          print(result.decode("utf-8"))

          輸出結果:

          <Element html at 0x39e58f0>
          <html><body><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>
          </li></ul>
          </div>
          </body></html>

          1)獲取某個標簽的內容(a標簽后不需要加斜杠,否則會報錯)

          #第一種寫法

          html=etree.HTML(source_html)
          html_data=html.xpath('/html/body/div/ul/li/a')#絕對查找
          #html_data=html.xpath('//li/a')#相對查找
          print(html)
          for i in html_data:
              print(i.text)
          

          輸出結果:

          <Element html at 0x14fe6b8>
          first item
          second item
          third item
          fourth item
          fifth item

          #第二種寫法
          #在要找的標簽后面加/text(),就是獲取標簽中的文本內容,結果中直接就是文本內容了,不用在通過text屬性獲取了。

          html=etree.HTML(source_html)
          html_data=html.xpath('/html/body/div/ul/li/a/text()')#絕對查找
          #html_data=html.xpath('//li/a/text()')#相對查找
          print(html)
          for i in html_data:
              print(i)

          輸出結果:

          <Element html at 0x128e3b7>
          first item
          second item
          third item
          fourth item
          fifth item

          2)獲取a標簽下的屬性

          html=etree.HTML(source_html)
          html_data=html.xpath('//li/a/@href') #相對查找
          #html_data=html.xpath('/html/body/div/ul/li/a/@href') #絕對查找
          for i in html_data:
              print(i)
          

          輸出結果:

          link1.html
          link2.html
          link3.html
          link4.html
          link5.html

          3)查找a標簽屬性等于link2.html的內容

          html=etree.HTML(source_html)
          html_data=html.xpath('/html/body/div/ul/li/a[@href="link2.html"]/text()')絕對查找
          #html_data=html.xpath('//li/a[@href="link2.html"]/text()')#相對查找
          print(html_data)
          for i in html_data:
              print(i)
          

          輸出結果:

          ['second item']
          second item

          4)查找最后一個li標簽里的a標簽的href屬性

          html=etree.HTML(source_html)
          html_data=html.xpath('//li[last()]/a/text()')
          print(html_data)
          for i in html_data:
              print(i)
          

          輸出結果:

          ['fifth item']
          fifth item

          5)查找倒數第二個li標簽里a標簽的href屬性

          html=etree.HTML(source_html)
          html_data=html.xpath('//li[last()-1]/a/text()')
          print(html_data)
          for i in html_data:
              print(i)
          

          輸出結果:

          ['fourth item']
          fourth item

          6)查找某個標簽id屬性值等于value的標簽

          //*[@id="value"]

          7)使用chrome瀏覽器提取某個標簽的XPath

          2、CSS選擇器(基本上和jQuery選擇器用法一樣)

          選擇器

          描述

          *

          選擇所有標簽

          a

          選擇<a>標簽

          .link

          選擇所有class='link'的元素

          a.link

          選擇class='link'的<a>標簽

          a#home

          選擇id='home'的<a>標簽

          a > span

          選擇父元素為<a>標簽的所有<span>子標簽

          a span

          選擇<a>標簽內部的所有<span>標簽

          使用示例:

          >>> html="""<div>
          <tr id="places_area_row" class="body">
          <td>header</td>
          <td class="w2p_fw">item1</td>
          <td class="w2p_fw">item2</td>
          <td class="w2p_fw">item3</td>
          <td><tr><td class="w2p_fw">header</td>
          <td class="w2p_fw">item4</td>
          <td class="w2p_fw">item5</td>
          <td class="w2p_fw">item6</td></tr></td>
          </tr>
          </div>"""
          >>> tree=lxml.html.fromstring(html)
          >>> td=tree.cssselect('tr#places_area_row > td.w2p_fw')[0]
          >>> htmlText=td.text_content()
          >>> print htmlText
          item1

          參考文檔:https://www.cjavapy.com/article/65/

          ?


          主站蜘蛛池模板: 蜜臀AV免费一区二区三区| 国精品无码A区一区二区| 久久精品免费一区二区三区| 国产另类TS人妖一区二区 | www.亚洲一区| 免费萌白酱国产一区二区三区| 亚洲乱色熟女一区二区三区丝袜| 日韩精品无码免费一区二区三区| 亚洲熟女综合一区二区三区| 日本中文一区二区三区亚洲| 夜夜添无码试看一区二区三区| 国产精品一区二区久久国产| 无码中文人妻在线一区二区三区| 天海翼一区二区三区高清视频| 日本精品3d动漫一区二区| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久精品无码一区二区三区日韩| 中文字幕一区日韩在线视频| 无码AV天堂一区二区三区| 国产成人一区二区三中文| 日本韩国一区二区三区| 国产精品免费综合一区视频| 后入内射国产一区二区| 杨幂AV污网站在线一区二区| 日本丰满少妇一区二区三区| 国产AⅤ精品一区二区三区久久| 波多野结衣的AV一区二区三区| 久久国产午夜一区二区福利| 成人免费观看一区二区| 国产凸凹视频一区二区| 中文字幕Av一区乱码| 中文字幕人妻AV一区二区| 日韩精品久久一区二区三区 | 午夜福利国产一区二区| 久久精品国产亚洲一区二区| 中文字幕无线码一区二区 | 精品国产AV无码一区二区三区| 亚洲免费视频一区二区三区| 色婷婷一区二区三区四区成人网| 日韩精品一区在线| 国产在线无码一区二区三区视频|