简称bs4,主要功能也是解析和提取数据
缺点是效率没有lxml的效率高(xpath), 优点是接口设计人性化,使用方便
在PyCharm pip install bs4库
以此html文件为例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
<li id='l1'>张三</li>
<li id='l2'>李四</li>
<li>王五</li>
<a href="" id="" class="a1">哈哈哈</a>
<span>这是span</span>
</ul>
<a href="" title="ttt">嘿嘿嘿</a>
</body>
</html>
先打开文件,BeautifulSoup默认打开编码是gbk,所以需要指定编码方式
第二个参数是lxml,必须要有
from bs4 import BeautifulSoup
soup = BeautifulSoup(open('bs4.html', encoding='utf-8'), 'lxml')
soup.a 注:只能找到第一个a,
.attrs返回标签的属性和属性值
print(soup.a)
print(soup.a.attrs)
返回结果:哈哈哈
返回结果:{'href': '', 'id': '', 'class': ['a1']}
print(soup.find('a')) # 返回的第一个a
print(soup.find('a', title='ttt')) # 找title标签为'ttt'的a
print(soup.find('a', class_='a1')) # 找class为'a1'的a, 必须是class_
返回结果:哈哈哈
返回结果:嘿嘿嘿
返回结果:哈哈哈
print(soup.find_all('a'))
返回结果:[哈哈哈, 嘿嘿嘿]
print(soup.find_all(['a', 'span'])) #返回所有的a和span标签,要用列表
返回结果:[哈哈哈, 这是span, 嘿嘿嘿]
print(soup.find_all('li', limit=2)) # 返回前两个li标签,使用参数limit=2
返回结果:[张三 , 李四 ]
print(soup.select('a'))
返回结果:[哈哈哈, 嘿嘿嘿]
print(soup.select('.a1')) # 类选择器
print(soup.select('#l1')) # id选择器
返回结果:[哈哈哈]
返回结果:[张三 ]
# 查找到li标签中有id的标签
print(soup.select('li[id]'))
返回结果:[张三 , 李四 ]
# 查找到li标签中有id为'l2'的标签
print(soup.select('li[id="l2"]'))
返回结果:[李四 ]
给刚才的html页面的ul标签嵌套一层div
<body>
<div>
<ul>
<li id="l1" class="c1">张三</li>
<li id="l2">李四</li>
<li>王五</li>
<a href="" id="" class="a1">哈哈哈</a>
<span>这是span</span>
</ul>
</div>
<a href="" title="ttt">嘿嘿嘿</a>
<div id="d1">
<span>
这是内容
</span>
</div>
</body>
后代选择器
# 找到div下面所有的li
print(soup.select('div li'))
返回结果:[张三 , 李四 , 王五 ]
子代选择器
# 找到div下面的li
print(soup.select('div > ul > li'))
返回结果:[张三 , 李四 , 王五 ]
组合选择器(不需要列表,直接“,”隔开)
# 找到a标签和li标签的所有的对象
print(soup.select('a,li'))
返回结果:[张三 , 李四 , 王五 , 哈哈哈, 嘿嘿嘿]
如果标签对象中只有内容,那么string和get_text()都可以使用
如果标签对象中除了内容,还有其他标签,string不可以而get_text()可以获取到数据
一般情况下,推荐使用get_text()
# 先找到对象
obj = soup.select('#d1')[0]
# print(obj.string)
print(obj.get_text())
obj = soup.select('#l1')[0]
# attrs将属性值作为一个字典返回
print(obj.attrs)
返回结果:{'id': 'l1', 'class': ['c1']}
obj = soup.select('#l1')[0]
print(obj.attrs.get('class')) # 推荐
print(obj.get('class'))
print(obj['class'])
返回结果:['c1']
['c1']
['c1']
import urllib.request
from bs4 import BeautifulSoup
url = 'https://www.starbucks.com.cn/menu/'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/98.0.4758.102 Safari/537.36 "
}
request = urllib.request.Request(url=url, headers=headers)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
soup = BeautifulSoup(content, 'lxml')
name_list = soup.select('ul[class="grid padded-3 product"] strong')
# name_list = soup.select('div strong')) # 也可以
for name in name_list:
print(name.get_text())