是一個可以從HTML或XML檔案中提取數據的Python庫.它能夠通過你喜歡的轉換器實現慣用的文件導航,查詢,修改文件的方式.Beautiful Soup會幫你節省數小時甚至數天的工作時間.
pip install beautifulsoup4
from bs4 import BeautifulSoup
解析器 | 使用方法 | 優勢 | 劣勢 |
---|---|---|---|
Python標準庫 | BeautifulSoup(markup, 「html.parser」) | Python的內建標準庫,執行速度快,文件容錯能力強 | Python 2.7.3 or 3.2.2)前 的版本中文件容錯能力差 |
lxml HTML 解析器 | BeautifulSoup(markup, 「lxml」) | 速度快,文件容錯能力強 | 需要安裝C語言庫 |
lxml XML 解析器 | BeautifulSoup(markup, [「lxml-xml」]) | 速度快,唯一支援xml的解析器 | 需要安裝C語言庫 |
html5lib | BeautifulSoup(markup, 「html5lib」) | 最好的容錯性,以瀏覽器的方式 | 速度慢,不依賴外部拓展 |
在官方文件中推薦使用lxml作爲解析器,因爲效率更高。在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必須安裝lxml或html5lib, 因爲那些Python版本的標準庫中內建的HTML解析方法不夠穩定.
#匯入BS4的包
from bs4 import BeautifulSoup
#建立BeautifulSoup物件
#這裏的html是爬取到的網頁,"lxml"指的是選擇器
soup = BeautifulSoup(html,"lxml")
物件 | 屬性 |
---|---|
Tag | 是html中的一個標籤,用BeautifulSoup就能解析出來Tag的具體內容,具體的格式爲soup.name,其中name是html下的標籤。 |
BeautifulSoup | 整個html文字物件,可當作Tag物件. |
NavigableString | 標籤內的文字物件 |
Comment | 是一個特殊的NavigableString物件,如果html標籤記憶體在註釋,那麼它可以過濾掉註釋符號保留註釋文字 |
Tag物件:
from bs4 import BeautifulSoup
#建立一段html標籤
html = '''
<b class="boldest">Extremely bold</b>
<ul>
<li>li</li>
</ul>
'''
soup = BeautifulSoup(html,"lxml")
#建立一個tag物件
tag = soup.b
print(type(tag))
#>>> 此處獲取的就是b標籤
# <b class="boldest">Extremely bold</b>
# <class 'bs4.element.Tag'
from bs4 import BeautifulSoup
#建立一段html標籤
html = '''
<b class="boldest">Extremely bold</b>
<ul>
<li>li</li>
</ul>
'''
soup = BeautifulSoup(html,"lxml")
#建立一個tag物件
tag = soup.b
tag_name = tag.name
#列印出tag物件的名字
print(tag_name)
#列印出tag物件名字的型別
print(type(tag_name))
#>>> b
# <class 'str
soup = BeautifulSoup(html,"lxml")
#建立一個tag物件
tag = soup.b
#更改tag.name的值
tag.name = "genggai"
#過去tag,name
tag_name = tag.name
#列印出tag物件的名字
print(tag_name)
#列印出tag物件名字的型別
print(type(tag_name))
#>>> genggai
# <class 'str'>
如果改變了tag的name,那將影響所有通過當前Beautiful Soup物件生成的HTML文件
attrs:像字典一樣獲取標籤中的屬性資訊,attrs返回型別是字典型別
#建立一段html標籤
html = '''
<b class="boldest" id="di1">Extremely bold</b>
<ul>
<li>li</li>
</ul>
'''
soup = BeautifulSoup(html,"lxml")
#建立一個tag物件
tag = soup.b
#獲取tag中所有的資訊
tag_dict = tag.attrs
#列印出attrs的值
print(tag_dict)
#列印出attrs返回的型別
print(type(tag_dict))
#>>> {'class': ['boldest'], 'id': 'di1'}
# <class 'dict'
from bs4 import BeautifulSoup
html = """
<div class="boldest" id="di1">Extremely bold</div>
<ul>
<div class="boldest">沒有id的div</div>
<li>li</li>
</ul>
"""
soup = BeautifulSoup(html,"lxml")
div_data = soup.find("div",class_="boldest")
print(div_data)
#只取到了第一個class值爲boldest的標籤
#>>> <div class="boldest" id="di1">Extremely bold</div
from bs4 import BeautifulSoup
html = """
<div class="boldest" id="di1">Extremely bold</div>
<ul>
<div class="boldest">沒有id的div</div>
<li>li</li>
</ul>
"""
soup = BeautifulSoup(html,"lxml")
div_data = soup.find_all("div",class_="boldest")
print(div_data)
#>>> [<div class="boldest" id="di1">Extremely bold</div>, <div class="boldest">沒有id的div</div
from bs4 import BeautifulSoup
html = """
<div class="boldest" id="di1">Extremely bold</div>
<ul>
<div class="boldest">沒有id的div</div>
<li>li</li>
</ul>
"""
soup = BeautifulSoup(html,"lxml")
# #di1選擇id爲di1的標籤
div_data = soup.select("#di1")
print(div_data)
#>>>[<div class="boldest" id="di1">Extremely bold</div
類似於xpath中的/,只是在bs4中用>來表示,跨節點用空格表示,只不過bs4一定有一個層級的開始
from bs4 import BeautifulSoup
html = """
<div class="boldest" id="di1">Extremely bold
<ul>
<div class="boldest">沒有id的div</div>
<li>li1</li>
<li>li2</li>
</ul>
</div>
"""
soup = BeautifulSoup(html,"lxml")
#層級選擇器空格舉例
data = soup.select("#di1 li")
# 取id爲di1的標籤下面 下麪ul標籤裏面li標籤
div_data = soup.select("#di1 > ul > li")
print(div_data)
#兩個取值的結果都是一樣的
#>>>[<li>li1</li>, <li>li2</li>]
#>>>[<li>li1</li>, <li>li2</li>]