外行學 Python 爬蟲 第三篇 內容解析

從網絡上獲取網頁內容以後,需要從這些網頁中取出有用的信息,畢竟爬蟲的職責就是獲取有用的信息,而不僅僅是爲了下來一個網頁。獲取網頁中的信息,首先需要指導網頁內容的組成格式是什麼,沒錯網頁是由 HTML「我們成爲超文本標記語言,英語:HyperText Markup Language,簡稱:HTML」 組成的,其次需要解析網頁的內容,從中提取出我們想要的信息。

HTML

超文本標記語言(英語:HyperText Markup Language,簡稱:HTML)是一種用於創建網頁的標準標記語言。HTML是一種基礎技術,常與CSS、JavaScript一起被衆多網站用於設計網頁、網頁應用程序以及移動應用程序的用戶界面[3]。網頁瀏覽器可以讀取HTML文件,並將其渲染成可視化網頁。HTML描述了一個網站的結構語義隨着線索的呈現,使之成爲一種標記語言而非編程語言。

以上內容摘自維基百科,它將網頁的組成做了一個簡單且明確的解釋,從中我們知道 HTML、CSS、JavaScript 是一個網頁的重要組成部分。但是對於一個爬蟲來說它需要關注的僅僅只是 HTML,無需過多關注 CSS 和 JavaScript。

CSS 用於網頁的顯示格式,爬蟲不關注顯示的格式。JavaScript 主要用於動態加載內容,當前可暫不關注。

HTML 文檔主要有 HTML 元素「或者標籤」組成,常用的 HTML 標籤主要有以下幾種:

  1. <html> 用來定義一個 HTML 文檔。
  2. <head> 用來定義 HTML 文檔的信息。
  3. <body> 定義 HTML 文檔的主體。
  4. <h1> 到 <h6> 定義 HTML 標題。
  5. <form> 定義 HTML 文檔表單。
  6. <p> 定義一個段落。
  7. <a> 定義一個超文本連接。
  8. <div> 定義文檔中的一個節。

HTML 標籤遠不止上面的這幾種,這裏只是列出了常見的幾種,大家可以在網上找到很多這方面的內容「從網絡上找到自己想要的內容,也是一種重要的能力」。

除了標籤以外,屬性也是 HTML 的一個重要組成部分。屬性以“名稱-值”的形式成對出現,由“=”分離並寫在開始標籤元素名之後,對每個標籤的顯示方式及顯示狀態進行控制。常用的屬性主要有以下幾種:

  1. id 屬性爲元素提供了在全文檔內的唯一標識。它用於識別元素,以便樣式表可以改變其表現屬性,腳本可以改變、顯示或刪除其內容或格式化。
  2. class 屬性提供一種將類似元素分類的方式。常被用於語義化或格式化。
  3. style 屬性可以將表現性質賦予一個特定元素
  4. title 屬性用於給元素一個附加的說明。 大多數瀏覽器中這一屬性顯示爲工具提示。

我們通過 HTML 文檔中的標籤和屬性來確定一個內容的位置,從而獲取我們需要從網頁上讀取內容。

網頁內容的解析

網頁實際上就是一個 HTML 文檔,網頁內容的解析實際上就是對 HTML 文檔的解析,在 python 中我們可以使用正則表達式 re,BeautifulSoup、Xpath等網頁解析工具來實現對網頁內容的解析。這裏主要介紹 BeautifulSoup 的使用。

今天主要介紹 BeautfulSoup 的以下內容:

  1. stringstringsstripped_strings: BeautifulSoup 通過這三個屬性來獲取 Tag 的內容。
  2. findfind_all:搜索當前 Tag 及其所有子節點,判斷其是否符合過濾條件。

如果一個 Tag 僅有一個子節點有內容「NavigableString 類型子節點」或其只有一個子節點可以使用 string 屬性來獲取節點內容。若 Tag 包含多個子節點,且不止一個子節點含有內容,此時需要用到 strings 和 stripped_strings 屬性,使用 strings 獲取的內容會包含很多的空格和換行,使用 stripped_strings 可以過濾這些空格和換行。

通過 find 和 find_all 方法可以過濾掉不需要的字符串對象,使用示例如下:

# -*- coding:utf-8 -*-
from bs4 import BeautifulSoup
import re

html = """
<html><head><title>The Dormouse's story</title></head>
 <body>
  <p class="title"><b>The Dormouse's story</b></p>
  <p class="story">Once upon a time there were three little sisters; and their names were
   <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
   <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>and
   <a class="sister" href="http://example.com/tillie" id="link2">Tillie</a>;
   and they lived at the bottom of a well.
  </p>
 </body>
</html>
"""

soup = BeautifulSoup(html, features='lxml')

print ('---------- string ----------')
print (soup.find_all('title'))
print ('---------- regex ----------')
print (soup.find_all(re.compile('^b')))
print ('---------- list ----------')
print (soup.find_all(['b', 'a']))
print ('---------- True ----------')
print (soup.find_all(True))
print ('---------- function ----------')
def has_class_but_no_href(tag):
    return tag.has_attr('class') and not tag.has_attr('href')
print (soup.find_all(has_class_but_no_href))

現在需要從以上的網頁中解析出品牌、廠家型號、商品編號、封裝規格等內容,該怎麼做?首先先確定一下它所對應的 HTML 文檔的內容

從以上 HTML 文檔內容中,可以看出索要獲取的內容在 <div class="product_brand_con"> 的小節中,那麼需要使用 find 方法從整個 HTML 文檔中先把這個小節提取出來,然後使用 find_all 提取出所有的 <div class="item"> 的內容,最後使用 string 屬性獲取對應的字符串內容。整個過程使用代碼表示如下:

        brand_dict = {}
        soup = soup.find('div', class_='product_brand_con')
        if soup is None:
            return brand_dict
        soup = soup.find_all('div', class_='item')
        for item in soup:
            str = []
            for stri in item.stripped_strings:
                str.append(stri)
            if len(str) < 2:
                continue
            if str[0] == '品  牌:':
                brand_dict['brand'] = str[1]
            if str[0] == '廠家型號:':
                brand_dict['model'] = str[1]
            if str[0] == '商品編號:':
                brand_dict['number'] = str[1]
            if str[0] == '封裝規格:':
                brand_dict['package'] = str[1]

以上代碼最終返回一個包含所需內容的字典,若該網頁中不存在所需內容將返回一個空字典。

有關 BeautifulSoup 的更多內容,請看 Python 爬蟲之網頁解析庫 BeautifulSoup 這篇文章。

對網頁內容的解析實際上就是對 HTML 文檔的分割讀取,藉助於 BeautifuSoup 庫,可以非常簡單的從複雜的 HTML 文檔中獲取所需要的內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章