网页信息解析--BeautifulSoup库

BeautifulSoup库简介

我们在使用requests库获得一个网页的信息后,只能够得到对应的网页内容要想要从这些网页内容中获得有用的信息,便需要对网页信息进行解析
BeautifulSoup库是解析、遍历、维护‘标签树’的功能库

<p class="title"></p>	<!-- 一个标签-->

BeutifulSoup的基本元素

基本元素描述对应属性
Tag标签,最基本的信息组成单元,分别用<>和</>标明开头和结尾
Name标签名,如p<tag>.name
Attributes标签的属性,字典形式组织<tag>.attrs
NavigableString标签内非属性字符串,<>…</>中字符串<tag>.string
Comment标签内字符串注释部分,一种特殊的Comment类型

下面我们使用一个html文档来解释bs库中的基本元素

<!DOCTYPE html>
<html lang="en">
<body>
    <br/>
    <div name="div2" style="text-align:center">
        <image alt="div2-img2" src="http://www.baidu.com/img/bdligo.png" href="http://www.baidu.com"></image></br>
        <a href="http://www.baidu.com">百度搜索</a>
    </div>
</body>
</html>

标签(tag)和名称(name)
在这里插入图片描述

属性attrs
在这里插入图片描述

文本信息(string)和注释(comments)
在这里插入图片描述

BeautifulSoup支持的解析器

解析器使用格式需安装的库
bs4的HTML解析器Beautifulsoup(mk,'html.parser')bs4
lxml的HTML解析器Beautifulsoup(mk,'lxml')lxml
lxml的XML解析器Beautifulsoup(mk,'xml')lxml
html5lib的解析器Beautifulsoup(mk,'html5lib')html5lib

注:mk为makeup,可以是一段标签,也可以是一个打开的html文档

基于bs4库的html文本遍历方法

当我们想要的节点不好定位时,可以找到目标节点的附近节点,通过这些附近节点来找到目标节点,这就需要使用到遍历方法来获取附近节点

下行遍历

属性类型描述
next_element字符串返回下一个节点
contents包含子节点列表将所有子节点存入一个列表并返回
.children生成器(包含子节点)将所有子节点(只包含直接子节点)存入一个迭代器并返回
.descendants生成器(包含子节点)包含所有子孙节点,用于循环遍历

下行遍历方法

下行遍历方法
soup.body.contents[n]		# body子节点列表中,索引值为n的节点
for child in soup.body.children:		# 遍历儿子节点
	print(child)
for chile in soup.body.descendants:		# 遍历子孙节点
	print(child)

上行遍历

属性类型描述
previous_elements字符串返回上一个节点
parent字符串返回节点的父亲节点
parents生成器对象返回所有先辈节点
soup.a.parent		# 返回标签a的parent节点
soup.parent		# soup是一个特殊的节点,它的parent为空
soup.html.parent		# html是最高的parent,它的parent是自己
for parent in soup.a.parents:		# 输出a的所有parent节点
	if parent is None:
		print(parent)
	else:
		print(parent.name)	

平行遍历

平行遍历发生在同一个父节点下的个节点之间

属性类型描述
next_sibling字符串返回下一个平行节点标签
previous_sibling字符串返回上一个平行节点标签
next_siblings生成器返回后续所有平行节点标签
previous_siblings生成器返回前序所有平行节点标签
for sibling in soup.a.next_siblings:
	print(sibling)
for sibling in soup.a.previous_siblings:
	print(sibling)	

基于bs4库的格式化和编码

prettify方法,用于把要解析的字符串以标准的缩进格式输出,并且自动更正
我们以下面的一段html代码为例

<ul><li>列表中的第一项</li><li>列表中的第二项</li></ul>

代码实现

from bs4 import BeautifulSoup
soup=BeautifulSoup('<ul><li>列表中的第一项</li><li>列表中的第二项</li></ul>','html.parser')
print(soup.prettify())

代码执行结果

<ul>
 <li>
  列表中的第一项
 </li>
 <li>
  列表中的第二项
 </li>
</ul>

基于bs4的html内容查找方法

常用方法–**find_all()**方法

<>.find_all(name=None,attrs={},recursive=True/False,string=None,**kwargs)

返回一个列表类型存储查找结果

参数描述表示形式
name标签名称的检索字符串一个(‘a’)、多个[‘a’,‘b’]或所有(True),(带入正则表达式re.complie())
attrs标签属性值的检索字符串,可标记属性检索模糊查找(带入正则表达式re.complie()),也可以直接指定一个属性值进行过滤,如href=‘http://www.baidu.com’(class要写成class_)
recursive是否针对子孙所有节点进行搜索,默认Truesoup.find_all('a'),若将该参数设为Flase,则返回空列表因为soup子节点下没有a标签
string对尖括号中的文本内容进行检索string='python',则结果返回返回'python'(带入正则表达式re.complie())
**kwargs其它形参如limit=None,用于限制返回结果的数量

find_all()方法的扩展方法

方法描述类型参数是否与find_all()相同
find()搜索只返回一个结果字符串
find_parents()在先辈节点中搜索列表
find_parent()在先辈节点中搜索字符串
find_next_siblings()后续平行节点搜索列表
find_next_sibling()后续平行节点中返回一个结果字符串
find_previous_siblings()前序平行节点中搜索列表
find_previous_sibling()前序平行节点中搜索,返回一个结果字符串

BeautfulSoup解析网页实践

案例1:爬取豆瓣top250电影排数据

import requests,bs4,re

url='https://movie.douban.com/top250'
headers={'user-agent':'Mozzlia/5.0'}
response=requests.get(url,headers=headers)
print(response.status_code)	# 检测是否请求成功

soup=bs4.BeautifulSoup(response.text,'html.parser')	# “煲一锅汤”
ol=soup.find('ol',attrs={'class':"grid_view"})		# 找到ol节点作为起始定位点
li_list = ol.find_all('li')		# 找到列表的节点名称
movie_info=[]

for li in li_list:
    # name = detail.find('span')
    name = li.find('span', class_='title').get_text()		# get_text()函数用于从html中提取文本
    hot = str(li.find(text=re.compile('\d+人评价')))		# 使用re库进行模糊匹配
    star=li.find('span',class_='rating_num').get_text()
    quote=li.find('span',class_='inq').get_text()
    # print(name,hot,star,quote)
    movie_info.append((name,hot,star,quote))		# 将获得的信息进入列表进行存储
for movie in movie_info:
    print(movie)

代码执行结果
在这里插入图片描述

案例2:爬取微博热搜榜单

import requests
from bs4 import BeautifulSoup

url='https://s.weibo.com/top/summary'
headers={'user-agent':'Mozzila/5.0'}
resp=requests.get(url,headers=headers)


soup=BeautifulSoup(resp.text,'html.parser')	# “煲一锅汤”
thead=soup.find('table')		# 找到table节点作为起始定位点
trs=thead.find_all('tr')		# 找到列表的节点名称

for tr in trs:
    topic=tr.find('a')
    if tr.find('span')==None:		# 如果没有热度就跳过此次循环
        continue
    else:
        hot=tr.find('span').get_text()
    print(topic.get_text(),hot)

代码执行结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夺笋123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值