一、Beautiful Soup4簡介
這個第三方庫可以幫助我們來處理請求下來的HTML頁面中的數(shù)據(jù),如果你之前有過前端開發(fā)的經(jīng)驗或者是熟悉HTML標(biāo)記語言和CSS語言的話,那么基本上可以無縫對接地使用這個第三方庫來幫助你處理數(shù)據(jù),繼而完成我們的爬蟲。
這里我們會給出Beautiful Soup4的中文文檔,學(xué)習(xí)Pyhton到現(xiàn)在,提供這么詳細(xì)中文文檔的第三方庫,還真是不多。如果大家想詳細(xì)了解學(xué)習(xí)這個庫的話,可以直接訪問官網(wǎng)中文文檔。
但是如果你想快速掌握這個第三方庫,那么就繼續(xù)看下去吧。這篇文章會給大家介紹Beautiful Soup4常用的方法和屬性,能夠幫助你快速掌握該庫,快速將其應(yīng)用到你的項目中。
使用這個庫之前,需要安裝一下,如果你不知道如何安裝,推薦大家查看博客:Pycharm配置環(huán)境及安裝第三方庫。
二、Beautiful Soup基本使用
Beautiful Soup4(后面簡稱bs4)這個庫只能從HTML字符串中,來查找和過濾我們需要的數(shù)據(jù),不能從本地文件中讀取數(shù)據(jù)進(jìn)行過濾。不過這對我們基本上沒有影響,因為我們做爬蟲的時候,大多數(shù)情況下,都是從網(wǎng)絡(luò)上直接爬取HTML頁面中的內(nèi)容,然后進(jìn)行查找篩選了,而不需存儲到本地文件中。
比如我們以騰訊招聘頁面中的一些數(shù)據(jù)為例,首先創(chuàng)建一個字符串,存儲我們的原始數(shù)據(jù),我們接下來的方法講解,也是圍繞這一字符串進(jìn)行的。實例代碼如下:
from bs4 import BeautifulSoup # 引入我們的bs4庫
html_str = """
<tbody>
<tr class="h">
<td class="l" width="374">職位名稱</td>
<td>職位類別</td>
<td>人數(shù)</td>
<td>地點</td>
<td>發(fā)布時間</td>
</tr>
<tr class="even">
<td class="l square"><a target="_blank" href="position_detail.php?id=44569&keywords=Python&tid=0&lid=0">MIG16-基礎(chǔ)架構(gòu)工程師(北京)</a></td>
<td>技術(shù)類</td>
<td>1</td>
<td>北京</td>
<td>2018-09-29</td>
</tr>
<tr class="odd">
<td class="l square"><a target="_blank" href="position_detail.php?id=44570&keywords=Python&tid=0&lid=0">MIG16-數(shù)據(jù)系統(tǒng)高級開發(fā)工程師</a></td>
<td>技術(shù)類</td>
<td>1</td>
<td>北京</td>
<td>2018-09-29</td>
</tr>
<tr class="even">
<td class="l square"><a target="_blank" href="position_detail.php?id=44567&keywords=Python&tid=0&lid=0">MIG16-基礎(chǔ)架構(gòu)工程師(北京)</a></td>
<td>技術(shù)類</td>
<td>1</td>
<td>北京</td>
<td>2018-09-29</td>
</tr>
<tr class="odd">
<td class="l square"><a target="_blank" href="position_detail.php?id=44559&keywords=Python&tid=0&lid=0">18796-專項技術(shù)測試(深圳)</a><span class="hot"> </span></td>
<td>技術(shù)類</td>
<td>2</td>
<td>深圳</td>
<td>2018-09-29</td>
</tr>
</tbody>
"""
現(xiàn)在有了一個字符串,我們便可以將其作為參數(shù),調(diào)用BeautifulSoup(param_1,param_2)來生成一個Beautiful Soup對象。這個時候涉及到一個解析器的知識,也就是上述方法的第二個參數(shù)。解析器用來幫助我們解析文本結(jié)構(gòu),目前主要的解析器有以下幾種:

這里推薦大家使用xlml解析器,因為效率高?,F(xiàn)在便可以將字符串生成Beautiful Soup對象了。示例代碼如下:
bs = BeautifulSoup(html_str,'lxml')
接下來,我們便以這個Beautiful Soup對象為基礎(chǔ),講解bs4庫中常用的方法和屬性。
三、Beautiful Soup常用的方法和屬性
1.find_all() 方法:
find_all()方法搜索當(dāng)前tag的所有符合過濾條件的tag子節(jié)點。在搜索子節(jié)點的時候,我們不僅可以制定要搜索的子節(jié)點的標(biāo)簽名,還可以添加過濾條件,更精確的選擇我們需要的子節(jié)點。實例代碼如下:
- 不加過濾條件,獲取全部的tr標(biāo)簽
trs = bs.find_all('tr')
- 限制選擇標(biāo)簽的數(shù)量,獲取符合條件的前兩個tr標(biāo)簽
trs = bs.find_all('tr',limit=2)
- 選擇class為even的tr子節(jié)點,注意傳入的參數(shù)是class_,不是class
trs = bs.find_all('tr',class_="even")
- 選擇class=even,且id=feng的tr子節(jié)點
trs = bs.find_all('tr', class_="even", id="feng")
# 上述代碼等價于
trs = bs.find_all('tr', {"class": "even", "id": "feng"})
2.find() 方法:
find()方法和find_all()方法的參數(shù)和用法幾乎一樣,只不過find()方法只選取符合條件的第一個標(biāo)簽。同時,下面三條數(shù)據(jù)是等價的。
tr = bs.find("tr")
tr = bs.find_all("tr", limit=1)
tr = bs.find_all("tr")[0]
3.get_text()方法:
如果只想得到tag中包含的文本內(nèi)容,那么可以使用get_text()方法,這個方法獲取到tag中包含的所有文版內(nèi)容包括子孫tag中的內(nèi)容,并將結(jié)果作為Unicode字符串返回。
tr = bs.find_all("tr")[0]
print(tr.get_text())
# 上述代碼返回的字符串如下:
# 職位名稱
# 職位類別
# 人數(shù)
# 地點
# 發(fā)布時間
我們還可以傳入一個參數(shù)作為分隔符,讓獲取的字符串更好的顯示出來,示例代碼如下:
tr = bs.find_all("tr")[0]
print(tr.get_text("----"))
# 上述代碼返回的字符串如下:
# ----職位名稱----
# ----職位類別----
# ----人數(shù)----
# ----地點----
# ----發(fā)布時間----
我們還可以傳入?yún)?shù)strip=True刪除返回的字符串左右兩邊的空格,示例代碼如下:
tr = bs.find_all("tr")[0]
print(tr.get_text("----",strip=True))
# 上述代碼返回的字符串如下:
# 職位名稱----職位類別----人數(shù)----地點----發(fā)布時間
4.獲取節(jié)點屬性的方法:
如果我們想要獲取節(jié)點的屬性,比如對于<a href="www.baidu.com"></a>,我們想獲取它的href屬性值,即www.baidu.com。或者對于其他的節(jié)點元素,我們想要獲取name、class、id等屬性值的時候,我們可以采用下面的方法:
trs = bs.find_all("a")
for tr in trs:
print(tr["href"])
5.select()方法:
通過使用bs庫中的select()方法,我們可以使用CSS選擇器來選擇我們需要的標(biāo)簽。也就是說,我們可以通過標(biāo)簽名,標(biāo)簽的class、標(biāo)簽的id,通過標(biāo)簽的name、href等屬性來選擇我們的元素。使用該方法返回的是一個迭代器,我們可以通過for...in...循環(huán)遍歷。示例代碼如下:
# 選擇所有的p標(biāo)簽
p = bs.select("p")
# 選擇class為box的標(biāo)簽
box = bs.select(".box")
# 選擇id為text的標(biāo)簽
text = bs.select("#text")
# 選擇div中的span標(biāo)簽
span = bs.select("div span")
# 選擇div中的直接子元素img
img = bs.select("div > img")
# 通過屬性來查找標(biāo)簽,比如查找href屬性等于index.html的a節(jié)點
a = bs.select("a[href='index.html']")
這只是CSS選擇器的一部分,其他的CSS也是很類似的。如果有web前端基礎(chǔ),那么你平時如何設(shè)置節(jié)點元素的樣式,在這里你就按照同樣的方法選擇節(jié)點元素即可。
6.string屬性:
如果一個節(jié)點只包含一個文本節(jié)點,或者是只包含一個節(jié)點,那么可以使用該屬性獲取該文本節(jié)點的文本內(nèi)容,或者是這個節(jié)點的文本內(nèi)容。例如:對于<div>hahaha</div>和<div><p>hahaha</p></div>,使用返回的結(jié)果是一樣的,示例代碼如下:
divs = bs.select("div")
for div in divs:
print(div.string)
但是如果一個節(jié)點下面有很多子孫節(jié)點,使用string屬性在獲取文本的時候,最終返回的是None。這個時候我們應(yīng)該使用下面的屬性。
7.strings屬性:
如果一個節(jié)點下面有很多子孫節(jié)點,我們可以使用strings屬性來獲取其子孫節(jié)點的所有文本。該屬性最終返回的是一個迭代器,我們可以通過for...in...循環(huán)來遍歷。實例代碼如下:
tr = bs.select("tr")[0]
for text in tr.strings:
print(text)
# 上述代碼的結(jié)果可能是這樣的,由于換行和空格的存在,可能會有空白文本
#
#
# 職位名稱
#
#
# 職位類別
#
#
# 人數(shù)
#
#
# 地點
#
#
# 發(fā)布時間
8.stripped_strings屬性:
在使用上述strings屬性獲取一個節(jié)點中后代文本的時候,可能或出現(xiàn)換行和空格等空白文本,這樣在處理的時候會出現(xiàn)麻煩,如果不想獲取換行和空格,那么我們可以使用stripped_strings屬性。該屬性和strings屬性一樣,返回的也是迭代器,不能直接打印,需要使用for...in...循環(huán)來遍歷。示例代碼如下:
tr = bs.select("tr")[0]
for text in tr.stripped_strings:
print(text)
# 過濾到空白文本,這個時候的文本是這樣的
# 職位名稱
# 職位類別
# 人數(shù)
# 地點
# 發(fā)布時間
9.contents屬性:
該屬性返回的是某個節(jié)點下的全部子元素,包括子元素的標(biāo)簽名和文本內(nèi)容。返回的數(shù)據(jù)類型是列表,示例代碼如下:
feng = bs.find("tr",id="test")
print(type(feng.contents)) # 打印出來的是 <class 'list'>
for text in feng.contents:
print(text)
10.children屬性
該屬性和contents屬性的用法是一樣的,但是返回的數(shù)據(jù)類型是迭代器,示例代碼如下:
feng = bs.find("tr",id="test")
print(type(feng.children)) # 打印出來的是 <class 'list_iterator'>
for text in feng.children:
print(text)
四、Beautiful Soup4中四中常見的對象
1.Tag對象:
Beautiful Soup中所有的標(biāo)簽都是Tag類型,并且通過bs = BeautifulSoup(html_str, 'lxml')方法常見的bs對象在本質(zhì)上也是Tag類型。我們我們前面說到的find_all()、find()等方法,也都是Tag對象的方法。
2.BeautifulSoup對象
通過bs = BeautifulSoup(html_str, 'lxml')方法常見的bs是BeautifulSoup對象,BeautifulSoup繼承自Tag對象。所以我們之前說bs在本質(zhì)上是Tag類型,而且BeautifulSoup對象的find_all()、find()也是繼承自Tag對象的。
3.NavigableString對象
該對象繼承自Python中的str對象,用起來和str一樣,沒什么說的。
4.Comment對象
這個對象繼承自NavigableString對象,也沒什么說的。
這些知識點知識個人總結(jié),使我們在使用Python做爬蟲的時候常用的一些方法和屬性。
如果想獲取更過的知識,大家可以訪問文章開頭給出的Beautiful Soup4的官方文檔進(jìn)行學(xué)習(xí)。