Beautiful Soup 4 是什么?

是一个 Python 库,协助解析 HTML 和 XML 的内容的 Python 库。

可以协助开发者在文档中准确定位到想要寻找的元素。

Basic usage

Installing and importing

Installing

pip3 install beautifulsoup4

Very easy.

Importing

from bs4 import BeautifulSoup

Create a BeautifulSoup Object

soup = BeautifulSoup(markup, 'html.parser')
print(type(soup))
# <class 'bs4.BeautifulSoup'>

接下来我们会详细介绍这个 BeautifulSoup 对象。

Objects 可能用到的对象类型

BeautifulSoup 会将一个复杂的 HTML 文档转化成一颗树,但我们真正需要处理的只有四种对象:

  • Tag
  • NavigableString
  • BeautifulSoup
  • Comment

下面我们将一一介绍。

Tag

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>', 'html.parser')
tag = soup.b
type(tag)
# <class 'bs4.element.Tag'>

Tag 的基本属性:

<b class="boldest">Extremely bold</b> 中:

  • Name: b # tag.name == b
  • Attributes:
    • class # tag['class'] == “boldest”
    • // Use tag.attrs to get all attributes

特别说明:对于多值属性,查询时会返回列表.

NavigableString类存储了 HTML 中可以被划分出来的 Tag 中的文本内容,如<div>bulabula</div>.

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>', 'html.parser')
tag = soup.b
tag.string
# 'Extremely bold'
type(tag.string)
# <class 'bs4.element.NavigableString'>

NavigableString 对象大可当做普通的 str 来使用,只是在其上又实现了在文档中定位和搜索的功能而已。

  • 要想把NavigableString转换成str,自然可以使用str()强制类型转换。
  • 要想修改NavigableString内存储的文本内容的话,可以使用replace_with() 函数
tag.string.replace_with("No longer bold")
tag
# <b class="boldest">No longer bold</b>

BeautifulSoup

BeautifulSoup 对象将整个文档解析成了一个整体。

大多数情况下,我们可以把 BeautifulSoup 对象看作是 Tag 对象。

它的 .name 字段返回 [document],无其它附加属性attrs.

Comments and other special strings

Comment 对象是一种特殊的 NavigableString 对象。

markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
soup = BeautifulSoup(markup, 'html.parser')
comment = soup.b.string
type(comment)
# <class 'bs4.element.Comment'>

除了Comment之外,BS4还提供了Stylesheet, Script, TemplateString 等类。

html_doc = """
<html>
<head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>

<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">...</p>
</body>
</html>
"""

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')

示例 HTML 文件如上。

Going down 向下一级

一个 Tag 的子元素可能包括 string 和其他 Tag.

>>> soup.head
# <head><title>The Dormouse's story</title></head>
>>> soup.title
# <title>The Dormouse's story</title>
>>>
>>> soup.body
#<body>
#<p class="title"><b>The Dormouse's story</b></p>
#<p class="story">Once upon a time there were three little sisters; and their names were
#<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
#<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
#and they lived at the bottom of a well.</p>
#<p class="story">...</p>
#</body>
>>>
>>> soup.body.b
#<b>The Dormouse's story</b>
>>> soup.a
#<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
# Only returns the first matched tag.
>>>
>>> soup.find_all('a')
#[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
# Use find_all() if you need all matched tags.

.contents and .children

  • tag.contents 返回一个tag下的所有子元素 List.

  • tag.children 返回一个tag下的所有子元素的集合的迭代器.

.descendants

.contents.children 只能用于获取某个 tag 下一级的子元素。而 .descendants 可以返回某个 tag 下属的所有子元素的迭代器。

.string

返回某个只有一个 NavigableString 作为子元素的元素的该子元素的文本内容。

.strings and stripped_strings

返回所有子元素中字符的迭代器。

Going up 向上一级

.parent

返回上层元素.

.parents

返回上层元素的迭代器.

Going sideways 找同级别

.next_sibling and .previous_sibling

.next_siblings and .previous_siblings

Searching the tree 查询搜索

本节主要介绍两个主要方法:

  • find()
  • find_all()

Filters 过滤器类型

String

过滤出所有 tag.name == (Input) 的 tag.

正则表达式

过滤出满足 tag.name matches pattern 的tag.

List

List 是上述两个项目的组合,过滤结果是并集。

True

返回所有内容.

Function

回调函数,接受一个参数 tag,如果返回True则过滤出来.

find_all(name, attrs, recursive=True, string, **kwargs)

注意:keyword arguments 也可以帮助 attrs 查找.

soup.find_all(href=re.compile("elsie"), id='link1')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]

Searching by CSS class

Usage: soup.find_ll("p", class_="body")

Reference