【一起學爬蟲】BeautifulSoup庫詳解

2021-12-29 菜鳥名企夢
回顧

上一次介紹正則表達式的時候,分享了一個爬蟲實戰,即爬取豆瓣首頁所有的:書籍、連結、作者、出版日期等。在上個實戰中我們是通過正則表達式來解析源碼爬取數據,整體來說上次實戰中的正則表達式是比較複雜的,所以引入了今天的主角BeautifulSoup:它是靈活方便的網頁解析庫,處理高效,而且支持多種解析器。使用Beautifulsoup,不用編寫正則表達式就可以方便的實現網頁信息的提取。

一、 BeautifulSoup的安裝

pip install beautifulsoup4

二、用法講解1. 解析庫

解析器

使用方法

優勢

劣勢





Python標準庫

BeautifulSoup(markup, "html.parser")

Python的內置標準庫、執行速度適中 、文檔容錯能力強

Python 2.7.3 or 3.2.2)前的版本中文容錯能力差

lxml HTML 解析器

BeautifulSoup(markup, "lxml")

速度快、文檔容錯能力強,常用

需要安裝C語言庫 lxml

lxml XML 解析器

BeautifulSoup(markup, "xml")

速度快、唯一支持XML的解析器

需要安裝C語言庫

html5lib

BeautifulSoup(markup, "html5lib")

最好的容錯性、以瀏覽器的方式解析文檔、生成HTML5格式的文檔

速度慢、不依賴外部擴展

2.基本使用

下面是一個不完整的html:body標籤、html標籤都沒有閉合

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"></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""

下面使用lxml解析庫解析上面的html

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.prettify())
print(soup.title.string)

下面是容錯處理時標籤補全後的結果和獲取的title內容,可以看到html和body標籤都被補全了:

<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" href=" " id="link1">

</ a>
,
<a class="sister" href="http://example.com/lacie" 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

3.標籤選擇器(1)選擇元素

依舊使用上面的html

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.title)
print(type(soup.title))
print(soup.head)
print(soup.p)

結果是:

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

從結果發現只輸出了一個p標籤,但是HTML中有3個p標籤
標籤選擇器的特性:當有多個標籤的時候,它只返回第一個標籤的內容

(2)獲取屬性

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.attrs['name'])
print(soup.p['name'])

輸出結果:

dromouse
dromouse

(3) 獲取內容

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.string)

輸出結果:

The Dormouse's story

(4) 嵌套獲取屬性

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.head.title.string)

輸出:

The Dormouse's story

(5)獲取子節點和子孫節點

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.contents)

輸出的是一個列表

['\n Once upon a time there were three little sisters; and their names were\n ',
<a class="sister" href=" " id="link1">
<span>Elsie</span>
</ a>,
'\n'
, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</ a>
, ' \n and\n '
, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</ a>
, '\n and they lived at the bottom of a well.\n ']

另外一種獲取方式

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.p.children)
for i, child in enumerate(soup.p.children):
print(i, child)

輸出:

<list_iterator object at 0x1064f7dd8>
0
Once upon a time there were three little sisters; and their names were
 
1 <a class="sister" href=" " id="link1">
<span>Elsie</span>
</ a>
2
 
3 <a class="sister" href="http://example.com/lacie" id="link2">Lacie</ a>
4
and   
5    
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</ a>           
6
and they lived at the bottom of a well.

(6)獲取父節點

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.a.parent)

程序列印出的是p標籤,即a標籤的父節點:

<p class="story">
Once upon a time there were three little sisters; and their names were
<a class="sister" href=" " id="link1">
<span>Elsie</span>
</ a>
<a class="sister" href="http://example.com/lacie" 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 >

於此類似的還有:

上面是標籤選擇器:處理速度很快,但是這種方式不能滿足我們解析HTML的需求。因此beautifulsoup還提供了一些其他的方法

4.標準選擇器

**find_all( name , attrs , recursive , text , kwargs )
可根據標籤名、屬性、內容查找文檔
下面使用的測試HTML都是下面這個

html='''
<div>
<div>
<h4>Hello</h4>
</div>
<div>
<ul id="list-1">
<li>Foo</li>
<li>Bar</li>
<li>Jay</li>
</ul>
<ul id="list-2">
<li>Foo</li>
<li>Bar</li>
</ul>
</div>
</div>
'''

(1) 根據標籤名,即name查找

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all('ul'))
print(type(soup.find_all('ul')[0]))

輸出了所有的ul標籤:

[<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>, <ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>]
<class 'bs4.element.Tag'>

上述可以繼續進行嵌套:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.find_all('ul'):
print(ul.find_all('li'))

(2)根據屬性名進行查找

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(id='list-1'))
print(soup.find_all(name='element'))

輸出:

[<ul class="list" id="list-1" name="elements">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>]
[<ul class="list" id="list-1" name="elements">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>]
[<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>]
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li>Jay</li>, <li class="element">Foo</li>, <li>Bar</li>]

(3)根據文本的內容,即text進行選擇

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(text='Foo'))

輸出:

['Foo;'Foo']

返回的不是標籤,在查找的時候用途不大,更多是做內容匹配

find( name , attrs , recursive , text , kwargs )
和findall類似,只不過find方法只是返回單個元素

find_parents() find_parent()
find_parents()返回所有祖先節點,find_parent()返回直接父節點。

find_next_siblings() find_next_sibling()
find_next_siblings()返回後面所有兄弟節點,find_next_sibling()返回後面第一個兄弟節點。

find_previous_siblings() find_previous_sibling()
find_previous_siblings()返回前面所有兄弟節點,find_previous_sibling()返回前面第一個兄弟節點。

find_all_next() find_next()
find_all_next()返回節點後所有符合條件的節點, find_next()返回第一個符合條件的節點

find_all_previous() 和 find_previous()
find_all_previous()返回節點後所有符合條件的節點, find_previous()返回第一個符合條件的節點

5.CSS選擇器

通過select()直接傳入CSS選擇器即可完成選擇

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')

print(soup.select('.panel .panel-heading'))
print(soup.select('ul li'))
print(soup.select('#list-2 .element'))
print(type(soup.select('ul')[0]))

輸出:

[<div class="panel-heading">
<h4>Hello</h4>
</div>]
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>, <li class="element">Foo</li>, <li class="element">Bar</li>]
[<li class="element">Foo</li>, <li class="element">Bar</li>]
<class 'bs4.element.Tag'>

也可以進行嵌套,不過沒必要,上面通過標籤之間使用空格就實現了嵌套:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):
print(ul.select('li'))

輸出:

[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>]
[<li class="element">Foo</li>, <li class="element">Bar</li>]

6.獲取到html後如何獲取屬性和內容:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for ul in soup.select('ul'):
print(ul['id'])
獲取內容
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
for li in soup.select('li'):
print(li.get_text())

7.總結

推薦使用lxml解析庫,必要時使用html.parser

標籤選擇篩選功能弱但是速度快

建議使用find()、find_all() 查詢匹配單個結果或者多個結果

如果對CSS選擇器熟悉建議使用select(),方便

記住常用的獲取屬性和文本值的方法

更多關於Beautifulsoup的使用可以查看對應的文檔說明

- End -

長按,掃碼,關注

及時收看更多精彩內容

博主:今日頭條大數據工程師

 專註:求職 面經 源碼 java 大數據技術分享

點擊閱讀原文獲取4T基礎資料5T精品資料

喜歡就給個「在看

相關焦點

  • 小白學 Python 爬蟲(21):解析庫 Beautiful Soup(上)
    收錄於話題 #小白學爬蟲(3):前置準備(二)Linux基礎入門小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門小白學 Python 爬蟲(5):前置準備(四)資料庫基礎小白學 Python 爬蟲(6):前置準備(五)爬蟲框架的安裝小白學 Python 爬蟲(7):HTTP 基礎小白學 Python 爬蟲(8):網頁基礎
  • python爬蟲常用庫之BeautifulSoup詳解
    但是有人說,前面的正則很難唉,學不好。正則的確很難,有人說過:如果一個問題用正則解決,那麼就變成了兩個問題。所以說學不會是很正常的,不怕,除了正則,我們還可以用另外一個強大的庫來解析html。所以,今天的主題就是來學習這個強大的庫--BeautifulSoup,不過正則還是需要多多練習下的。
  • python爬蟲系列二: Beautiful Soup庫學習筆記
    收錄於話題 #爬蟲安裝:1.安裝beautiful soup4  即bs4          2.安裝lxmlBeautiful Soup對象beautiful soup對象:代表要解析的整個文檔樹,它支持遍歷文檔樹和搜索文檔樹中描述的大部分方法
  • 「小白學爬蟲連載(5)」——Beautiful Soup庫詳解
    歡迎大家關注公眾號【哈希大數據】Beautiful Soup是解析、遍歷、維護HTML或XML文件的Python功能庫,它能幫助我們快速獲取到文件中的數據信息。Beautiful Soup安裝與測試對於Windows平臺:首先介紹一種簡單的安裝包的方法,打開cmd,執行pip installbeautifulsoup4,這裡千萬不要忘記最後的數字4。
  • Python爬蟲快速入門,BeautifulSoup基本使用及實踐
    爬蟲,是學習Python的一個有用的分支,網際網路時代,信息浩瀚如海,如果能夠便捷的獲取有用的信息,我們便有可能領先一步,而爬蟲正是這樣的一個工具。「Python數據之道」 之前已經分享過一些關於介紹 爬蟲 的內容,大家也可以前往閱讀:Beautiful Soup 是一個可以從HTML或XML文件中提取數據的Python庫。
  • 美女老師帶你做爬蟲:BeautifuSoup庫詳解及實戰!
    工具:python2.7版本+pycharm模塊:urllib、urllib2、BeautifuSoup4模塊(解析器lxml、html)課題:BeautifuSoup原理詳解,項目實戰應用!目標:1、了解Beautifulsoup庫 2、學會Beautifulsoup庫及其參數 3、通過一個項目使用beautifulsoup4模塊爬取內容HTML文件其實就是由一組尖括號構成的標籤組織起來的,每一對尖括號形式一個標籤,標籤之間存在上下關係,形成標籤樹;因此可以說
  • Python爬蟲從入門到精通(3): BeautifulSoup用法總結及多線程爬蟲爬取糗事百科
    我們還會利用requests庫和BeauitfulSoup來爬取糗事百科上的段子, 並對比下單線程爬蟲和多線程爬蟲的爬取效率。什麼是BeautifulSoup及如何安裝BeautifulSoup是一個解析HTML或XML文件的第三方庫。
  • BeautifulSoup解析html介紹
    爬蟲抓取的數據以html數據為主。有時也是xml數據,xml數據對標籤的解析和html是一樣的道理,兩者都是<tag>來區分數據的。這種格式的數據結構可以說是一個頁面一個樣子,解析起來很麻煩。BeautifulSoup提供了強大的解析功能,可以幫助我們省去不少麻煩。使用之前安裝BeautifulSoup和lxml。
  • 5分鐘快速學習掌握python爬蟲Beautifulsoup解析網頁
    python爬蟲用Beatifulsoup庫解析網頁提取所需元素新手看懂個人觀點:之前我們有講過爬蟲和網頁的一些聯繫,網頁的一些組成部分,爬蟲就是對網頁裡面的數據進行提取然後對其進行數據處理,篩選出所需部分,供需要者使用。
  • Python爬蟲擴展庫BeautifulSoup4用法精要
    收錄於話題 #網絡爬蟲;   Once upon a time there were three little sisters; and their names were   <a href="http://example.com/elsie" id="link1">    Elsie   </a>   ,   &
  • [Python從零到壹] 五.網絡爬蟲之BeautifulSoup基礎語法萬字詳解
    前一篇文章講述了基於正則表達式的Python爬蟲以及Python常用的爬蟲模塊,而Python強大的網絡支持能力和豐富的擴展包是否也提供了相關的爬蟲包呢?答案是肯定的。本篇文章主要講解BeautifulSoup技術。BeautifulSoup是一個可以從HTML或XML文件中提取數據的Python庫,一個分析HTML或XML文件的解析器。
  • BeautifulSoup庫是爬蟲中的神級庫!最詳細的入門教程!適用新手
    標籤內容,還包括了換行符 ' '過tag的 .children 生成器,可以對tag的子節點進行循環文檔樹的搜索對樹形結構的文檔進行特定的搜索是爬蟲抓取過程中最常用的操作搜索所有帶有 target 屬性的標籤soup.find_all(target=True)搜索所有不帶 target 屬性的標籤(仔細觀察會發現,搜索結果還是會有帶 target 的標籤,那是不帶 target 標籤的子標籤,這裡需要注意一下。)
  • 爬蟲入門系列(四):HTML文本解析庫BeautifulSoup
    BeautifulSoup 是一個用於解析 HTML 文檔的 Python 庫,通過 BeautifulSoup,你只需要用很少的代碼就可以提取出 HTML 中任何感興趣的內容,此外,它還有一定的 HTML 容錯能力,對於一個格式不完整的HTML 文檔,它也可以正確處理。
  • BeautifulSoup
    Beautiful Soup 是一個可以從HTML或XML文件中提取數據的Python庫.# <title>The Dormouse's story</title>soup.title.name# u'title'soup.title.string# u'The Dormouse's story'soup.title.parent.name# u'head'soup.p# <p class="title"><b>The Dormouse's
  • [Python從零到壹] 六.網絡爬蟲之BeautifulSoup爬取豆瓣TOP250電影詳解
    前一篇文章講述了BeautifulSoup技術,它是一個可以從HTML或XML文件中提取數據的Python庫,一個分析HTML或XML文件的解析器,包括安裝過程和基礎語法。這篇文章將詳細講解 BeautifulSoup 爬取豆瓣TOP250電影,通過案例的方式讓大家熟悉Python網絡爬蟲,同時豆瓣TOP250也是非常適合入門的案例,也能普及簡單的預處理知識。
  • Python 爬蟲之 BeautifulSoup
    點擊上方藍字,快速關注我們)來源:chenjiabing666chenjiabing666.github.io/2017/04/29/python爬蟲之
  • BeautifulSoup | 讓你一次性搞清楚BeautifulSoup!(上)
    BeautifulSoup用法介紹下面我們正式介紹BeautifulSoup庫。print(soup.prettify())格式化代碼,自動補全代碼,進行容錯的處理。title_tag = soup.title注意這裡的title_tag是一個Tag對象。
  • Python爬蟲html解析,還在用BeautifulSoup嗎?試試PyQuery吧
    在初學python時,大家都喜歡寫些小腳本來爬些網頁,因為這能在最短的時間讓我們達到一種小小的滿足感,通常我們解析網頁時有幾種方法:正則表達式匹配 - 比較低級用beautifulsoup、pyquery等包解析用scrapy、pyspider等框架來解析其實,方法
  • python程序媛BeautifulSoup快速入門
    爬蟲最常用就是要在response回的html文件中獲取我們想要的資源,而常用方法除了正則就是BeautifulSoup庫了。其實,媛媛本人呢,是習慣使用正則的,不過經常聽到很多同學表示正則太複雜,想要使用BeautifulSoup庫,今天呢,就滿足大家,帶著大家超級簡單案例,快速入門。
  • 技術分享|利用Python和BeautifulSoup進行網頁爬取(新手教程)
    使用Python與BeautifulSoup可以很容易的進行網頁爬取,通過網站爬蟲獲取信息可以幫助企業或個人節省很多的時間和金錢。學習本文之後,我相信大部分新手都能根據自己的需求來開發出相應的網頁爬蟲。