爬虫系列之【数据解析之bs4】《四》
目录
前言
一、用法详解
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)