python3解析庫BeautifulSoup4的安裝配置與基本用法

單來說,BeautifulSoup就是Python的一個HTML或XML的解析庫,我們可以用它來方便地從網頁中提取數據,下面這篇文章主要給大家介紹了關於python3解析庫BeautifulSoup4的安裝配置與基本用法的相關資料,需要的朋友可以參考下

前言

Beautiful Soup是python的一個HTML或XML的解析庫,我們可以用它來方便的從網頁中提取數據,它擁有強大的API和多樣的解析方式。

Beautiful Soup的三個特點:

Beautiful Soup提供一些簡單的方法和python式函數,用於瀏覽,搜索和修改解析樹,它是一個工具箱,通過解析文檔爲用戶提供需要抓取的數據
Beautiful Soup自動將轉入穩定轉換爲Unicode編碼,輸出文檔轉換爲UTF-8編碼,不需要考慮編碼,除非文檔沒有指定編碼方式,這時只需要指定原始編碼即可
Beautiful Soup位於流行的Python解析器(如lxml和html5lib)之上,允許您嘗試不同的解析策略或交易速度以獲得靈活性。

1、Beautiful Soup4的安裝配置

Beautiful Soup4通過PyPi發佈,所以可以通過系統管理包工具安裝,包名字爲beautifulsoup4在這裏插入圖片描述
也可用通過下載源碼包來安裝:

#wget https://www.crummy.com/software/BeautifulSoup/bs4/download/4.0/beautifulsoup4-4.1.0.tar.gz
#tar xf beautifulsoup4-4.1.0.tar.gz
#cd beautifulsoup4
#python setup.py install

Beautiful Soup在解析時實際上是依賴解析器的,它除了支持python標準庫中的HTML解析器外還支持第三方解析器如lxml

Beautiful Soup支持的解析器,以及它們的優缺點:在這裏插入圖片描述安裝解析器:

$pip install lxml
$pip install html5lib

推薦使用lxml作爲解析器,因爲效率更高. 在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必須安裝lxml或html5lib, 因爲那些Python版本的標準庫中內置的HTML解析方法不夠穩定

2、BeautifulSoup的基本用法

通過傳入一段字符或一個文件句柄,BeautifulSoup的構造方法就能得到一個文檔的對象,選擇合適的解析器來解析文檔,如手動指定將選擇指定的解析器來解析文檔,Beautiful Soup將複雜的HTML文檔轉換成一個複雜的樹形結構,每個節點都是python對象,所有對象可以歸納爲4種:Tag、NavigableString、BeautifulSoup、Comment

注意:BeautifulSoup版本4的包是在bs4中引入的

rom bs4 import BeautifulSoup
 
#下面代碼示例都是用此文檔測試
html_doc = """
<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 href="http://example.com/elsie" rel="external nofollow" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" rel="external nofollow" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" rel="external nofollow" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
 
<p class="story">...</p>
"""
markup="<b><!--Hey, buddy. Want to buy a used parser?--></b>"
soup=BeautifulSoup(html_doc,"lxml")
soup1=BeautifulSoup(markup,"lxml")
tag=soup.a
navstr=tag.string
comment=soup1.b.string
print(type(tag)) #Tag標籤對象
print(type(comment)) #Comment對象包含文檔註釋內容
print(type(navstr)) #NavigableString對象包裝字符串內容
print(type(soup)) #BeautifulSoup對象爲文檔的全部內容
 
#
<class 'bs4.element.Tag'>
<class 'bs4.element.Comment'>
<class 'bs4.element.NavigableString'>
<class 'bs4.BeautifulSoup'>

(1)節點選擇器(tag)

直接調用節點的名稱就可以選擇節點元素,節點可以嵌套選擇返回的類型都是bs4.element.Tag對象

soup=BeautifulSoup(html_doc,'lxml')
print(soup.head) #獲取head標籤
print(soup.p.b) #獲取p節點下的b節點
print(soup.a.string) #獲取a標籤下的文本,只獲取第一個

name屬性獲取節點名稱:

soup.body.name

attrs屬性獲取節點屬性,也可以字典的形式直接獲取,返回的結果可能是列表或字符串類型,取決於節點類型

soup.p.attrs #獲取p節點所有屬性
soup.p.attrs['class'] #獲取p節點class屬性
soup.p['class'] #直接獲取p節點class屬性

string屬性獲取節點元素包含的文本內容:

soup.p.string #獲取第一個p節點下的文本內容

contents屬性獲取節點的直接子節點,以列表的形式返回內容

soup.body.contents #是直接子節點,不包括子孫節點

children屬性獲取的也是節點的直接子節點,只是以生成器的類型返回

soup.body.children

descendants屬性獲取子孫節點,返回生成器

soup.body.descendants

parent屬性獲取父節點,parents獲取祖先節點,返回生成器

soup.b.parent
soup.b.parents

next_sibling屬性返回下一個兄弟節點,previous_sibling返回上一個兄弟節點,注意換行符也是一個節點,所以有時候在獲取兄弟節點是通常是字符串或者空白

soup.a.next_sibling
soup.a.previous_sibling

next_siblings和previous_sibling分別返回前面和後面的所有兄弟節點,返回生成器

soup.a.next_siblings
soup.a.previous_siblings

next_element和previous_element屬性獲取下一個被解析的對象,或者上一個

soup.a.next_element
soup.a.previous_element

next_elements和previous_elements迭代器向前或者後訪問文檔解析內容

soup.a.next_elements
soup.a.previous_elements

(2)方法選擇器

前面使用的都是通過節點屬性來選擇的,這種方法非常快,但在進行比較複雜的選擇時就不夠靈活,幸好Beautiful Soup還爲我們提供了一些查詢方法,如fang_all()和find()等

find_all(name,attrs,recursive,text,**kwargs):查詢所有符合條件的元素,其中的參數

name表示可以查找所有名字爲name的標籤(tag),也可以是過濾器,正則表達式,列表或者是True

attrs表示傳入的屬性,可以通過attrs參數以字典的形式指定如常用屬性id,attrs={‘id’:‘123’},由於class屬性是python中的關鍵字,所有在查詢時需要在class後面加上下劃線即class_=‘element’,返回的結果是tag類型的列表

text參數用來匹配節點的文本,傳入的形式可以是字符串也可以是正則表達式對象

recursive表示,如果只想搜索直接子節點可以將參數設爲false:

recursive=Flase

limit參數,可以用來限制返回結果的數量,與SQL中的limit關鍵字類似import re
from bs4 import BeautifulSoup
 
html_doc = """ #下面示例都是用此文本內容測試
<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 href="http://example.com/elsie" class="sister" id="link1">Elsie</a>
 ddd
<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>
<span>中文</span>
"""
 
soup=BeautifulSoup(html_doc,'lxml')
print(type(soup))
print(soup.find_all('span')) #標籤查找
print(soup.find_all('a',id='link1')) #屬性加標籤過濾
print(soup.find_all('a',attrs={'class':'sister','id':'link3'})) #多屬性
print(soup.find_all('p',class_='title')) #class特殊性,此次傳入的參數是**kwargs
print(soup.find_all(text=re.compile('Tillie'))) #文本過濾
print(soup.find_all('a',limit=2)) #限制輸出數量
 
 
#
<class 'bs4.BeautifulSoup'>
[<span>中文</span>]
[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
[<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
[<p class="title"><b>The Dormouse's story</b></p>]
['Tillie']
[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

在這裏插入圖片描述
參數同find_all()一樣

另外還有許多查詢方法,其用法和前面介紹的find_all()方法完全相同,只不過查詢範圍不同,參數也一樣
find_parents(name , attrs , recursive , text , **kwargs )和find_parent(name , attrs , recursive , text , **kwargs ) :前者返回所有祖先節點,後者返回直接父節點

find_next_siblings(name , attrs , recursive , text , **kwargs )和find_next_sibling(name , attrs , recursive , text , **kwargs ) :對當前tag後面的節點進行迭代,前者返回後面的所有兄弟節點,後者返回後面第一個兄弟節點

find_previous_siblings(name , attrs , recursive , text , **kwargs )和find_previous_sibling(name , attrs , recursive , text , **kwargs ) :對當前tag前面的節點進行迭代,前者返回前面的所有兄弟節點,後者返回前面的第一個兄弟節點

find_all_next(name , attrs , recursive , text , **kwargs )和find_next(name , attrs , recursive , text , **kwargs ) :對當前tag之後的tag和字符串進行迭代,前者返回所有符合條件的節點,後者返回第一個符合條件的節點

find_all_previous()和find_previous() :對當前tag之前的tag和字符串進行迭代,前者返回節點後所有符合條件的節點,後者返回第一個符合條件的節點

(3)CSS選擇器

Beautiful Soup還提供了CSS選擇器,如果多CSS選擇器不熟悉可以參考下http://www.w3school.com.cn/cssref/css_selectors.asp

在 Tag 或 BeautifulSoup 對象的 .select()方法中傳入字符串參數,即可使用CSS選擇器的語法找到tag:

In [10]: soup.select('title')
Out[10]: [<title>The Dormouse's story</title>]

通過tag標籤逐層查找:

In [12]: soup.select('body a')
Out[12]: 
[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
 <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
 <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

查找某個tag標籤下的直接子標籤:

In [13]: soup.select('head > title')
Out[13]: [<title>The Dormouse's story</title>]

查找兄弟節點標籤:

In [14]: soup.select('#link1 ~ .sister')
Out[14]: 
[<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
 <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

通過CSS類名查找:

In [15]: soup.select('.title')
Out[15]: [<p class="title"><b>The Dormouse's story</b></p>]
 
In [16]: soup.select('[class~=title]')
Out[16]: [<p class="title"><b>The Dormouse's story</b></p>]

通過tag的id查找:

In [17]: soup.select('#link1')
Out[17]: [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
 
In [18]: soup.select('a#link2')
Out[18]: [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

通過是否存在某個屬性來查找:

In [20]: soup.select('a[href]')
Out[20]: 
[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
 <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
 <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

通過屬性的值來查找匹配:

In [22]: soup.select('a[href="http://example.com/elsie"]')
Out[22]: [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
 
In [23]: soup.select('a[href^="http://example.com/"]') #匹配值的開頭
Out[23]: 
[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
 <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
 <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
 
In [24]: soup.select('a[href$="tillie"]') #匹配值的結尾
Out[24]: [<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
 
In [25]: soup.select('a[href*=".com/el"]') #模糊匹配
Out[25]: [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]

tag節點查找,方法選擇器查找和CSS選擇器查找三種方法的實現方式基本相似,tag相對於其他兩種所有最快速的查找方式,但方法選擇器提供更便利更復雜的查找方式,使用更如有上手。

(4)tag修改方法

Beautiful Soup的強項是文檔的搜索功能,修改功能使用場景不是很多隻做簡單介紹,要了解更多修改方法請前往Beautiful Soup官方文檔查看。

Beautiful Soup可以實現改變tag標誌的屬性的值,添加或刪除屬性和內容,下面介紹一些常用的方法

In [26]: markup='<a href="http://www.baidu.com/">baidu</a>'
In [28]: soup=BeautifulSoup(markup,'lxml')
In [29]: soup.a.string='百度'
In [30]: soup.a
Out[30]: <a href="http://www.baidu.com/">百度</a>
#如果a節點下包括子也將被覆蓋掉

Tag.append() 方法想tag中添加內容,就好像Python的列表的 .append() 方法:

In [30]: soup.a
Out[30]: <a href="http://www.baidu.com/">百度</a>
 
In [31]: soup.a.append('一下')
 
In [32]: soup.a
Out[32]: <a href="http://www.baidu.com/">百度一下</a>

new_tag()方法用於創建一個tag標籤

In [33]: soup=BeautifulSoup('<b></b>','lxml')
 
In [34]: new_tag=soup.new_tag('a',href="http://www.python.org") #創建tag,第一個參數必須爲tag的名稱
 
In [35]: soup.b.append(new_tag) #添加到b節點下
 
In [36]: new_tag.string='python' #爲tag設置值
 
In [37]: soup.b
Out[37]: <b><a href="http://www.python.org">python</a></b>

其他方法:

insert()將元素插入到指定的位置

inert_before()在當前tag或文本節點前插入內容

insert_after()在當前tag或文本節點後插入內容

clear()移除當前tag的內容

extract()將當前tag移除文檔數,並作爲方法結果返回

prettify()將Beautiful Soup的文檔數格式化後以Unicode編碼輸出,tag節點也可以調用

get_text()輸出tag中包含的文本內容,包括子孫tag中的內容

soup.original_encoding 屬性記錄了自動識別的編碼結果

from_encoding:參數在創建BeautifulSoup對象是可以用來指定編碼,減少猜測編碼的運行速度

#解析部分文檔,可以使用SoupStrainer類來創建一個內容過濾器,它接受同搜索方法相同的參數

from bs4 import BeautifulSoup,SoupStrainer
 
html_doc = """
<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 href="http://example.com/elsie" class="sister" id="link1">Elsie</a>
 ddd
<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>
<span>中文</span>
"""
 
 
only_a_tags = SoupStrainer('a') #顧慮器
 
soup=BeautifulSoup(html_doc,'lxml',parse_only=only_a_tags)
 
print(soup.prettify())
 
#
<a class="sister" href="http://example.com/elsie" id="link1">
 Elsie
</a>
<a class="sister" href="http://example.com/lacie" id="link2">
 Lacie
</a>
<a class="sister" href="http://example.com/tillie" id="link3">
 Tillie
</a>

#Beautiful Soup異常處理:

HTMLParser.HTMLParseError:malformed start tag

HTMLParser.HTMLParseError:bad end tag 這個兩個異常都是解析器引起的,解決方法是安裝lxml或者html5lib

推薦我們的Python學習扣qun:913066266 ,看看前輩們是如何學習的!從基礎的python腳本到web開發、爬蟲、django、數據挖掘等【PDF,實戰源碼】,零基礎到項目實戰的資料都有整理。送給每一位python的小夥伴!每天都有大牛定時講解Python技術,分享一些學習的方法和需要注意的小細節,點擊加入我們的 python學習者聚集地

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章