BeautifulSoup深入学习

BeautifulSoup深入学习

简介

BeautifulSoup是python的一个库,其提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
BeautifulSoup4和lxml一样,BeautifulSoup也是一个HTML/XML的解析器,主要的功能也是如何解析和提取HTML/XML数据。
BeautifulSoup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。
BeautifulSoup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,比如lxml,如果我们不安装它,则Python会使用Python默认的解析器,lxml解析器更加强大,速度更快,推荐使用lxml解析器。

安装

pip install beautifulsoup

导入

import requests
from bs4 import BeautifulSoup as bs

准备Html脚本

# 定义一串html格式的字符串或用request方法读取一个html页面
html = '''
<!doctype html>
<html lang="en"><head><title class='title'>html示例</title></head>
<body>
<div><!-- 注释信息 --></div>
<a href="http://www.baidu.com" target="_blank">百度一下</a> 
<p class="p1">同一个世界 <span>爱学习</span><span>爱运动</span></p>
<p class="p2">同一个梦想</p> 
</body>
</html>
'''

解析脚本

使用python内置的html解析器解析html代码,速度慢
使用lxml库解析html代码:速度快


soup = bs(html,'lxml')
#soup = bs(html,'html.parser')

输出结果

通过soup.prettify()方法对我们的字符串格式化,会自动进行缩进处理,这样提高美观性,而且说明里面包含的库有利于我们提取内容。

print(soup.prettify())  #注意一定要用print方法观察,直接调用prettify()方法看不到美化结果。
<!DOCTYPE html>
<html lang="en">
 <head>
  <title class="title">
   html示例
  </title>
 </head>
 <body>
  <div>
   <!-- 注释信息 -->
  </div>
  <a href="http://www.baidu.com" target="_blank">
   百度一下
  </a>
  <p class="p1">
   同一个世界
   <span>
    爱学习
   </span>
   <span>
    爱运动
   </span>
  </p>
  <p class="p2">
   同一个梦想
  </p>
 </body>
</html>

四大对象种类

BeautifulSoup能够将复杂的HTML转换成为一个复杂的树形结构,其中每个节点都是python对象,所有这些对象可以分类4大类,分别为:
Tag
NavigableString
BeautifulSoup
Comment

(1)Tag

Tag就是HTML中的一个个标签,如a标签、title标签等,具体的tag就是一个包含内部内容的整个标签对。
其有两个属性,name和attrs。name属性返回标签的名字,attrs属性返回标签的属性字典。
注意其返回的是第一个满足条件的标签。

print(soup.p)
print(soup.p.name)
print(soup.p.attrs)
print(soup.a.attrs)
<p class="p1">同一个世界 <span>爱学习</span><span>爱运动</span></p>
p
{'class': ['p1']}
{'href': 'http://www.baidu.com', 'target': '_blank'}
print(soup.a['href'])
print(soup.a['target'])
http://www.baidu.com
_blank

(2)NavigableString

以上可知利用标签的attrs参数可以获得标签的属性内容,对标签对内部的内容的获取,只需要在标签后加.string或strings即可。
如果一个标签中包含了多个或多级子标签,返回的是一个标签内容的迭代器,包含了其下层所有标签的内容,可用list函数返回其列表形式。

print(soup.title.string)
print(soup.a.string)
print(list(soup.p.strings))
print(list(soup.html.strings))
html示例
百度一下
['同一个世界 ', '爱学习', '爱运动']
['html示例', '\n', '\n', '\n', '百度一下', '\n', '同一个世界 ', '爱学习', '爱运动', '\n', '同一个梦想', '\n', '\n']
由此看出string就是获取标签内的内容,strings就是获取多个内容。
当内容仅有一个嵌套,依旧会获取那个嵌套里的内容。
当内容里还嵌套几个标签,就需要用strings,否则就会出错返回None

(3)BeautifulSoup对象

BeautifulSoup对象表示的是一个文档的内容。大部分时候,可以把它当作Tag对象,是一个特殊的Tag,
我们可以分别获取它的类型,名称,以及属性

print(type(soup))
print(soup.name)
print(soup.attrs)
<class 'bs4.BeautifulSoup'>
[document]
{}

(4)Comment

Comment对象是一个特殊类型的NavigableString对象,其实输出的内容是不包括注释符号,以下面带注释的标签为例:
在这里插入图片描述

print(soup.div.string)
 注释信息 

可见a标签中包含的内容时一个注释,但.string的值确实不带有注释符号,其类型为Comment。

其他常用属性方法

content 和 contents

以上可用看到使用string或strings会过滤其子标签,仅包含各级标签间的内容
如果要获取标签对间的完整内容,可通过contents获取,以列表的形式返回。

print(soup.title.contents)
print(soup.p.contents)
print(list(soup.p.contents))
print(soup.p.contents[0])
['html示例']
['同一个世界 ', <span>爱学习</span>, <span>爱运动</span>]
['同一个世界 ', <span>爱学习</span>, <span>爱运动</span>]
同一个世界 

children

# 可以通过children获取tag的子节点列表,子节点以list_iterator的方式输出
print(soup.p.children)
print(list(soup.p.children))
<list_iterator object at 0x0000017ACCC54670>
['同一个世界 ', <span>爱学习</span>, <span>爱运动</span>]

可以看出contents属性是以列表方式输出,而children属性以列表迭代器输出,需要用list方式输出,不过两种方法都可以通过list输出。而且两者的功能是有点类似的。

parent 和 parents

# 父节点
print(soup.p.parent)
print("---------------")
# span的父节点
print(soup.span.parent)
print("---------------")
# 所有父节点
print(list(soup.span.parents))
print("---------------")
# 对其所有父节点进行遍历。
for parent in soup.span.parents:
    if parent is None:
        print(parent)
    else:
        print(parent.name)
<body>
<div><!-- 注释信息 --></div>
<a href="http://www.baidu.com" target="_blank">百度一下</a>
<p class="p1">同一个世界 <span>爱学习</span><span>爱运动</span></p>
<p class="p2">同一个梦想</p>
</body>
---------------
<p class="p1">同一个世界 <span>爱学习</span><span>爱运动</span></p>
---------------
[<p class="p1">同一个世界 <span>爱学习</span><span>爱运动</span></p>, <body>
<div><!-- 注释信息 --></div>
<a href="http://www.baidu.com" target="_blank">百度一下</a>
<p class="p1">同一个世界 <span>爱学习</span><span>爱运动</span></p>
<p class="p2">同一个梦想</p>
</body>, <html lang="en"><head><title class="title">html示例</title></head>
<body>
<div><!-- 注释信息 --></div>
<a href="http://www.baidu.com" target="_blank">百度一下</a>
<p class="p1">同一个世界 <span>爱学习</span><span>爱运动</span></p>
<p class="p2">同一个梦想</p>
</body>
</html>, <!DOCTYPE html>
<html lang="en"><head><title class="title">html示例</title></head>
<body>
<div><!-- 注释信息 --></div>
<a href="http://www.baidu.com" target="_blank">百度一下</a>
<p class="p1">同一个世界 <span>爱学习</span><span>爱运动</span></p>
<p class="p2">同一个梦想</p>
</body>
</html>
]
---------------
p
body
html
[document]

通过 .parent 属性来获取某个元素的父节点
通过元素的. parents 属性可以递归得到元素的所有父辈节点
不能直接用parents属性,需要通过循环遍历输出

## find() 和 find_all()
find()找出满足条件的第一个标签
find_all()找出满足条件的所有标签,以列表的形式返回
格式:find_all(name , attrs , recursive , text , **kwargs)
find_all是爬虫常用的方法。
print(soup.find('p'))
print(soup.find_all('title'))
print(soup.find_all('p'))
# 由于class是python的关键词,所以这里默认为class_
print(soup.find_all(class_='p2'))
<p class="p1">同一个世界 <span>爱学习</span><span>爱运动</span></p>
[<title class="title">html示例</title>]
[<p class="p1">同一个世界 <span>爱学习</span><span>爱运动</span></p>, <p class="p2">同一个梦想</p>]
[<p class="p2">同一个梦想</p>]

select()选择器

我们在写 CSS 时,标签名不加任何修饰,类名前加点,id 名前加 #,在这里我们也可以利用类似的方法来筛选元素,用到的方法是 soup.select(),返回类型是 list,这个也是用得比较频繁的!

标签名
类名
id号
组合查找
属性查找
注意:select完之后获得的是列表,一般用get_text()方法来获取它的内容。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值