網站首頁 編程語言 正文
前言
??? BeautifulSoup是主要以解析web網頁的Python模塊,它會提供一些強大的解釋器,以解析網頁,然后提供一些函數,從頁面中提取所需要的數據,目前是Python爬蟲中最常用的模塊之一。
安裝庫
? ? ? ?在使用前需要安裝庫,這里建議安裝bs4,也就是第四版本,因為根據官方文檔第三版的已經停止更新。同時安裝lxml解釋器
pip3 install bs4
pip3 install lxml
導入庫
from bs4 import BeautifulSoup
解析文檔示例
? ? ? ? 這里以官方文檔進行舉例,我把常用的函數都舉出來,實際開發過程中用到的不多,了解就可以。
# 取自《愛麗絲夢游仙境》的一段 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> """ # 解析文檔,建立一個BeautifulSoup對象,各種函數都是針對此對象展開,此函數會自動編碼為Unicode soup = BeautifulSoup(html,'lxml')
此函數有兩個參數:
1、需要解析的文本,可以使字符串,可以使本地文件
2、解釋器,這里有"lxml", "lxml-xml", "html.parser", or "html5lib",4種,可以解析絕大多數網頁,常用lxml解析??? 這里有一個坑,如果網頁中沒有規定編碼格式,解釋器就不能編碼為Unicode,必須先聲明一下編碼格式,只需要到網頁源碼中查找編碼格式然后做個聲明就可以。一般在網頁中查找charset關鍵字。
# 美化文檔,有些網頁書寫不規范,這個函數會補全標簽,使其看起來更規范 print(soup.prettify())
提取數據示例
????????獲取到文本后,接下來需要提取我們所需的數據,這里用到選擇器 有三種選擇器????????
標簽選擇器(tag選擇器)
標準選擇器
CSS選擇器
1、標簽選擇器(tag選擇器)
# 直接用標簽獲取標題 print("title: ", soup.title) # 獲取標題文本 print(soup.title.text) # 獲取p標簽 print(soup.p) # 獲取head標簽 print(soup.head) # 獲取a標簽 print(soup.a)
輸出:?
標簽中最重要的倆個屬性:name、attributes
# 使用.name函數獲取標簽名 print('標題標簽的名字: ', soup.title.name) # tag的屬性用法和字典基本一樣,可以用屬性名取屬性,類似字典的鍵值對,也可以用.attrs取屬性: print('a標簽中屬性為"href"的值: ', soup.a["href"]) # 會返回一個字典,需要何種屬性可自行提取 print('a標簽的所有屬性: ',soup.a.attrs) dict1 = soup.a.attrs # 屬性為class的值 print('屬性為class的值: ', dict1['class'])
輸出:
這里的子孫父兄節點,我感覺用起來忒不順手,可能是我學的不太徹底?,我在這里列出來,大家看看。
# 返回子節點的列表 print("p的子節點: ", soup.p.contents) # 返回子節點的生成器 print('a的子節點: ', soup.a.children) # 返回子孫結點的生成器 print("a的子孫結點: ", soup.a.descendants) # 返回父節點 print("a的父節點: ", soup.a.parent) # 遞歸父節點 print("a的遞歸父節點: ",soup.a.parents)
輸出:?
?????????上述的標簽選擇器如果遇到相同的標簽名,比如說上述的文檔中就有多個a標簽,這時就沒法選擇相同標簽的第二個標簽,也可能是我沒會操作,如果有發現的歡迎評論。
? ? ? ? 所以需要一個遍歷全文的選擇器來提取數據: find_all( name , attrs , recursive , text , **kwargs ) # 可根據標簽名、屬性、內容查找文檔,此函數配合正則表達式可匹配出各種特定的數據。。。
# 遍歷文檔中所有a標簽 print("文檔中所有a標簽: ", soup.find_all('a')) a_list = soup.find_all('a') for i, aList in enumerate(a_list): print(i, aList)
輸出:可以提取到文本中所有a標簽的內容,再通過遍歷就可以得到每一個的內容
?根據屬性、文本篩選
# 根據屬性篩選 print(soup.find_all(attrs={'class': 'sister'})) # 根據文本篩選 print(soup.find_all(text="The Dormouse's story"))
正則表達式篩選
#使用正則表達式找出文本中帶有story字符串的內容 print(soup.find_all(text=re.compile('story')))
還有一個find()方法,用法和findall()類似,不同的是返回的只有一個值,而?findall()返回的是列表。
CSS選擇器
? ? ? ? 目前來說,CSS選擇器是最常用的一種,通過標簽及屬性的層層嵌套可以實現各種特定內容的提取。
# 元素選擇器:選擇p標簽 print('標簽為p:', soup.select("p")) # 類選擇器:類前加'.' print("文本中所有class類的標簽: \n", soup.select('.sister')) # id選擇器:id前加'#' print("id為link2的標簽: \n", soup.select('#link2'))
輸出:?
# 屬性選擇器: print("屬性為name的標簽: \n", soup.select("p[name]")) print("選擇所有屬性中有sister的標簽: \n", soup.select("*[href]")) print("選擇p標簽的后代第三個a標簽 \n", soup.select("p>a")[2]) print("選擇id=link1后的所有兄弟標簽 \n", soup.select("#link1 ~ .sister")) print('通過屬性為 \n', soup.select('a[)) print("通過href屬性中以http開頭的所有標簽的查找 \n", soup.select('a[href^="http"]')) print("通過href屬性中以elsie結尾的所有標簽的查找 \n", soup.select('a[href$="elsie"]')) print("通過href屬性中包含.com的所有標簽的查找 \n", soup.select("a[href*='.com']")) # 通過標簽層層查找,這里的:nth-child(2)代表第二個p標簽,a#link2表示a標簽的id為link2的標簽 print("通過標簽層層查找 \n", soup.select("body>p:nth-child(2)>a#link2"))
示例輸出:大家可以自行試試?
?以上的CSS選擇器的常用函數已經講完,通過上面的示例基本上可以拿到web文本中絕大多數數據。下面通過一個小栗子試試水。
實例小項目
需求:爬取某代理網站的免費代理IP地址
第一步:請求數據,獲取數據文本第二步:通過BeautifulSoup分析數據 提取數據第三步:保存數據到本地文本
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"} # 請求數據 response = requests.get(url, headers=header) print(response.status_code) # 判斷是否請求成功 if response.status_code == 200: # 獲取web信息的文本模式 dataText = response.text # 使用lxml解析器解析文本 soup = BeautifulSoup(dataText, 'lxml') # 觀察網頁源碼,獲取需求數據,這里使用CSS選擇器層層嵌套獲得最終的ip信息 ipText = soup.select('body div>div>div>div>table>tbody>tr>td:nth-child(1)') # 遍歷列表獲取每一個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") # 關閉文件 file.close()
運行結果:?
總結
? ? ? ? BeautifulSoup模塊主要作用是網頁解析、提取數據,主要有三種提取數據的選擇器,最常用的是CSS選擇器,可以根據層層嵌套的方式獲取所需信息。在這里需要一點HTML和CSS基本知識。
原文鏈接:https://blog.csdn.net/m0_64816081/article/details/122790170
相關推薦
- 2022-10-17 QT?TCP實現簡單的通信示例_C 語言
- 2022-07-30 windows安裝matplotlib方法(cmd+pycharm)+cmd不運行python命令解
- 2022-06-15 GO語言字符串處理Strings包的函數使用示例講解_Golang
- 2023-06-03 C++11學習之右值引用和移動語義詳解_C 語言
- 2023-01-03 python中import和from-import的區別解析_python
- 2022-11-20 Rust指南之泛型與特性詳解_Rust語言
- 2022-09-08 Prometheus和NodeExporter安裝監控數據說明_其它綜合
- 2022-06-24 python中的__dict__屬性介紹_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支