爬蟲筆記——第三方庫Beautiful Soup4 使用總結(jié)

一、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&amp;keywords=Python&amp;tid=0&amp;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&amp;keywords=Python&amp;tid=0&amp;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&amp;keywords=Python&amp;tid=0&amp;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&amp;keywords=Python&amp;tid=0&amp;lid=0">18796-專項技術(shù)測試(深圳)</a><span class="hot">&nbsp;</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í)。

最后編輯于
?著作權(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)容