目录
1.bs4的安装
2.bs4的语法
(1)查找节点
(2)查找结点信息
3.bs4的操作
(1)对本地文件进行操作
(2)对服务器响应文件进行操作
4.实战
beautifulsoup:和lxml一样,是一个html的解析器,主要功能也是解析和提取数据。
优缺点:
缺点:没有lxml效率高
优点:接口更加人性化,使用方便
安装:pip install bs4
导入 from bs4 import BeautifulSoup
1.根据标签名查找节点:
soup.a 【注】只能找到第一个
soup.a.name 标签a的名字,即“a”
soup.a.attrs 标签a 的属性,即“href=”..”
2.函数
(1).find(返回一个对象)
find(‘a’):只找到第一个 a 标签
find(‘a’, title=’属性值’)
find(‘a’, class=’属性值’)
(2).find_all (返回一个列表)
find_all('a’) 查找到所有的a
find_all(['a,'span']) 返回所有的a和span
find_all('a",limit=2) 只找前两个a
(3).select(根选择器得到节点对象)【推荐】
1. element
eg:p
2..class
eg: .firstname
3.#id
eg:#firstname
4.属性选择器
[attribute]
5.层级选择器
①后代选择器:element element
div p
②子代选择器:element>element
div>p
③多项选择器:element ,element
div,p
eg:soup = soup.select("a,span')
# 根据标签名查找节点
# 注意:找到的是第一个符合条件的数据
print(soup.a) # BeautifulSoup
# 获取标签名
print(soup.a.name) # a
# 获取标签的属性和属性值
print(soup.a.attrs) # {'href': 'https://...', 'id': 'a1'}
# bs4 的一些函数
# (1)find 返回的是第一个符合条件的对象
print(soup.find('a')) # BeautifulSoup
# 根据属性值找到符合条件的标签对象
print(soup.find('a', id='a2')) #lxml
# 根据class查找标签对象,注意,class要加下划线'class_',因为这里的的class和定义类的class冲突了
print(soup.find('a',class_='link'))
# (2)findAll 返回的是所有符合条件的对象的列表
# 找到所有符合条件的标签对象
print(soup.findAll('a')) # [BeautifulSoup, lxml]
# 获取多个标签,需要在 findAll中添加列表的数据
print(soup.findAll(['a','span'])) # [BeautifulSoup, demo, lxml]
# 找前几个符合条件的数据
print(soup.findAll('a',limit=1))
# (3)select
# select 返回的是所有符合条件的对象列表
print(soup.select('a')) # [BeautifulSoup, lxml]
# 可以通过 '.' 代表 class,我们把这种操作叫做类选择器
print(soup.select('.link')) # [BeautifulSoup]
print(soup.select('#a1')) # [BeautifulSoup]
# 属性选择器 通过属性来寻找对应的标签
# 查找标签中有class的标签
print(soup.select('li[class]')) # [ 北京 , 上海 ]
# 查找标签中 id 为 l2 的标签
print(soup.select('li[id="l2"]')) # [ 上海 ]
# 层级选择器
# 后代选择器
# 找到 div 下面的 li
print(soup.select('div li')) # [北京 , 上海 , 广州 , 深圳 ]
# 子代选择器
# 某标签的第一级子标签
print(soup.select('div > ul > li')) # [北京 , 上海 , 广州 , 深圳 ]
# 找到 a 标签 和 li 标签的所有对象
print(soup.select('a, li')) # [北京 , 上海 , 广州 , 深圳 , BeautifulSoup, lxml]
1.获取节点内容: 适用于标签中嵌套标签的结构
obj.string
obj.get_text()[推荐]
2.节点的属性
tag.name 获取标签名
eg:tag=find("li)
print(tag.name)
tag.attrs将属性值作为一个字典返回
3.获取节点属性
obj.attrs.get('title')[常用]
obj.get('title')
obj['title"]
# 节点信息
# 获取节点内容
obj = soup.select('#d2')
# 如果 标签对象中只有内容,那string和get_text(),如果标签对象中,除了内容还有标签,那string就获取不到数据,而get_text()可以获取到数据
# 推荐使用 get_text()
print(obj[0].string)
print(obj[0].get_text())
# 节点的属性
# 标签的名字
obj = soup.select('#p1')
print(obj[0].name) # p
# 将属性值作为一个字典返回
print(obj[0].attrs) # {'id': 'p1', 'class': ['p1']}
# 获取节点的属性
obj = soup.select('#p1')[0]
print(obj.attrs.get('class')) # ['p1']
print(obj.get('class')) # ['p1']
print(obj['class']) # ['p1']
HTML文件
Title
- 北京
- 上海
- 广州
- 深圳
BeautifulSoup
demo
lxml
temp
id和class都是p1怎么办
bs4可以对服务器响应文件和本地文件进行操作
(1)服务器响应的文件生成对象
soup = BeautifulSoup(response.read().decode(),’lxml’)
(2)本地文件生成对象
soup = BeautifulSoup(open(‘1.html’),’lxml’
from bs4 import BeautifulSoup
# 通过解析本地文件讲解bs4 的基本语法
soup = BeautifulSoup(open('_075.html','r',encoding='utf-8'),'lxml')
import urllib.request
url = 'https://www.starbucks.com.cn/menu/'
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8')
from bs4 import BeautifulSoup
# 通过解析本地文件讲解bs4 的基本语法
soup = BeautifulSoup(content,'lxml')
获取豆瓣评分的 Top250。
from bs4 import BeautifulSoup
import requests
# 小demo
# content = requests.get("http://books.toscrape.com/").text
# # html.parser 指定解析器,说明我们正在解析html内容
# soup = BeautifulSoup(content,"html.parser")
# # findAll返回一个可迭代对象
# # 通过特有class查找元素
# all_price = soup.findAll("p",attrs={"class": "price_color"})
# # print(all_price)
# for i in all_price:
# # 只想要数字,不想要标签,调用string属性
# print(i.string)
# # 根据共有标签查找元素
# all_title = soup.findAll("h3")
# for i in all_title:
# all_a = soup.findAll("a")
# # # 如果该标签下只有一个元素,那就直接用find提取这个元素就ok了,这样就能少写一个循环
# # a = soup.find("a")
# for link in all_a:
# print(link.string)
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.76"
}
for start_num in range(0,250,25):
response = requests.get(f'https://movie.douban.com/top250?start={start_num}', headers = headers)
html = response.text
soup = BeautifulSoup(html,"html.parser")
all_title = soup.findAll("span",attrs={"class":"title"})
for title in all_title:
title_string = title.string
if "/" not in title_string:
print(title_string)
参考
尚硅谷Python爬虫教程小白零基础速通(含python基础+爬虫案例)