Python中BeautifulSoup模塊詳解
前言
BeautifulSoup是主要以解析web網(wǎng)頁的Python模塊,它會提供一些強(qiáng)大的解釋器,以解析網(wǎng)頁,然后提供一些函數(shù),從頁面中提取所需要的數(shù)據(jù),目前是Python爬蟲中最常用的模塊之一。
安裝庫
在使用前需要安裝庫,這里建議安裝bs4,也就是第四版本,因?yàn)楦鶕?jù)官方文檔第三版的已經(jīng)停止更新。同時(shí)安裝lxml解釋器
pip3 install bs4
pip3 install lxml
導(dǎo)入庫
from bs4 import BeautifulSoup
解析文檔示例
這里以官方文檔進(jìn)行舉例,我把常用的函數(shù)都舉出來,實(shí)際開發(fā)過程中用到的不多,了解就可以。
# 取自《愛麗絲夢游仙境》的一段 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對象,各種函數(shù)都是針對此對象展開,此函數(shù)會自動編碼為Unicode soup = BeautifulSoup(html,'lxml')
此函數(shù)有兩個(gè)參數(shù):
1、需要解析的文本,可以使字符串,可以使本地文件
2、解釋器,這里有"lxml", "lxml-xml", "html.parser", or "html5lib",4種,可以解析絕大多數(shù)網(wǎng)頁,常用lxml解析 這里有一個(gè)坑,如果網(wǎng)頁中沒有規(guī)定編碼格式,解釋器就不能編碼為Unicode,必須先聲明一下編碼格式,只需要到網(wǎng)頁源碼中查找編碼格式然后做個(gè)聲明就可以。一般在網(wǎng)頁中查找charset關(guān)鍵字。
# 美化文檔,有些網(wǎng)頁書寫不規(guī)范,這個(gè)函數(shù)會補(bǔ)全標(biāo)簽,使其看起來更規(guī)范 print(soup.prettify())
提取數(shù)據(jù)示例
獲取到文本后,接下來需要提取我們所需的數(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的屬性用法和字典基本一樣,可以用屬性名取屬性,類似字典的鍵值對,也可以用.attrs取屬性: print('a標(biāo)簽中屬性為"href"的值: ', soup.a["href"]) # 會返回一個(gè)字典,需要何種屬性可自行提取 print('a標(biāo)簽的所有屬性: ',soup.a.attrs) dict1 = soup.a.attrs # 屬性為class的值 print('屬性為class的值: ', dict1['class'])
輸出:
這里的子孫父兄節(jié)點(diǎn),我感覺用起來忒不順手,可能是我學(xué)的不太徹底??,我在這里列出來,大家看看。
# 返回子節(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)簽名,比如說上述的文檔中就有多個(gè)a標(biāo)簽,這時(shí)就沒法選擇相同標(biāo)簽的第二個(gè)標(biāo)簽,也可能是我沒會操作,如果有發(fā)現(xiàn)的歡迎評論。
所以需要一個(gè)遍歷全文的選擇器來提取數(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)容,再通過遍歷就可以得到每一個(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選擇器
目前來說,CSS選擇器是最常用的一種,通過標(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('通過屬性為 \n', soup.select('a[)) print("通過href屬性中以http開頭的所有標(biāo)簽的查找 \n", soup.select('a[href^="http"]')) print("通過href屬性中以elsie結(jié)尾的所有標(biāo)簽的查找 \n", soup.select('a[href$="elsie"]')) print("通過href屬性中包含.com的所有標(biāo)簽的查找 \n", soup.select("a[href*='.com']")) # 通過標(biāo)簽層層查找,這里的:nth-child(2)代表第二個(gè)p標(biāo)簽,a#link2表示a標(biāo)簽的id為link2的標(biāo)簽 print("通過標(biāo)簽層層查找 \n", soup.select("body>p:nth-child(2)>a#link2"))
示例輸出:大家可以自行試試
以上的CSS選擇器的常用函數(shù)已經(jīng)講完,通過上面的示例基本上可以拿到web文本中絕大多數(shù)數(shù)據(jù)。下面通過一個(gè)小栗子試試水。
實(shí)例小項(xiàng)目
需求:爬取某代理網(wǎng)站的免費(fèi)代理IP地址
第一步:請求數(shù)據(jù),獲取數(shù)據(jù)文本第二步:通過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"} # 請求數(shù)據(jù) response = requests.get(url, headers=header) print(response.status_code) # 判斷是否請求成功 if response.status_code == 200: # 獲取web信息的文本模式 dataText = response.text # 使用lxml解析器解析文本 soup = BeautifulSoup(dataText, 'lxml') # 觀察網(wǎng)頁源碼,獲取需求數(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)頁解析、提取數(shù)據(jù),主要有三種提取數(shù)據(jù)的選擇器,最常用的是CSS選擇器,可以根據(jù)層層嵌套的方式獲取所需信息。在這里需要一點(diǎn)HTML和CSS基本知識。
到此這篇關(guān)于Python中BeautifulSoup模塊詳解的文章就介紹到這了,更多相關(guān)Python BeautifulSoup模塊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python使用Beautiful?Soup(BS4)庫解析HTML和XML
- Python使用BeautifulSoup4修改網(wǎng)頁內(nèi)容的實(shí)戰(zhàn)記錄
- python?beautifulsoup4?模塊詳情
- python?中的?BeautifulSoup?網(wǎng)頁使用方法解析
- Python爬蟲之BeautifulSoup的基本使用教程
- Python爬取求職網(wǎng)requests庫和BeautifulSoup庫使用詳解
- Python實(shí)戰(zhàn)快速上手BeautifulSoup庫爬取專欄標(biāo)題和地址
- python數(shù)據(jù)解析BeautifulSoup爬取三國演義章節(jié)示例
- python爬蟲beautiful?soup的使用方式
相關(guān)文章
Python實(shí)現(xiàn)數(shù)據(jù)地址實(shí)體抽取
大家好,本篇文章主要講的是Python實(shí)現(xiàn)數(shù)據(jù)地址實(shí)體抽取,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下2022-02-02python使用 zip 同時(shí)迭代多個(gè)序列示例
這篇文章主要介紹了python使用 zip 同時(shí)迭代多個(gè)序列,結(jié)合實(shí)例形式分析了Python使用zip遍歷迭代長度相等與不等的序列相關(guān)操作技巧,需要的朋友可以參考下2019-07-07Python 實(shí)用技巧之利用Shell通配符做字符串匹配
這篇文章主要介紹了Python 實(shí)用技巧之利用Shell通配符做字符串匹配的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08基于Python實(shí)現(xiàn)人臉識別和焦點(diǎn)人物檢測功能
基于dlib庫的模型,實(shí)現(xiàn)人臉識別和焦點(diǎn)人物的檢測。最后呈現(xiàn)的效果為焦點(diǎn)人物的識別框顏色與其他人物框不一樣。對Python人臉識別和焦點(diǎn)人物檢測設(shè)計(jì)過程感興趣的朋友一起看看吧2021-10-10巧妙使用Python裝飾器處理if...elif...else
大家好,今天在 Github 閱讀 EdgeDB[1] 的代碼,發(fā)現(xiàn)它在處理大量if…elif…else的時(shí)候,巧妙地使用了裝飾器,方法設(shè)計(jì)精巧,分享給大家一下,歡迎收藏學(xué)習(xí),喜歡點(diǎn)贊支持2021-11-11