Python中BeautifulSoup模塊詳解
前言
BeautifulSoup是主要以解析web網(wǎng)頁(yè)的Python模塊,它會(huì)提供一些強(qiáng)大的解釋器,以解析網(wǎng)頁(yè),然后提供一些函數(shù),從頁(yè)面中提取所需要的數(shù)據(jù),目前是Python爬蟲中最常用的模塊之一。
安裝庫(kù)
在使用前需要安裝庫(kù),這里建議安裝bs4,也就是第四版本,因?yàn)楦鶕?jù)官方文檔第三版的已經(jīng)停止更新。同時(shí)安裝lxml解釋器
pip3 install bs4
pip3 install lxml
導(dǎo)入庫(kù)
from bs4 import BeautifulSoup
解析文檔示例
這里以官方文檔進(jìn)行舉例,我把常用的函數(shù)都舉出來(lái),實(shí)際開發(fā)過(guò)程中用到的不多,了解就可以。
# 取自《愛麗絲夢(mèng)游仙境》的一段
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 class="sister" id="link1"><!--Elsie--></a>,
<a class="sister" id="link2">Lacie</a> and
<a class="sister" id="link3">Tillite</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
# 解析文檔,建立一個(gè)BeautifulSoup對(duì)象,各種函數(shù)都是針對(duì)此對(duì)象展開,此函數(shù)會(huì)自動(dòng)編碼為Unicode
soup = BeautifulSoup(html,'lxml')此函數(shù)有兩個(gè)參數(shù):
1、需要解析的文本,可以使字符串,可以使本地文件
2、解釋器,這里有"lxml", "lxml-xml", "html.parser", or "html5lib",4種,可以解析絕大多數(shù)網(wǎng)頁(yè),常用lxml解析 這里有一個(gè)坑,如果網(wǎng)頁(yè)中沒有規(guī)定編碼格式,解釋器就不能編碼為Unicode,必須先聲明一下編碼格式,只需要到網(wǎng)頁(yè)源碼中查找編碼格式然后做個(gè)聲明就可以。一般在網(wǎng)頁(yè)中查找charset關(guān)鍵字。
# 美化文檔,有些網(wǎng)頁(yè)書寫不規(guī)范,這個(gè)函數(shù)會(huì)補(bǔ)全標(biāo)簽,使其看起來(lái)更規(guī)范 print(soup.prettify())
提取數(shù)據(jù)示例
獲取到文本后,接下來(lái)需要提取我們所需的數(shù)據(jù),這里用到選擇器 有三種選擇器
標(biāo)簽選擇器(tag選擇器)
標(biāo)準(zhǔn)選擇器
CSS選擇器
1、標(biāo)簽選擇器(tag選擇器)
# 直接用標(biāo)簽獲取標(biāo)題
print("title: ", soup.title)
# 獲取標(biāo)題文本
print(soup.title.text)
# 獲取p標(biāo)簽
print(soup.p)
# 獲取head標(biāo)簽
print(soup.head)
# 獲取a標(biāo)簽
print(soup.a)輸出:

標(biāo)簽中最重要的倆個(gè)屬性:name、attributes
# 使用.name函數(shù)獲取標(biāo)簽名
print('標(biāo)題標(biāo)簽的名字: ', soup.title.name)
# tag的屬性用法和字典基本一樣,可以用屬性名取屬性,類似字典的鍵值對(duì),也可以用.attrs取屬性:
print('a標(biāo)簽中屬性為"href"的值: ', soup.a["href"])
# 會(huì)返回一個(gè)字典,需要何種屬性可自行提取
print('a標(biāo)簽的所有屬性: ',soup.a.attrs)
dict1 = soup.a.attrs
# 屬性為class的值
print('屬性為class的值: ', dict1['class'])輸出:

這里的子孫父兄節(jié)點(diǎn),我感覺用起來(lái)忒不順手,可能是我學(xué)的不太徹底??,我在這里列出來(lái),大家看看。
# 返回子節(jié)點(diǎn)的列表
print("p的子節(jié)點(diǎn): ", soup.p.contents)
# 返回子節(jié)點(diǎn)的生成器
print('a的子節(jié)點(diǎn): ', soup.a.children)
# 返回子孫結(jié)點(diǎn)的生成器
print("a的子孫結(jié)點(diǎn): ", soup.a.descendants)
# 返回父節(jié)點(diǎn)
print("a的父節(jié)點(diǎn): ", soup.a.parent)
# 遞歸父節(jié)點(diǎn)
print("a的遞歸父節(jié)點(diǎn): ",soup.a.parents)輸出:

上述的標(biāo)簽選擇器如果遇到相同的標(biāo)簽名,比如說(shuō)上述的文檔中就有多個(gè)a標(biāo)簽,這時(shí)就沒法選擇相同標(biāo)簽的第二個(gè)標(biāo)簽,也可能是我沒會(huì)操作,如果有發(fā)現(xiàn)的歡迎評(píng)論。
所以需要一個(gè)遍歷全文的選擇器來(lái)提取數(shù)據(jù): find_all( name , attrs , recursive , text , **kwargs ) # 可根據(jù)標(biāo)簽名、屬性、內(nèi)容查找文檔,此函數(shù)配合正則表達(dá)式可匹配出各種特定的數(shù)據(jù)。。。
# 遍歷文檔中所有a標(biāo)簽
print("文檔中所有a標(biāo)簽: ", soup.find_all('a'))
a_list = soup.find_all('a')
for i, aList in enumerate(a_list):
print(i, aList)輸出:可以提取到文本中所有a標(biāo)簽的內(nèi)容,再通過(guò)遍歷就可以得到每一個(gè)的內(nèi)容

根據(jù)屬性、文本篩選
# 根據(jù)屬性篩選
print(soup.find_all(attrs={'class': 'sister'}))
# 根據(jù)文本篩選
print(soup.find_all(text="The Dormouse's story"))正則表達(dá)式篩選
#使用正則表達(dá)式找出文本中帶有story字符串的內(nèi)容
print(soup.find_all(text=re.compile('story')))還有一個(gè)find()方法,用法和findall()類似,不同的是返回的只有一個(gè)值,而 findall()返回的是列表。
CSS選擇器
目前來(lái)說(shuō),CSS選擇器是最常用的一種,通過(guò)標(biāo)簽及屬性的層層嵌套可以實(shí)現(xiàn)各種特定內(nèi)容的提取。
# 元素選擇器:選擇p標(biāo)簽
print('標(biāo)簽為p:', soup.select("p"))
# 類選擇器:類前加'.'
print("文本中所有class類的標(biāo)簽: \n", soup.select('.sister'))
# id選擇器:id前加'#'
print("id為link2的標(biāo)簽: \n", soup.select('#link2'))輸出:

# 屬性選擇器:
print("屬性為name的標(biāo)簽: \n", soup.select("p[name]"))
print("選擇所有屬性中有sister的標(biāo)簽: \n", soup.select("*[href]"))
print("選擇p標(biāo)簽的后代第三個(gè)a標(biāo)簽 \n", soup.select("p>a")[2])
print("選擇id=link1后的所有兄弟標(biāo)簽 \n", soup.select("#link1 ~ .sister"))
print('通過(guò)屬性為 \n', soup.select('a[))
print("通過(guò)href屬性中以http開頭的所有標(biāo)簽的查找 \n", soup.select('a[href^="http"]'))
print("通過(guò)href屬性中以elsie結(jié)尾的所有標(biāo)簽的查找 \n", soup.select('a[href$="elsie"]'))
print("通過(guò)href屬性中包含.com的所有標(biāo)簽的查找 \n", soup.select("a[href*='.com']"))
# 通過(guò)標(biāo)簽層層查找,這里的:nth-child(2)代表第二個(gè)p標(biāo)簽,a#link2表示a標(biāo)簽的id為link2的標(biāo)簽
print("通過(guò)標(biāo)簽層層查找 \n", soup.select("body>p:nth-child(2)>a#link2"))示例輸出:大家可以自行試試

以上的CSS選擇器的常用函數(shù)已經(jīng)講完,通過(guò)上面的示例基本上可以拿到web文本中絕大多數(shù)數(shù)據(jù)。下面通過(guò)一個(gè)小栗子試試水。
實(shí)例小項(xiàng)目
需求:爬取某代理網(wǎng)站的免費(fèi)代理IP地址
第一步:請(qǐng)求數(shù)據(jù),獲取數(shù)據(jù)文本第二步:通過(guò)BeautifulSoup分析數(shù)據(jù) 提取數(shù)據(jù)第三步:保存數(shù)據(jù)到本地文本
url = "https://www.89ip.cn/"
header = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36"}
# 請(qǐng)求數(shù)據(jù)
response = requests.get(url, headers=header)
print(response.status_code)
# 判斷是否請(qǐng)求成功
if response.status_code == 200:
# 獲取web信息的文本模式
dataText = response.text
# 使用lxml解析器解析文本
soup = BeautifulSoup(dataText, 'lxml')
# 觀察網(wǎng)頁(yè)源碼,獲取需求數(shù)據(jù),這里使用CSS選擇器層層嵌套獲得最終的ip信息
ipText = soup.select('body div>div>div>div>table>tbody>tr>td:nth-child(1)')
# 遍歷列表獲取每一個(gè)ip地址
for i in range(len(ipText)):
# 獲取ip的文本信息,get_text()是獲取文本,strip()是去掉兩邊空格
ip = ipText[i].get_text().strip()
# 保存到本地
file = open("ipText.txt", 'a+')
file.write(ip+"\n")
# 關(guān)閉文件
file.close()運(yùn)行結(jié)果:

總結(jié)
BeautifulSoup模塊主要作用是網(wǎng)頁(yè)解析、提取數(shù)據(jù),主要有三種提取數(shù)據(jù)的選擇器,最常用的是CSS選擇器,可以根據(jù)層層嵌套的方式獲取所需信息。在這里需要一點(diǎn)HTML和CSS基本知識(shí)。
到此這篇關(guān)于Python中BeautifulSoup模塊詳解的文章就介紹到這了,更多相關(guān)Python BeautifulSoup模塊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python使用Beautiful?Soup(BS4)庫(kù)解析HTML和XML
- Python使用BeautifulSoup4修改網(wǎng)頁(yè)內(nèi)容的實(shí)戰(zhàn)記錄
- python?beautifulsoup4?模塊詳情
- python?中的?BeautifulSoup?網(wǎng)頁(yè)使用方法解析
- Python爬蟲之BeautifulSoup的基本使用教程
- Python爬取求職網(wǎng)requests庫(kù)和BeautifulSoup庫(kù)使用詳解
- Python實(shí)戰(zhàn)快速上手BeautifulSoup庫(kù)爬取專欄標(biāo)題和地址
- python數(shù)據(jù)解析BeautifulSoup爬取三國(guó)演義章節(jié)示例
- python爬蟲beautiful?soup的使用方式
相關(guān)文章
Python中日志模塊logging的使用技巧和應(yīng)用詳解
在Python開發(fā)中,日志記錄是一個(gè)非常重要的環(huán)節(jié),它不僅有助于開發(fā)者追蹤程序的執(zhí)行流程,還能在出現(xiàn)問(wèn)題時(shí)提供關(guān)鍵信息,幫助快速定位并解決問(wèn)題,本文將結(jié)合實(shí)際案例,詳細(xì)介紹logging模塊的基礎(chǔ)用法和高級(jí)特性,需要的朋友可以參考下2024-08-08
Python+tkinter實(shí)現(xiàn)一個(gè)繪圖風(fēng)格控件
這篇文章主要為大家詳細(xì)介紹了Python如何利用tkinter實(shí)現(xiàn)一個(gè)簡(jiǎn)單的繪圖風(fēng)格控件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下2023-09-09
Python純代碼通過(guò)神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)線性回歸的擬合方式
這篇文章主要介紹了Python純代碼通過(guò)神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)線性回歸的擬合方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
python plt.plot bar 如何設(shè)置繪圖尺寸大小
這篇文章主要介紹了python plt.plot bar 設(shè)置繪圖尺寸大小的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
Python實(shí)現(xiàn)csv文件(點(diǎn)表和線表)轉(zhuǎn)換為shapefile文件的方法
這篇文章主要介紹了Python實(shí)現(xiàn)csv文件(點(diǎn)表和線表)轉(zhuǎn)換為shapefile文件的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10
節(jié)日快樂(lè)! Python畫一棵圣誕樹送給你
節(jié)日快樂(lè)!這篇文章主要介紹了如何使用Python畫一棵圣誕樹,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12
linux環(huán)境下的python安裝過(guò)程圖解(含setuptools)
這篇文章主要介紹了linux環(huán)境下的python安裝過(guò)程圖解(含setuptools),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
Python telnet登陸功能實(shí)現(xiàn)代碼
這篇文章主要介紹了Python telnet登陸功能實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
在 Windows 下搭建高效的 django 開發(fā)環(huán)境的詳細(xì)教程
這篇文章主要介紹了如何在 Windows 下搭建高效的 django 開發(fā)環(huán)境,本文通過(guò)一篇詳細(xì)教程實(shí)例代碼相結(jié)合給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
一篇文章帶你了解python標(biāo)準(zhǔn)庫(kù)--time模塊
下面小編就為大家?guī)?lái)一篇python模塊之time模塊。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-08-08

