Python BS4解析库用法详解

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

beautiful soup库(bs4)

图1:BS4官网LOGO图

BS4下载安装

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

pip install bs4

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

pip install lxml

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

pip install html5lib

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

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

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网站站点" rel="nofollow" />

<html>

<head>

<title>

"c语言中文网"

</title>

</head>

<body>

<p class="title">

<b>

c.biancheng网站站点" rel="nofollow" />

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

BS4常用语法

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

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

<html><head><title>c语言中文网</title></head><h1>c.biancheng网站站点" rel="nofollow" /> 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网站站点" rel="nofollow" />

soup.p输出结果:

<p class="Web site url"><b>c.biancheng网站站点" rel="nofollow" />

#coding:utf8

from bs4 import BeautifulSoup

html_doc = """

<html><head><title>"c语言中文网"</title></head>

<body>

<p class="title"><b>c.biancheng网站站点" rel="nofollow" />

<body>

<p class="title"><b>c.biancheng网站站点" rel="nofollow" />

for child in body_tag.children:

print(child)

输出结果:

#注意此处已将换行符"\n"省略

<p class="title"><b>c.biancheng网站站点" rel="nofollow" />

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网站站点" rel="nofollow" />

[<a href="http://c.biancheng网站站点" rel="nofollow" />

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

print(soup.find_all(id="link4"))

输出结果:

[<p class="website">一个学习编程的网站</p>]

[<a href="http://vip.biancheng网站站点" rel="nofollow" />

#列表行书查找tag标签

print(soup.find_all(['b','a']))

#正则表达式匹配id属性值

print(soup.find_all('a',id=r网站站点" rel="nofollow" />

个print输出:

[<b>c.biancheng网站站点" rel="nofollow" />

#简化前

soup.find_all("a")

#简化后

soup("a")

上述两种的方法的输出结果是相同的。

2) find()

find() 方法与 find_all() 类似,不同之处在于 find_all() 会将文档中所有符条件的结果返回,而 find() 仅返回一个符条件的结果,所以 find() 方法没有limit参数。使用示例如下:

from bs4 import BeautifulSoup

import re

html_doc = """

<html><head><title>"c语言中文网"</title></head>

<body>

<p class="title"><b>c.biancheng网站站点" rel="nofollow" />

a标签:

<a href="http://c.biancheng网站站点" rel="nofollow" />

print(soup.find('bdi'))

print(soup.find_all('audio'))

输出结果如下:

None

[]

BS4 也为 find()提供了简化写法,如下所示:

#简化写法

print(soup.head.title)

#上面代码等价于

print(soup.find("head").find("title"))

两种写法的输出结果相同,如下所示:

<title>"c语言中文网"</title>

<title>"c语言中文网"</title>

CSS选择器

BS4 支持大部分的 CSS 选择器,比如常见的标签选择器、类选择器、id 选择器,以及层级选择器。Beautiful Soup 提供了一个 select() 方法,通过向该方法中添加选择器,就可以在 HTML 文档中搜索到与之对应的内容。应用示例如下:

#coding:utf8

html_doc = """

<html><head><title>"c语言中文网"</title></head>

<body>

<p class="title"><b>c.biancheng网站站点" rel="nofollow" />

个输出:

[<title>"c语言中文网"</title>]

第二个输出:

[<a href="http://c.biancheng网站站点" rel="nofollow" />