整合營銷服務商

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

          免費咨詢熱線:

          Python: 爬蟲網頁解析工具lxml.html(一)

          義上講,爬蟲只負責抓取,也就是下載網頁。而實際上,爬蟲還要負責從下載的網頁中提取我們想要的數據,即對非結構化的數據(網頁)進行解析提取出結構化的數據(有用數據)。

          所以說,網頁下載下來只是第一步,還有重要的一步就是數據提取。不同的爬蟲想要的數據不一樣,提取的數據也就不一樣,但提取方法都是類似的。

          最簡單的提取數據的方法,就是使用正則表達式,此種方法簡單,提取的邏輯也不能復雜,不然寫出的正則表達式就晦澀難懂,甚至不能提取復雜的數據結構。

          最終,老猿經過多年的使用經驗,選擇了lxml和xpath來解析網頁提取結構化數據。順便說一下 BeautifulSoup,它也是一個很棒的解析HTML的工具,可以使用多個解析器,比如Python標準庫的parser,但是速度比較慢,也可以使用lxml作為解析器,但是它的使用方法、API跟lxml不太一樣。使用下來,還是lxml的API更舒服。

          lxml 對C語言庫 libxml2和 libxslt進行綁定,提供了Pythonic的API,它有一些主要特點:

          • 支持標準的XML
          • 支持(損壞)的HTML
          • 非常快的解析速度
          • Pythonic的API更易于使用
          • 使用Python的unicode字符串
          • 內存安全(沒有段錯誤)
          • 不需要手動管理內存

          總結為一句話就是,C語言的速度和Python的簡易相結合的神器。

          lxml有兩大部分,分別支持XML和HTML的解析:

          • lxml.etree 解析XML
          • lxml.html 解析html

          lxml.etree可以用來解析RSS feed,它就是一個XML格式的文檔。然而爬蟲抓取的絕大部分都是html網頁,所以,我們這里主要講述lxml.html解析網頁的方法。

          lxml.html 從html字符串生成文檔樹結構

          我們下載得到的網頁就是一串html字符串,如何把它輸入給lxml.html模塊,從而生成html文檔的樹結構呢?

          該模塊提供了幾種不同的方法:

          • parse(filename_url_or_file):
          • 輸入的是一個文件名、URL或文件對象(有read()方法)。
          • document_fromstring(string):
          • 輸入的是一個html的字符串,創建一個HTML文檔樹結構,它的根節點就是, 和 子節點。
          • fragment_fromstring(string, create_parent=False):
          • 返回輸入字符串的HTML片段。這個片段壁紙只含有一個element(元素),也就是單一節點,除非給出了create_parent 參數,否則會報錯。
          • fragments_fromstring(string):
          • 返回包含輸入字符串中所有片段的列表。
          • fromstring(string):
          • 返回值依據輸入字符串而定,如果輸入看起來像是一個文檔,則返回document_fromstring(string),如果是一個單一片段,則返回fragment_fromstring(string)。

          下面我們通過具體示例來說明上面幾個方法的不同。

          document_fromstring 的使用方法

          In [1]: import lxml.html as lh
          In [2]: z = lh.document_fromstring('<span>abc</span><span>xyz</span>')
          # 可以看到,它自動加了根節點<html>
          In [3]: z
          Out[3]: <Element html at 0x7fc410667b88>
          In [4]: z.tag
          Out[4]: 'html'
          # 還加了<body>節點
          In [5]: z.getchildren()
          Out[5]: [<Element body at 0x7fc4101a3ae8>]
          # 把字符串的兩個節點放在了<body>里面
          In [6]: z.getchildren()[0].getchildren()
          Out[6]: [<Element span at 0x7fc410092bd8>, <Element span at 0x7fc410667c28>]
          

          fragment_fromstring 的使用

          In [11]: z = lh.fragment_fromstring(‘<div>abc</div><div>xyz</div>’)
          ---------------------------------------------------------------------------
          ParserError Traceback (most recent call last)
          <ipython-input-11-a11f9a0f71d1> in <module>()
          ----> 1 z = lh.fragment_fromstring(‘<div>abc</div><div>xyz</div>’)
          ~/.virtualenvs/py3.6/lib/python3.6/site-packages/lxml/html/__init__.py in fragment_fromstring(html, create_parent, base_url, parser, **kw)
           850 raise etree.ParserError(
           851 “Multiple elements found (%s)”
          --> 852 % ‘, ‘.join([_element_name(e) for e in elements]))
           853 el = elements[0]
           854 if el.tail and el.tail.strip():
          ParserError: Multiple elements found (div, div)
          # 可以看到,輸入是兩個節點(element)時就會報錯
          # 如果加上 create_parent 參數,就沒問題了
          In [12]: z = lh.fragment_fromstring('<div>abc</div><div>xyz</div>', create_parent='p')
          In [13]: z.tag
          Out[13]: 'p'
          In [14]: z.getchildren()
          Out[14]: [<Element div at 0x7fc40a41a818>, <Element div at 0x7fc40a41aea8>]
          

          fragments_fromstring 的使用

          # 輸入字符串含有一個節點,則返回包含這一個節點的列表
          In [17]: lh.fragments_fromstring('<div>abc</div>')
          Out[17]: [<Element div at 0x7fc40a124ea8>]
          # 輸入字符串含有多個節點,則返回包含這多個節點的列表
          In [18]: lh.fragments_fromstring('<div>abc</div><div>xyz</div>')
          Out[18]: [<Element div at 0x7fc40a124b88>, <Element div at 0x7fc40a124f98>]
          

          fromstring 的使用

          In [27]: z = lh.fromstring('<div>abc</div><div>xyz</div>')
          In [28]: z
          Out[28]: <Element div at 0x7fc40a0eb368>
          In [29]: z.getchildren()
          Out[29]: [<Element div at 0x7fc410135548>, <Element div at 0x7fc40a0eb2c8>]
          In [30]: type(z)
          Out[30]: lxml.html.HtmlElement
          

          這里,fromstring輸入的如果是多個節點,它會給加一個父節點并返回。但是像html網頁都是從節點開始的,我們使用fromstring() 和 document_fromstring() 都可以得到完整的網頁結構。

          從上面代碼中我們可以看到,那幾個函數返回的都是HtmlElement對象,也就是說,我們已經學會了如何從html字符串得到HtmlElement的對象,下一節我們將學習如何操作HtmlElement對象,從中提取我們感興趣的數據。

          發送HTTP請求:首先,你需要向目標網頁發送HTTP請求以獲取其HTML內容。這可以通過Java的內置庫java.net.HttpURLConnection或者使用更高級的庫如Apache Http Client OkHttp等來完成。

          ·讀取響應內容:一旦你發送了請求并收到了響應,你需要讀取響應的內容,這通常是HTML格式的字符串。

          ·解析HTML:然后,你需要解析HTML字符串以提取所需的信息,這可以通過正則表達式來完成。但通常建議使用專門的HTML解析庫,如Jsoup。Jsoup提供了一種非常方便的方式來解析HTML文檔,并可以通過類似于CSS或jQuery的選擇器語法來提取和操作數據。

          ·如果你需要處理更復雜的網頁或進行更高級的網頁抓取和解析任務,你可能還需要考慮使用如Selenium這樣的瀏覽器自動化工具來模擬真實的瀏覽器行為。但是請注意,頻繁或大規模地抓取網頁可能會違反網站的使用條款甚至可能構成法律問題。

          解析HTML文檔,可以使用一些編程語言中的HTML解析庫或工具。以下是一些常用的方法:

          1. 使用Python中的BeautifulSoup庫:BeautifulSoup是一個功能強大的HTML解析庫,可以幫助你從HTML文檔中提取數據。你可以使用pip安裝BeautifulSoup,然后使用它的解析器來解析HTML文檔。
          from bs4 import BeautifulSoup
          
          # 讀取HTML文檔
          with open('example.html', 'r') as file:
              html = file.read()
          
          # 創建BeautifulSoup對象
          soup = BeautifulSoup(html, 'html.parser')
          
          # 使用BeautifulSoup對象提取數據
          # 例如,提取所有的鏈接
          links = soup.find_all('a')
          for link in links:
              print(link.get('href'))
          
          1. 使用JavaScript中的DOM解析器:如果你在瀏覽器環境中,可以使用JavaScript的DOM解析器來解析HTML文檔。你可以使用document對象來訪問和操作HTML元素。
          // 讀取HTML文檔
          var html = document.documentElement.innerHTML;
          
          // 使用DOM解析器提取數據
          // 例如,提取所有的鏈接
          var links = document.getElementsByTagName('a');
          for (var i = 0; i < links.length; i++) {
              console.log(links[i].getAttribute('href'));
          }
          
          1. 使用其他編程語言的HTML解析庫:除了Python和JavaScript,還有許多其他編程語言也有自己的HTML解析庫,例如Java中的Jsoup、Ruby中的Nokogiri等。你可以根據自己的編程語言選擇適合的HTML解析庫來解析HTML文檔。

          無論你選擇哪種方法,解析HTML文檔的關鍵是了解HTML的結構和標簽,并使用相應的解析器或工具來提取所需的數據。

          當你解析HTML文檔時,你可能會遇到以下一些常見的任務和技術:

          1. 選擇器:使用選擇器可以方便地定位和提取HTML文檔中的特定元素。例如,你可以使用CSS選擇器來選擇具有特定類名或ID的元素,或者使用XPath來選擇具有特定屬性或層次結構的元素。
          2. 提取數據:一旦你定位到了要提取的元素,你可以使用相應的方法或屬性來獲取元素的文本內容、屬性值或其他相關信息。例如,你可以使用getText()方法來獲取元素的文本內容,使用getAttribute()方法來獲取元素的屬性值。
          3. 遍歷文檔:HTML文檔通常是一個樹狀結構,你可以使用遍歷方法來訪問和操作文檔中的不同元素。例如,你可以使用遞歸或循環來遍歷文檔的子元素、父元素或兄弟元素。
          4. 處理嵌套結構:HTML文檔中的元素可能會有嵌套的結構,你需要處理這些嵌套關系來正確地提取數據。例如,你可以使用遞歸方法來處理嵌套的列表、表格或嵌套的div元素。
          5. 處理特殊情況:在解析HTML文檔時,可能會遇到一些特殊情況,例如處理動態生成的內容、處理特殊字符或處理錯誤的HTML結構。你需要根據具體情況選擇合適的方法來處理這些特殊情況。

          總的來說,解析HTML文檔需要一定的HTML知識和編程技巧。你需要了解HTML的結構和標簽,選擇合適的解析器或工具,使用選擇器來定位元素,提取所需的數據,并處理特殊情況。通過不斷練習和實踐,你將能夠更熟練地解析HTML文檔并提取所需的數據。


          主站蜘蛛池模板: 久久精品中文字幕一区| 性色av一区二区三区夜夜嗨| 免费高清在线影片一区| 国模吧无码一区二区三区| 国产精品538一区二区在线| 亚洲av无码一区二区三区天堂 | 日韩精品无码一区二区中文字幕| 久久久久国产一区二区三区| 免费萌白酱国产一区二区| 精品国产一区二区三区av片| 亚洲精品无码一区二区| 亚洲精品国产suv一区88| 国产高清在线精品一区| 久久亚洲日韩精品一区二区三区 | 中文字幕在线无码一区二区三区| 丰满人妻一区二区三区视频| 精品无码一区二区三区水蜜桃| 日韩视频在线一区| 国产精品久久久久一区二区| 欧洲亚洲综合一区二区三区| 日本在线视频一区二区三区| 国产高清视频一区二区| 国产一区二区三区四| 美女视频一区二区三区| 福利片福利一区二区三区| 一区二区三区观看| 中文字幕无码一区二区免费 | 中文字幕久久久久一区| 丝袜人妻一区二区三区网站| 国产一区二区三区在线视頻| 国产伦理一区二区| 午夜影视日本亚洲欧洲精品一区 | 综合人妻久久一区二区精品| 久草新视频一区二区三区| 久久精品一区二区三区资源网| 日韩人妻精品无码一区二区三区 | 久久精品无码一区二区app| 国产成人久久精品麻豆一区| 久久亚洲中文字幕精品一区四| 国内精品无码一区二区三区| 性色av一区二区三区夜夜嗨 |