目錄
前言
一、用法詳解
1.1 獲取標簽內容
1.2 獲取標簽屬性?
1.3 獲取標簽包裹的文本內容
1.4 獲取標簽列表
1.5 css 選擇器:select
二、實戰案例
完整代碼
前言
HTML數據解析
1、正則
2、xpath(居多)
3、css 選擇器(bs4)較少
安裝 bs4 模塊:
pip install beautifulsoup4 -i https://pypi.tuna.tsinghua.edu.cn/simple
一、用法詳解
示例? HTML 文檔
html_doc = """
<html><head><title>這是一個示例網頁</title></head><body><p class="title"><b>示例標題</b></p><p class="story">這是一個示例段落。<a href="https://example.com" class="link" id="link1"><span>I am lysir</span>零一先生</a><a href="https://example.org" class="link" id="link2">中國共產黨萬歲</a></p></body>
</html>
"""
第一步:創建 bs4 對象
soup = BeautifulSoup(html_doc,'html.parser')
參數1:要解析的數據源
參數2:解析器
1.1 獲取標簽內容
例:拿 p 標簽的內容
html_doc = """
<html><head><title>這是一個示例網頁</title></head><body><p class="title"><b>示例標題</b></p><p class="story">這是一個示例段落。<a href="https://example.com" class="link" id="link1"><span>I am lysir</span>零一先生</a><a href="https://example.org" class="link" id="link2">中國共產黨萬歲</a></p></body>
</html>
"""# 1,導包
from bs4 import BeautifulSoup
# 2,創建bs4對象
soup = BeautifulSoup(html_doc,'html.parser')
# 3,獲取標簽內容:p標簽
result = soup.p
# 拿到的是第一個P標簽的內容
print(result)
1.2 獲取標簽屬性?
html_doc = """
<html><head><title>這是一個示例網頁</title></head><body><p class="title"><b>示例標題</b></p><p class="story">這是一個示例段落。<a href="https://example.com" class="link" id="link1"><span>I am lysir</span>零一先生</a><a href="https://example.org" class="link" id="link2">中國共產黨萬歲</a></p></body>
</html>
"""# 1,導包
from bs4 import BeautifulSoup
# 2,創建bs4對象
soup = BeautifulSoup(html_doc,'html.parser')
# 3,先獲取 a 標簽的所有屬性(返回的是字典)
result = soup.a.attrs
print("a標簽的所有屬性:",result)
# 4,從字典數據中取出需要的屬性值
print("常規:",result['href']) # https://example.com
# 5,簡寫
print("簡寫:",soup.a['href']) # https://example.com
# 6,get方法
print("get方法:",soup.a.get('href')) # https://example.com
1.3 獲取標簽包裹的文本內容
html_doc = """
<html><head><title>這是一個示例網頁</title></head><body><p class="title"><b>示例標題</b></p><p class="story">這是一個示例段落。<a href="https://example.com" class="link" id="link1"><span>I am lysir</span>零一先生</a><a href="https://example.org" class="link" id="link2">中國共產黨萬歲</a></p></body>
</html>
"""# 1,導包
from bs4 import BeautifulSoup
# 2,創建bs4對象
soup = BeautifulSoup(html_doc,'html.parser')
# 3,獲取標簽包裹的文本內容
# 3.1 可以拿到第一個a標簽的所有文本內容,包括子孫節點的:零一先生 和 I am lysir(子節點數據)
print("常規寫法:",soup.a.text)
# 3.2 get_text()效果一樣
print("get_text()方法:",soup.a.get_text())
# 3.3 string 會不一樣些
# 在只有一個子標簽的情況下可以正常返回,多一個都會返回None
# 就像這里,除非刪除<span>I am lysir</span> 或者 零一先生 其中一個才能正常輸出
print("string方法:",soup.a.string) # None
1.4 獲取標簽列表
html_doc = """
<html><head><title>這是一個示例網頁</title></head><body><p class="title"><b>示例標題</b></p><p class="story">這是一個示例段落。<a href="https://example.com" class="link" id="link1"><span>I am lysir</span>零一先生</a><a href="https://example.org" class="link" id="link2">中國共產黨萬歲</a></p></body>
</html>
"""# 1,導包
from bs4 import BeautifulSoup
# 2,創建bs4對象
soup = BeautifulSoup(html_doc,'html.parser')
# 3,獲取標簽列表
print("常規寫法:",soup.find_all('a'))
# 4,加條件過濾
# class加 _ 是因為class是python中的關鍵字,id就不用
print("條件過濾:",soup.find_all('a',class_='link'))
1.5 css 選擇器:select
# 號是id ?
. 號是class?
>? 表示子節點 ?
空格 表示后代(可以跳級)
+ 表示相鄰的兄弟節點 ?
~ 表示某個元素后的所有兄弟節點
例:找到第二個 a 節點
html_doc = """
<html><head><title>這是一個示例網頁</title></head><body><p class="title"><b>示例標題</b></p><p class="story">這是一個示例段落。<a href="https://example.com" class="link" id="link1"><span>I am lysir</span>零一先生</a><a href="https://example.org" class="link" id="link2">中國共產黨萬歲</a></p></body>
</html>
"""# 1,導包
from bs4 import BeautifulSoup
# 2,創建bs4對象
soup = BeautifulSoup(html_doc,'html.parser')
# 3,重點: css 選擇器 select
# 例:找到第二個 a 節點
result = soup.select('p.story>a') # p標簽屬性class=story下的才是a標簽
print("a標簽列表:",result) # 返回的是符合條件的列表
# 4,取出第二個 a 標簽
two_a = result[1]
print("第二個a標簽:",two_a)# select_one 只拿符合條件的第一個
二、實戰案例
需求:爬取番組計劃每一條圖書字段的值
鏈接:https://bgm.tv/book/browser/?sort=rank
詳細分析:
分析得知,響應數據是 html 的數據,所以可以采用bs4解析
完整代碼
import requests# 1,目標url
url = 'https://bgm.tv/book/browser/?sort=rank'
# 2,身份偽裝
header={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
}
# 3,發起請求獲取響應
response = requests.get(url=url,headers=header)# 4,修改編碼格式(在網頁去查看數據編碼格式)沒加這行代碼之前會發生亂碼現象
response.encoding="utf-8"
# 5,打印內容查看是否符合我們需要的響應數據
# print(response.text)
# 6,對html用bs4解析
from bs4 import BeautifulSoup# 創建 bs4 對象
soup = BeautifulSoup(response.text,'html.parser')
# 獲取 li 列表
li_list = soup.select('ul#browserItemList>li') # select返回的是列表
# 打印一下列表長度
print(f"共有{len(li_list)}條數據")
# 取標題
for data in li_list:# data 就是每一條 li 標簽title = data.select('div>h3>a')print(title[0].text)