Python知識(shí)分享網(wǎng) - 專業(yè)的Python學(xué)習(xí)網(wǎng)站 學(xué)Python,上Python222
超級(jí)詳細(xì)的BeautifulSoup使用方法
匿名網(wǎng)友發(fā)布于:2023-07-08 12:05:04
(侵權(quán)舉報(bào))

BeautifulSoup 的使用

我們學(xué)習(xí)了正則表達(dá)式的相關(guān)用法,但是一旦正則寫(xiě)的有問(wèn)題,可能得到的就不是我們想要的結(jié)果了,而且對(duì)于一個(gè)網(wǎng)頁(yè)來(lái)說(shuō),都有一定的特殊的結(jié)構(gòu)和層級(jí)關(guān)系,而且很多標(biāo)簽都有 id 或 class 來(lái)對(duì)作區(qū)分,所以我們借助于它們的結(jié)構(gòu)和屬性來(lái)提取不也是可以的嗎?

所以,這一節(jié)我們就介紹一個(gè)強(qiáng)大的解析工具,叫做 BeautiSoup,它就是借助網(wǎng)頁(yè)的結(jié)構(gòu)和屬性等特性來(lái)解析網(wǎng)頁(yè)的工具,有了它我們不用再去寫(xiě)一些復(fù)雜的正則,只需要簡(jiǎn)單的幾條語(yǔ)句就可以完成網(wǎng)頁(yè)中某個(gè)元素的提取。

廢話不多說(shuō),接下來(lái)我們就來(lái)感受一下 BeautifulSoup 的強(qiáng)大之處吧。

 

BeautifulSoup 簡(jiǎn)介

簡(jiǎn)單來(lái)說(shuō),BeautifulSoup 就是 Python 的一個(gè) HTML 或 XML 的解析庫(kù),我們可以用它來(lái)方便地從網(wǎng)頁(yè)中提取數(shù)據(jù),官方的解釋如下:

BeautifulSoup 提供一些簡(jiǎn)單的、python 式的函數(shù)用來(lái)處理導(dǎo)航、搜索、修改分析樹(shù)等功能。它是一個(gè)工具箱,通過(guò)解析文檔為用戶提供需要抓取的數(shù)據(jù),因?yàn)楹?jiǎn)單,所以不需要多少代碼就可以寫(xiě)出一個(gè)完整的應(yīng)用程序。BeautifulSoup 自動(dòng)將輸入文檔轉(zhuǎn)換為 Unicode 編碼,輸出文檔轉(zhuǎn)換為 utf-8 編碼。你不需要考慮編碼方式,除非文檔沒(méi)有指定一個(gè)編碼方式,這時(shí)你僅僅需要說(shuō)明一下原始編碼方式就可以了。BeautifulSoup 已成為和 lxml、html6lib 一樣出色的 python 解釋器,為用戶靈活地提供不同的解析策略或強(qiáng)勁的速度。

所以說(shuō),利用它我們可以省去很多繁瑣的提取工作,提高解析效率。

安裝

使用之前,我們當(dāng)然需要首先說(shuō)明一下它的安裝方式。目前 BeautifulSoup 的最新版本是 4.x 版本,之前的版本已經(jīng)停止開(kāi)發(fā)了,推薦使用 pip 來(lái)安裝,安裝命令如下:

 

pip3 install beautifulsoup4

 

好,安裝完成之后可以驗(yàn)證一下,寫(xiě)一段 Python 程序試驗(yàn)一下。

 

from bs4 import BeautifulSoup

soup = BeautifulSoup('<p>Hello</p>', 'html.parser')print(soup.p.string)

 

運(yùn)行結(jié)果

 

Hello

 

如果沒(méi)有報(bào)錯(cuò),則證明安裝沒(méi)有問(wèn)題。

 

解析器

BeautifulSoup 在解析的時(shí)候?qū)嶋H上是依賴于解析器的,它除了支持 Python 標(biāo)準(zhǔn)庫(kù)中的 HTML 解析器,還支持一些第三方的解析器比如 lxml,下面我們對(duì) BeautifulSoup 支持的解析器及它們的一些優(yōu)缺點(diǎn)做一個(gè)簡(jiǎn)單的對(duì)比。

解析器使用方法優(yōu)勢(shì)劣勢(shì)

Python 標(biāo)準(zhǔn)庫(kù) BeautifulSoup (markup, “html.parser”) Python 的內(nèi)置標(biāo)準(zhǔn)庫(kù)、執(zhí)行速度適中 、文檔容錯(cuò)能力強(qiáng) Python 2.7.3 or 3.2.2) 前的版本中文容錯(cuò)能力差

lxml HTML 解析器 BeautifulSoup (markup, “lxml”) 速度快、文檔容錯(cuò)能力強(qiáng)需要安裝 C 語(yǔ)言庫(kù)

lxml XML 解析器 BeautifulSoup (markup, “xml”) 速度快、唯一支持 XML 的解析器需要安裝 C 語(yǔ)言庫(kù)

html5libBeautifulSoup (markup, “html5lib”) 最好的容錯(cuò)性、以瀏覽器的方式解析文檔、生成 HTML5 格式的文檔速度慢、不依賴外部擴(kuò)展

所以通過(guò)以上對(duì)比可以看出,lxml 這個(gè)解析器有解析 HTML 和 XML 的功能,而且速度快,容錯(cuò)能力強(qiáng),所以推薦使用這個(gè)庫(kù)來(lái)進(jìn)行解析,但是這里的劣勢(shì)是必須安裝一個(gè) C 語(yǔ)言庫(kù),它叫做 lxml,我們?cè)谶@里依然使用 pip 安裝即可,命令如下:

 

pip3 install lxml

 

安裝完成之后,我們就可以使用 lxml 這個(gè)解析器來(lái)解析了,在初始化的時(shí)候我們可以把第二個(gè)參數(shù)改為 lxml,如下:

 

from bs4 import BeautifulSoup

soup = BeautifulSoup('<p>Hello</p>', 'lxml')

print(soup.p.string)

 

運(yùn)行結(jié)果是完全一致的。

 

基本使用

下面我們首先用一個(gè)實(shí)例來(lái)感受一下 BeautifulSoup 的基本使用:

 

html = """<html><head><title>The Dormouse's story</title></head><body><p class="title" name="dromouse"><b>The Dormouse'

s story</b></p><p class="story">Once upon a time there were three little sisters; and their names were<a href="http

://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,<a  class="sister" 

id="link2">Lacie</a> and<a  class="sister" id="link3">Tillie</a>;and they lived at the 

bottom of a well.</p><p class="story">...</p>"""

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, 'lxml')

print(soup.prettify())

print(soup.title.string)

 

運(yùn)行結(jié)果

 

<html> <head>  <title>   The Dormouse's story  </title> </head> <body>  <p class="title" name="dromouse">   <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" href="

  http://example.com/tillie" id="link3">    Tillie   </a>   ;and they lived at the bottom of a well.  </p>  

  <p class="story">   ...  </p> </body></html>The Dormouse's story

 

首先我們聲明了一個(gè)變量 html,它是一個(gè) HTML 字符串,但是注意到,它并不是一個(gè)完整的 HTML 字符串, 和 標(biāo)簽都沒(méi)有閉合,但是我們將它當(dāng)作第一個(gè)參數(shù)傳給 BeautifulSoup 對(duì)象,第二個(gè)參數(shù)傳入的是解析器的類型,在這里我們使用 lxml,這樣就完成了 BeaufulSoup 對(duì)象的初始化,將它賦值給 soup 這個(gè)變量。

那么接下來(lái)我們就可以通過(guò)調(diào)用 soup 的各個(gè)方法和屬性對(duì)這串 HTML 代碼解析了。

我們首先調(diào)用了 prettify () 方法,這個(gè)方法可以把要解析的字符串以標(biāo)準(zhǔn)的縮進(jìn)格式輸出,在這里注意到輸出結(jié)果里面包含了 和 標(biāo)簽,也就是說(shuō)對(duì)于不標(biāo)準(zhǔn)的 HTML 字符串 BeautifulSoup 可以自動(dòng)更正格式,這一步實(shí)際上不是由 prettify () 方法做的,這個(gè)更正實(shí)際上在初始化 BeautifulSoup 時(shí)就完成了。

然后我們調(diào)用了 soup.title.string,這個(gè)實(shí)際上是輸出了 HTML 中

 

標(biāo)簽選擇器

剛才我們選擇元素的時(shí)候直接通過(guò)調(diào)用標(biāo)簽的名稱就可以選擇節(jié)點(diǎn)元素了,然后再調(diào)用 string 屬性就可以得到標(biāo)簽內(nèi)的文本了,這種選擇方式速度非???,如果單個(gè)標(biāo)簽結(jié)構(gòu)話層次非常清晰,可以選用這種方式來(lái)解析。

 

選擇元素

下面我們?cè)儆靡粋€(gè)例子詳細(xì)說(shuō)明一下它的選擇方法。

 

html = """<html><head><title>The Dormouse's story</title></head><body><p class="title" name="dromouse"><b>The Dormouse'

s story</b></p><p class="story">Once upon a time there were three little sisters; and their names were<a href="http:

//example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,<a  class="sister"

 id="link2">Lacie</a> and<a  class="sister" id="link3">Tillie</a>;and they lived at 

 the bottom of a well.</p><p class="story">...</p>"""

 from bs4 import BeautifulSoup

 soup = BeautifulSoup(html, 'lxml')

 print(soup.title)

 print(type(soup.title))

 print(soup.title.string)

 print(soup.head)

 print(soup.p)

 

運(yùn)行結(jié)果

 

<title>The Dormouse's story</title><class 'bs4.element.Tag'>The Dormouse's story<head><title>

The Dormouse's story</title></head><p class="title" name="dromouse"><b>The Dormouse's story</b></p>

 

在這里我們依然選用了剛才的 HTML 代碼,我們首先打印輸出了 title 標(biāo)簽的選擇結(jié)果,輸出結(jié)果正是 title 標(biāo)簽加里面的文字內(nèi)容。接下來(lái)輸出了它的類型,是 bs4.element.Tag 類型,這是 BeautifulSoup 中的一個(gè)重要的數(shù)據(jù)結(jié)構(gòu),經(jīng)過(guò)選擇器選擇之后,選擇結(jié)果都是這種 Tag 類型,它具有一些屬性比如 string 屬性,調(diào)用 Tag 的 string 屬性,就可以得到節(jié)點(diǎn)的文本內(nèi)容了,所以接下來(lái)的輸出結(jié)果正是節(jié)點(diǎn)的文本內(nèi)容。

接下來(lái)我們又嘗試選擇了 head 標(biāo)簽,結(jié)果也是標(biāo)簽加其內(nèi)部的所有內(nèi)容,再接下來(lái)選擇了 p 標(biāo)簽,不過(guò)這次情況比較特殊,我們發(fā)現(xiàn)結(jié)果是第一個(gè) p 標(biāo)簽的內(nèi)容,后面的幾個(gè) p 標(biāo)簽并沒(méi)有選擇到,也就是說(shuō),當(dāng)有多個(gè)標(biāo)簽時(shí),這種選擇方式只會(huì)選擇到第一個(gè)匹配的標(biāo)簽,其他的后面的標(biāo)簽都會(huì)忽略。

 

提取信息

在上面我們演示了調(diào)用 string 屬性來(lái)獲取文本的值,那我們要獲取標(biāo)簽屬性值怎么辦呢?獲取標(biāo)簽名怎么辦呢?下面我們來(lái)統(tǒng)一梳理一下信息的提取方式

 

獲取名稱

可以利用 name 屬性來(lái)獲取標(biāo)簽的名稱。還是以上面的文本為例,我們選取 title 標(biāo)簽,然后調(diào)用 name 屬性就可以得到標(biāo)簽名稱。

 

print(soup.title.name)

 

運(yùn)行結(jié)果

 

title

 

屬性獲取

每個(gè)標(biāo)簽可能有多個(gè)屬性,比如 id,class 等等,我們選擇到這個(gè)節(jié)點(diǎn)元素之后,可以調(diào)用 attrs 獲取所有屬性。

 

print(soup.p.attrs)print(soup.p.attrs['name'])

 

運(yùn)行結(jié)果

 

{'class': ['title'], 'name': 'dromouse'}dromouse

 

 

 

轉(zhuǎn)載自:https://blog.csdn.net/zt772612939/article/details/100668663