2024 一天掌握python爬虫【基础篇】 涵盖 requests、beautifulsoup、selenium:
https://www.bilibili.com/video/BV1Ju4y1Y7k6/
beautifulsoup支持解析本地文件和网络文件,需要注意的是在实例化 BeautifulSoup 对象时,“html.parser” 是一个解析器,用于解析 HTML 代码,可以使用其他解析器,如 lxml、html5lib 等
通过 bs4 对象,可以使用多种方式来获取 HTML 中的元素信息,包括标签名、属性、文本等。
首先准备一个测试文件test.html
<html>
<head>
<meta charset="utf-8">
<title>python222-这是一个示例文档</title>
</head>
<body>
<p id="p1" class="content">这是一个段落。</p>
<div>
<ul class="list">
<li class="item">列表项1</li>
<li class="item" id="l2">列表项2</li>
<li class="item" id="l3">列表项3</li>
<a href="http://www.java1234.com" class="c1">java1234</a>
</ul>
</div>
<a href="http://www.python222.com" target="_blank" class="c2">python222</a>
<div id="d1">
<span>
测试内容
</span>
</div>
</body>
</html>
bs4常用方法有find(),find_all(),select()
.find_all() | 查找所有符合条件的元素 |
.find() | 查找第一个符合条件的元素 |
.select() | 使用 CSS 选择器查找元素 |
.children | 获取当前标签的直接子元素 |
.descendants | 获取当前标签的所有子孙节点 |
.parent | 获取当前标签的父节点 |
.parents | 获取当前标签的所有祖先节点 |
.next_sibling | 获取下一个同级标签 |
.previous_sibling | 获取上一个同级标签 |
.next_siblings | 获取后续所有同级标签 |
.previous_siblings | 获取前序所有同级标签 |
.has_attr() | 判断元素是否含有某个属性 |
bs4支持DOM标签选择器,属性选择前,层级选择器等,以及获取元素属性和节点内容
测试代码:
from bs4 import BeautifulSoup
# 默认打开的文件编码是gbk,我们需要设置编码
soup = BeautifulSoup(open('test.html', encoding='utf-8'), 'lxml')
# 根据标签名查找DOM节点 找到是第一个符合条件的DOM节点
# DOM DOM值 DOM标签名
print(type(soup.a), soup.a, soup.a.name)
# 获取标题的属性和属性值
print(type(soup.a.attrs), soup.a.attrs['href'])
# 获取标签内容
print(soup.p.string)
# bs4的一些常用方法
# 查找第一个符合条件的元素,支持属性条件
print(soup.find('a'))
print(soup.find('a', target="_blank"))
# class属性特殊点 关键字,所以加个下划线
print(soup.find('a', class_="c2"))
# find_all 返回一个列表
print(soup.find_all('a'))
print(soup.find_all(['a', 'p'])) # 获取多个DOM
print(soup.find_all('li', limit=2))
# select方法,使用 选择器查找元素 返回一个列表
print(soup.select('a')) # 根据标签选择器
print(soup.select('.c2')) # 根据类选择器
print(soup.select('#l2')) # 根据id选择器
# 属性选择器
print(soup.select('li[id]')) # 查找li标签中有id的DOM
print(soup.select('li[id="l3"]')) # 查找li标签中id=l3的DOM
# 层级选择器
print(soup.select('div li')) # 后代选择器 包括儿子和孙子等后代 多个标签名之间用空格
print(soup.select('div > ul > li')) # 子代选择器 仅限儿子这代 多个标签名之间用 >
print(soup.select('li,p'))
# 获取节点信息
obj = soup.select('#d1')[0]
# 如果标签对象中,只有内容,那么string,get_text()都可以使用
# 如果标签对象中,除了内容还有标签,那么string就获取不到数据 而get_text()是可以获取数据
print(obj.string)
print(obj.get_text().strip())
# 节点属性获取
obj = soup.select('#p1')[0]
print(obj.name) # 获取标签名
print(obj.attrs) # 返回属性 字典类型
print(obj.attrs['id']) # 获取属性值
print(obj['id']) # 简写
print(obj.attrs.get("class")[0]) # 获取属性值
print(obj.get("class")[0]) # 简写