外行學(xué) Python 爬蟲 第三篇 內(nèi)容解析

從網(wǎng)絡(luò)上獲取網(wǎng)頁內(nèi)容以后,需要從這些網(wǎng)頁中取出有用的信息,畢竟爬蟲的職責(zé)就是獲取有用的信息,而不僅僅是為了下來一個網(wǎng)頁。獲取網(wǎng)頁中的信息,首先需要指導(dǎo)網(wǎng)頁內(nèi)容的組成格式是什么,沒錯網(wǎng)頁是由 HTML「我們成為超文本標(biāo)記語言,英語:HyperText Markup Language,簡稱:HTML」 組成的,其次需要解析網(wǎng)頁的內(nèi)容,從中提取出我們想要的信息。

HTML

超文本標(biāo)記語言(英語:HyperText Markup Language,簡稱:HTML)是一種用于創(chuàng)建網(wǎng)頁的標(biāo)準(zhǔn)標(biāo)記語言。HTML是一種基礎(chǔ)技術(shù),常與CSS、JavaScript一起被眾多網(wǎng)站用于設(shè)計網(wǎng)頁、網(wǎng)頁應(yīng)用程序以及移動應(yīng)用程序的用戶界面[3]。網(wǎng)頁瀏覽器可以讀取HTML文件,并將其渲染成可視化網(wǎng)頁。HTML描述了一個網(wǎng)站的結(jié)構(gòu)語義隨著線索的呈現(xiàn),使之成為一種標(biāo)記語言而非編程語言。

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

CSS 用于網(wǎng)頁的顯示格式,爬蟲不關(guān)注顯示的格式。JavaScript 主要用于動態(tài)加載內(nèi)容,當(dāng)前可暫不關(guān)注。

HTML 文檔主要有 HTML 元素「或者標(biāo)簽」組成,常用的 HTML 標(biāo)簽主要有以下幾種:

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

HTML 標(biāo)簽遠(yuǎn)不止上面的這幾種,這里只是列出了常見的幾種,大家可以在網(wǎng)上找到很多這方面的內(nèi)容「從網(wǎng)絡(luò)上找到自己想要的內(nèi)容,也是一種重要的能力」。

除了標(biāo)簽以外,屬性也是 HTML 的一個重要組成部分。屬性以“名稱-值”的形式成對出現(xiàn),由“=”分離并寫在開始標(biāo)簽元素名之后,對每個標(biāo)簽的顯示方式及顯示狀態(tài)進(jìn)行控制。常用的屬性主要有以下幾種:

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

我們通過 HTML 文檔中的標(biāo)簽和屬性來確定一個內(nèi)容的位置,從而獲取我們需要從網(wǎng)頁上讀取內(nèi)容。

網(wǎng)頁內(nèi)容的解析

網(wǎng)頁實際上就是一個 HTML 文檔,網(wǎng)頁內(nèi)容的解析實際上就是對 HTML 文檔的解析,在 python 中我們可以使用正則表達(dá)式 re,BeautifulSoup、Xpath等網(wǎng)頁解析工具來實現(xiàn)對網(wǎng)頁內(nèi)容的解析。這里主要介紹 BeautifulSoup 的使用。

今天主要介紹 BeautfulSoup 的以下內(nèi)容:

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

如果一個 Tag 僅有一個子節(jié)點有內(nèi)容「NavigableString 類型子節(jié)點」或其只有一個子節(jié)點可以使用 string 屬性來獲取節(jié)點內(nèi)容。若 Tag 包含多個子節(jié)點,且不止一個子節(jié)點含有內(nèi)容,此時需要用到 strings 和 stripped_strings 屬性,使用 strings 獲取的內(nèi)容會包含很多的空格和換行,使用 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"  id="link1">Elsie</a>,
   <a class="sister"  id="link2">Lacie</a>and
   <a class="sister"  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))
image

現(xiàn)在需要從以上的網(wǎng)頁中解析出品牌、廠家型號、商品編號、封裝規(guī)格等內(nèi)容,該怎么做?首先先確定一下它所對應(yīng)的 HTML 文檔的內(nèi)容

image

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

        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] == '封裝規(guī)格:':
                brand_dict['package'] = str[1]

以上代碼最終返回一個包含所需內(nèi)容的字典,若該網(wǎng)頁中不存在所需內(nèi)容將返回一個空字典。

有關(guān) BeautifulSoup 的更多內(nèi)容,請看 Python 爬蟲之網(wǎng)頁解析庫 BeautifulSoup 這篇文章。

對網(wǎng)頁內(nèi)容的解析實際上就是對 HTML 文檔的分割讀取,借助于 BeautifuSoup 庫,可以非常簡單的從復(fù)雜的 HTML 文檔中獲取所需要的內(nèi)容。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容