爬虫解析-BeautifulSoup-bs4(七)
目录
beautifulsoup:和lxml一样,是一个html的解析器,主要功能也是解析和提取数据。
优缺点:
????????缺点:没有lxml效率高
????????优点:接口更加人性化,使用方便
1.bs4的安装
安装:pip install bs4
导入 from bs4 import BeautifulSoup
2.bs4的语法
(1)查找节点
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) # <a href="https://..." id="a1">BeautifulSoup</a>
# 获取标签名
print(soup.a.name) # a
# 获取标签的属性和属性值
print(soup.a.attrs) # {'href': 'https://...', 'id': 'a1'}
# bs4 的一些函数
# (1)find 返回的是第一个符合条件的对象
print(soup.find('a')) # <a href="https://..." id="a1">BeautifulSoup</a>
# 根据属性值找到符合条件的标签对象
print(soup.find('a', id='a2')) #<a href="http://..." id="a2">lxml</a>
# 根据class查找标签对象,注意,class要加下划线'class_',因为这里的的class和定义类的class冲突了
print(soup.find('a',class_='link'))
# (2)findAll 返回的是所有符合条件的对象的列表
# 找到所有符合条件的标签对象
print(soup.findAll('a')) # [<a class="link" href="https://..." id="a1">BeautifulSoup</a>, <a href="http://..." id="a2">lxml</a>]
# 获取多个标签,需要在 findAll中添加列表的数据
print(soup.findAll(['a','span'])) # [<a class="link" href="https://..." id="a1">BeautifulSoup</a>, <span>demo</span>, <a href="http://..." id="a2">lxml</a>]
# 找前几个符合条件的数据
print(soup.findAll('a',limit=1))
# (3)select
# select 返回的是所有符合条件的对象列表
print(soup.select('a')) # [<a class="link" href="https://..." id="a1">BeautifulSoup</a>, <a href="http://..." id="a2">lxml</a>]
# 可以通过 '.' 代表 class,我们把这种操作叫做类选择器
print(soup.select('.link')) # [<a class="link" href="https://..." id="a1">BeautifulSoup</a>]
print(soup.select('#a1')) # [<a class="link" href="https://..." id="a1">BeautifulSoup</a>]
# 属性选择器 通过属性来寻找对应的标签
# 查找<li>标签中有class的标签
print(soup.select('li[class]')) # [<li class="c1" id="l1">北京</li>, <li class="c2" id="l2">上海</li>]
# 查找<li>标签中 id 为 l2 的标签
print(soup.select('li[id="l2"]')) # [<li class="c2" id="l2">上海</li>]
# 层级选择器
# 后代选择器
# 找到 div 下面的 li
print(soup.select('div li')) # [<li class="c1" id="l1">北京</li>, <li class="c2" id="l2">上海</li>, <li id="s1">广州</li>, <li id="s2">深圳</li>]
# 子代选择器
# 某标签的第一级子标签
print(soup.select('div > ul > li')) # [<li class="c1" id="l1">北京</li>, <li class="c2" id="l2">上海</li>, <li id="s1">广州</li>, <li id="s2">深圳</li>]
# 找到 a 标签 和 li 标签的所有对象
print(soup.select('a, li')) # [<li class="c1" id="l1">北京</li>, <li class="c2" id="l2">上海</li>, <li id="s1">广州</li>, <li id="s2">深圳</li>, <a class="link" href="https://..." id="a1">BeautifulSoup</a>, <a href="http://..." id="a2">lxml</a>]
?(2)查找结点信息
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文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<div>
<ul>
<li id='l1' class="c1">北京</li>
<li id="l2" class="c2">上海</li>
<li id="s1">广州</li>
<li id="s2">深圳</li>
<a href="https://..." id="a1" class="link">BeautifulSoup</a>
<span>demo</span>
</ul>
</div>
<a href="http://..." id="a2">lxml</a>
<div id = 'd2'>
<span>temp</span>
</div>
<p id="p1" class="p1">id和class都是p1怎么办</p>
</body>
</html>
3.bs4的操作
bs4可以对服务器响应文件和本地文件进行操作
(1)服务器响应的文件生成对象
soup = BeautifulSoup(response.read().decode(),’lxml’)
(2)本地文件生成对象
soup = BeautifulSoup(open(‘1.html’),’lxml’
(1)对本地文件进行操作
from bs4 import BeautifulSoup
# 通过解析本地文件讲解bs4 的基本语法
soup = BeautifulSoup(open('_075.html','r',encoding='utf-8'),'lxml')
(2)对服务器响应文件进行操作
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')
4.实战
获取豆瓣评分的 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")
# # # 如果该标签下只有一个<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)
参考
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!