首页 > 编程语言 >33. Python BS4解析库

33. Python BS4解析库

时间:2022-09-21 14:23:44浏览次数:91  
标签:BS4 教程 soup 33 Python html 文档 print find

1. 前言

Beautiful Soup 简称 BS4(其中 4 表示版本号)是一个 Python 第三方库,它可以从 HTML 或 XML 文档中快速地提取指定的数据。Beautiful Soup 语法简单,使用方便,并且容易理解,因此您可以快速地学习并掌握它。本节我们讲解 BS4 的基本语法。

beautiful soup库(bs4)
图1:BS4官网LOGO图

2. BS4下载安装

由于 Bautiful Soup 是第三方库,因此需要单独下载,下载方式非常简单,执行以下命令即可安装:

pip install bs4

由于 BS4 解析页面时需要依赖文档解析器,所以还需要安装 lxml 作为解析库:

pip install lxml

Python 也自带了一个文档解析库 html.parser, 但是其解析速度要稍慢于 lxml。除了上述解析器外,还可以使用 html5lib 解析器,安装方式如下:

pip install html5lib

该解析器生成 HTML 格式的文档,但速度较慢。

“解析器容错”指的是被解析的文档发生错误或不符合格式时,通过解析器的容错性仍然可以按照既定的正确格式实现解析。

3. BS4解析对象

创建 BS4 解析对象是万事开头的第一步,这非常地简单,语法格式如下所示:

#导入解析包
from bs4 import BeautifulSoup
#创建beautifulsoup解析对象
soup = BeautifulSoup(html_doc, 'html.parser')

上述代码中,html_doc 表示要解析的文档,而 html.parser 表示解析文档时所用的解析器,此处的解析器也可以是 'lxml' 或者 'html5lib',示例代码如下所示:

 
#coding:utf8
html_doc = """
<html><head><title>"c语言中文网"</title></head>
<body>
<p class="title"><b>c.biancheng.net</b></p>
<p class="website">一个学习编程的网站
<a href="http://c.biancheng.net/python/" id="link1">python教程</a>
<a href="http://c.biancheng.net/c/" id="link2">c语言教程</a>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')
#prettify()用于格式化输出html/xml文档
print(soup.prettify())

输出结果:

<html>
<head>
  <title>
   "c语言中文网"
  </title>
</head>
<body>
  <p class="title">
   <b>
    c.biancheng.net
   </b>
  </p>
  <p class="website">
   一个学习编程的网站
   <a href="http://c.biancheng.net/python/" id="link1">
    python教程
   </a>
   <a href="http://c.biancheng.net/c/" id="link2">
    c语言教程
   </a>
</body>
</html>

如果是外部文档,您也可以通过 open() 的方式打开读取,语法格式如下:

soup = BeautifulSoup(open('html_doc.html', encoding='utf8'), 'lxml')

4. BS4常用语法

下面对爬虫中经常用到的 BS4 解析方法做详细介绍。

Beautiful Soup 将 HTML 文档转换成一个树形结构,该结构有利于快速地遍历和搜索 HTML 文档。下面使用树状结构来描述一段 HTML 文档:

<html><head><title>c语言中文网</title></head><h1>c.biancheng.net</h1><p><b>一个学习编程的网站</b></p></body></html>

树状图如下所示:

HTML文档树结构图
图1:HTML文档树结构图
 

文档树中的每个节点都是 Python 对象,这些对象大致分为四类:Tag , NavigableString , BeautifulSoup , Comment 。其中使用最多的是 Tag 和 NavigableString。

  • Tag:标签类,HTML 文档中所有的标签都可以看做 Tag 对象。
  • NavigableString:字符串类,指的是标签中的文本内容,使用 text、string、strings 来获取文本内容。
  • BeautifulSoup:表示一个 HTML 文档的全部内容,您可以把它当作一个人特殊的 Tag 对象。
  • Comment:表示 HTML 文档中的注释内容以及特殊字符串,它是一个特殊的 NavigableString。

1) Tag节点

标签(Tag)是组成 HTML 文档的基本元素。在 BS4 中,通过标签名和标签属性可以提取出想要的内容。看一组简单的示例

from bs4 import BeautifulSoup
soup = BeautifulSoup('<p class="Web site url"><b>c.biancheng.net</b></p>', 'html.parser')
#获取整个p标签的html代码
print(soup.p)
#获取b标签
print(soup.p.b)
#获取p标签内容,使用NavigableString类中的string、text、get_text()
print(soup.p.text)
#返回一个字典,里面是多有属性和值
print(soup.p.attrs)
#查看返回的数据类型
print(type(soup.p))
#根据属性,获取标签的属性值,返回值为列表
print(soup.p['class'])
#给class属性赋值,此时属性值由列表转换为字符串
soup.p['class']=['Web','Site']
print(soup.p)

输出结果如下:

soup.p输出结果:
<p class="Web site url"><b>c.biancheng.net</b></p>

soup.p.b输出结果:
<b>c.biancheng.net</b>

soup.p.text输出结果:
c.biancheng.net

soup.p.attrs输出结果:
{'class': ['Web', 'site', 'url']}

type(soup.p)输出结果:
<class 'bs4.element.Tag'>

soup.p['class']输出结果:
['Web', 'site', 'url']

class属性重新赋值:
<p class="Web Site"><b>c.biancheng.net</b></p>

5. 遍历节点

Tag 对象提供了许多遍历 tag 节点的属性,比如 contents、children 用来遍历子节点;parent 与 parents 用来遍历父节点;而 next_sibling 与 previous_sibling 则用来遍历兄弟节点 。示例如下:

#coding:utf8
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>"c语言中文网"</title></head>
<body>
<p class="title"><b>c.biancheng.net</b></p>
<p class="website">一个学习编程的网站</p>
<a href="http://c.biancheng.net/python/" id="link1">python教程</a>,
<a href="http://c.biancheng.net/c/" id="link2">c语言教程</a> and
"""
soup = BeautifulSoup(html_doc, 'html.parser')
body_tag=soup.body
print(body_tag)
#以列表的形式输出,所有子节点
print(body_tag.contents)

输出结果:

<body>
<p class="title"><b>c.biancheng.net</b></p>
<p class="website">一个学习编程的网站</p>
<a href="http://c.biancheng.net/python/" id="link1">python教程</a>,
<a href="http://c.biancheng.net/c/" id="link2">c语言教程</a> and
</body>
#以列表的形式输出
['\n', <p class="title"><b>c.biancheng.net</b></p>, '\n', <p class="website">一个学习编程的网站</p>, '\n', <a href="http://c.biancheng.net/python/" id="link1">python教程</a>, '\n', <a href="http://c.biancheng.net/c/" id="link2">c语言教程</a>, '\n']

Tag 的 children 属性会生成一个可迭代对象,可以用来遍历子节点,示例如下:

for child in body_tag.children:
    print(child)

输出结果:

#注意此处已将换行符"\n"省略
<p class="title"><b>c.biancheng.net</b></p>
<p class="website">一个学习编程的网站</p>

想了解更多相关示例可参考官方文档:点击前往

6. find_all()与find()

find_all() 与 find() 是解析 HTML 文档的常用方法,它们可以在 HTML 文档中按照一定的条件(相当于过滤器)查找所需内容。find() 与 find_all() 的语法格式相似,希望大家在学习的时候,可以举一反三。

BS4 库中定义了许多用于搜索的方法,find() 与 find_all() 是最为关键的两个方法,其余方法的参数和使用与其类似。

1) find_all()

find_all() 方法用来搜索当前 tag 的所有子节点,并判断这些节点是否符合过滤条件,最后以列表形式将符合条件的内容返回,语法格式如下:

find_all( name , attrs , recursive , text , limit )

参数说明:

  • name:查找所有名字为 name 的 tag 标签,字符串对象会被自动忽略。
  • attrs:按照属性名和属性值搜索 tag 标签,注意由于 class 是 Python 的关键字吗,所以要使用 "class_"。
  • recursive:find_all() 会搜索 tag 的所有子孙节点,设置 recursive=False 可以只搜索 tag 的直接子节点。
  • text:用来搜文档中的字符串内容,该参数可以接受字符串 、正则表达式 、列表、True。
  • limit:由于 find_all() 会返回所有的搜索结果,这样会影响执行效率,通过 limit 参数可以限制返回结果的数量。


find_all() 使用示例如下:

from bs4 import BeautifulSoup
import re
html_doc = """
<html><head><title>"c语言中文网"</title></head>
<body>
<p class="title"><b>c.biancheng.net</b></p>
<p class="website">一个学习编程的网站</p>
<a href="http://c.biancheng.net/python/" id="link1">python教程</a>
<a href="http://c.biancheng.net/c/" id="link2">c语言教程</a>
<a href="http://c.biancheng.net/django/" id="link3">django教程</a>
<p class="vip">加入我们阅读所有教程</p>
<a href="http://vip.biancheng.net/?from=index" id="link4">成为vip</a>
"""
#创建soup解析对象
soup = BeautifulSoup(html_doc, 'html.parser')
#查找所有a标签并返回
print(soup.find_all("a"))
#查找前两条a标签并返回
print(soup.find_all("a",limit=2))
#只返回两条a标签

最后以列表的形式返回输出结果,如下所示:

[<a href="http://c.biancheng.net/python/" id="link1">python教程</a>, <a href="http://c.biancheng.net/c/" id="link2">c语言教程</a>, <a href="http://c.biancheng.net/django/" id="link3">django教程</a>, <a href="http://vip.biancheng.net/?from=index" id="link4">成为vip</a>]

[<a href="http://c.biancheng.net/python/" id="link1">python教程</a>, <a href="http://c.biancheng.net/c/" id="link2">c语言教程</a>]

按照标签属性以及属性值查找 HTML 文档,如下所示

print(soup.find_all("p",class_="website"))
print(soup.find_all(id="link4"))

输出结果:

[<p class="website">一个学习编程的网站</p>]
[<a href="http://vip.biancheng.net/?from=index" id="link4">成为vip</a>]

正则表达式、列表,以及 True 也可以当做过滤条件,使用示例如下:

#列表行书查找tag标签
print(soup.find_all(['b','a']))
#正则表达式匹配id属性值
print(soup.find_all('a',id=re.compile(r'.\d')))
print(soup.find_all(id=True))
#True可以匹配任何值,下面代码会查找所有tag,并返回相应的tag名称
for tag in soup.find_all(True):
    print(tag.name,end=" ")
#输出所有以b开始的tag标签
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)

输出结果如下:

第一个print输出:
[<b>c.biancheng.net</b>, <a href="http://c.biancheng.net/python/" id="link1">python教程</a>, <a href="http://c.biancheng.net/c/" id="link2">c语言教程</a>, <a href="http://c.biancheng.net/django/" id="link3">django教程</a>, <a href="http://vip.biancheng.net/?from=index" id="link4">成为vip</a>]
第二个print输出:
[<a href="http://c.biancheng.net/python/" id="link1">python教程</a>, <a href="http://c.biancheng.net/c/" id="link2">c语言教程</a>, <a href="http://c.biancheng.net/django/" id="link3">django教程</a>, <a href="http://vip.biancheng.net/?from=index" id="link4">成为vip</a>]
第三个print输出:
[<a href="http://c.biancheng.net/python/" id="link1">python教程</a>, <a href="http://c.biancheng.net/c/" id="link2">c语言教程</a>, <a href="http://c.biancheng.net/django/" id="link3">django教程</a>, <a href="http://vip.biancheng.net/?from=index" id="link4">成为vip</a>]
第四个print输出:
html head title body p b p a a a p a
最后一个输出:
body b

BS4 为了简化代码,为 find_all() 提供了一种简化写法,如下所示:

#简化前
soup.find_all("a")
#简化后
soup("a")

 

标签:BS4,教程,soup,33,Python,html,文档,print,find
From: https://www.cnblogs.com/jiajunling/p/16715444.html

相关文章

  • 30. Python json模块
    1.前言JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,遵循欧洲计算机协会制定的JavaScript规范(简称ECMAScript)。JSON易于人阅读和编写,同时也易于机器解......
  • python 时间调度
    Prerequisite主要分为两个:查看时间任务调度查看时间fromdatetimeimportdateimporttimelocaltime=time.asctime(time.localtime(time.time())).split('')[......
  • python学习笔记:pytest单元测试框架
    一、安装配置和运行规则1、安装:pipinstallpytest查看安装版本:pytest--version 2、Pytest用例运行规则用Pytest写用例时候,一定要按照下面的规则去写,否则不符合规......
  • “Python 中的监督学习”Datacamp 课程回顾
    “Python中的监督学习”Datacamp课程回顾这是我刚刚参加的课程的回顾。这篇评论作为学习辅助:帮助我在第一次学习后综合信息,并希望将内容保留更长时间。这篇文章还提供了......
  • 用于数据准备的 Python — 探索和清理数据集
    用于数据准备的Python—探索和清理数据集什么是数据准备?数据准备是收集、组合、结构化和组织数据的过程,以便将其用于商业智能(BI)应用程序、分析和数据可视化。此......
  • 你应该知道的 Python F 字符串技巧
    Python你应该知道的PythonF字符串技巧停止打印(f”variable={variable}”)Photoby约尔格·安杰利on不飞溅早在2016年,Python3.6就引入了一种新的字符串格......
  • 力扣2(java&python)-两数相加(中等)
    题目:给你两个 非空的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表......
  • python (),[], {}的含义
    1、python()表示元组,元组是一种不可变序列1)创建如:tuple=(1,2,3)取数据tuple[0]......tuple[0,2].....tuple[1,2]......2)修改元祖:元组是不可修改的3)删除元祖del......
  • 25. [实例]Python lxml应用
    1.前言本节通过编写一个简单的爬虫程序,进一步熟悉lxml解析库的使用。下面使用lxml库抓取猫眼电影Top100榜(点击访问),编写程序的过程中,注意与《Python爬虫抓取猫眼电......
  • 24. Python lxml库的安装和使用
    1.前言lxml是Python的第三方解析库,完全使用Python语言编写,它对Xpath表达式提供了良好的支持,因此能够了高效地解析HTML/XML文档。本节讲解如何通过lxml库解析H......