Python中的BS4模組-Beautiful Soup

2020-08-12 11:23:39

什麼是BS4?

是一個可以從HTML或XML檔案中提取數據的Python庫.它能夠通過你喜歡的轉換器實現慣用的文件導航,查詢,修改文件的方式.Beautiful Soup會幫你節省數小時甚至數天的工作時間.

BS4的安裝

pip install beautifulsoup4

BS4的匯入

from bs4 import BeautifulSoup

BS4的解析器

解析器 使用方法 優勢 劣勢
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解析方法不夠穩定.

建立BeautifulSoup物件

#匯入BS4的包
from bs4 import BeautifulSoup
#建立BeautifulSoup物件
#這裏的html是爬取到的網頁,"lxml"指的是選擇器
soup = BeautifulSoup(html,"lxml")

BS中的四大物件

物件 屬性
Tag 是html中的一個標籤,用BeautifulSoup就能解析出來Tag的具體內容,具體的格式爲soup.name,其中name是html下的標籤。
BeautifulSoup 整個html文字物件,可當作Tag物件.
NavigableString 標籤內的文字物件
Comment 是一個特殊的NavigableString物件,如果html標籤記憶體在註釋,那麼它可以過濾掉註釋符號保留註釋文字

Tag屬性的介紹

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'

.name屬性:每一個tag物件都有自己的名字,通過.name來獲取

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

更改tag.name的屬性

	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:像字典一樣獲取標籤中的屬性資訊,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'

屬性定位

  • soup.find(「tagName」,attrName=「value」):定位屬性值tagName中attrName="value"的第一個標籤
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
  • soup.find_all(「tagName」,attrName=「value」):定位屬性值tagName中attrName="value"的所有標籤,返回值是一個集合
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

選擇器定位

  • soup.select(「css選擇器」):定位css選擇器選中的標籤,返回值是一個列表
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>]