爬虫:使用Python的BeautifulSoup库进行网页抓取

🚀 个人主页xmp65535

🚀 专栏python技术专栏


目录

一、安装

二、基本使用

三、导航树结构

四、搜索文档树

4.1 find_all()

4.2 find()

4.3 使用场景

4.4 举例说明

五、标签Tag对象操作

5.1 获取和设置属性

5.2 访问标签的内容

5.3 寻找标签

5.4 修改标签树

5.5 其他方法

六、css选择器使用方法

七、解析器

八、输出格式化

九、其他特性


BeautifulSoup 是一个用于从HTML或XML文件中提取数据的Python库,它能够通过你喜欢的转换器(例如lxml,html5lib)来解析这些文件。下面是一个基本的使用指南。

一、安装

首先,你需要安装 beautifulsoup4 包,这通常可以通过pip完成:

pip install beautifulsoup4

如果你想使用 lxml 的解析器(速度快,效率高),你还需要安装 lxml

pip install lxml

二、基本使用

导入BeautifulSoup类,并加载一个文档。

from bs4 import BeautifulSoup

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>
"""

soup = BeautifulSoup(html_doc, 'html.parser')  # 或者 'lxml' 来使用lxml解析器

BeautifulSoup() 是Python库BeautifulSoup中的一个构造函数,用于解析HTML和XML文档,创建一个可以被用来提取数据的解析树(parse tree)。下面详细解释了BeautifulSoup() 函数的参数用法:

被解析的文档

  • 第一个参数是你希望BeautifulSoup帮你解析的HTML或XML文档。
  • 这个参数可以是一个字符串,也可以是一个打开的文件句柄。

例如:

from bs4 import BeautifulSoup

html_doc = "<html><head><title>The Dormouse's story</title></head>"
soup = BeautifulSoup(html_doc, 'html.parser')

解析器

  • 第二个参数是用来指定解析器的字符串。BeautifulSoup可以使用多种解析器,如 html.parserlxmlhtml5lib
  • html.parser 是Python标准库中的解析器,无需额外安装。
  • lxml 是一个非常快的解析器,需要安装 lxml 库。
  • html5lib 解析器的容错性最好,能够按照HTML5的规范来解析文档,但速度较慢,需要安装 html5lib 库。

例如:

soup = BeautifulSoup(html_doc, 'lxml')

解析器特定参数

  • 一些解析器接受额外的参数,比如 lxml 解析器允许你指定解析器应该解析HTML还是XML文档。
  • 如果使用 lxml 解析XML文档,传递 features='xml' 参数会触发 lxml 的XML解析器。

例如:

xml_doc = "<doc><tag1>Some Data</tag1></doc>"
soup = BeautifulSoup(xml_doc, 'lxml', features='xml')

其他参数

  • from_encoding:如果文档包含非UTF-8字符编码,你可以使用这个参数来指定字符编码。如果不指定,BeautifulSoup将自动检测编码。
  • exclude_encodings:指定一个编码列表,告诉BeautifulSoup排除这些编码。
  • parse_only:一个 SoupStrainer 对象,允许你只解析文档的一部分。
  • markup:用于直接传递内容给构造函数,而不使用第一个参数,这通常用于测试。

例如:

from bs4 import SoupStrainer

parse_only_a_tags = SoupStrainer('a')
soup = BeautifulSoup(html_doc, 'html.parser', parse_only=parse_only_a_tags)

使用 BeautifulSoup() 时,最重要的是选择一个合适的解析器。解析器的选择会影响解析的速度和效果。如果你只需要处理简单的HTML文档,html.parser 就足够了。如果你需要更高的性能或者更好的容错性,可以安装并使用 lxmlhtml5lib

三、导航树结构

# 访问标签内容
soup.title
# <title>The Dormouse's story</title>

soup.title.name
# 'title'

soup.title.string
# 'The Dormouse's story'

soup.title.parent.name
# 'head'

soup.p
# <p class="title"><b>The Dormouse's story</b></p>

soup.p['class']
# ['title']

soup.a
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

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

soup.find(id="link3")
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>

四、搜索文档树

find_all()find() 是BeautifulSoup中的两个常用方法,它们用于搜索文档树并提取信息。

基本调用格式如下:

find(name, attrs, recursive, string, **kwargs)

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

参数说明:

  • name:要查找的标签的名称或者匹配名称的任何对象。
  • attrs:一个 Python 字典,包含标签的属性。你可以添加一个或多个属性来精确匹配。
  • recursive:如果为 True(默认值),find() 方法会检查当前标签的所有子孙节点。如果为 False,则只检查当前标签的直接子节点。
  • string:用于查找标签的文本内容。你可以使用字符串、正则表达式、列表或者 True。
  • **kwargs:特定属性过滤器,例如 idclass_ 等。
4.1 find_all()

find_all() 方法搜索当前标签的所有子孙节点,并返回所有符合条件的标签内容。这是一个非常灵活的方法,因为它允许你指定你想要检索的标签的名称、属性、内容,甚至是使用函数来进行复杂的匹配。

这是find_all()的一些基本用法:

soup.find_all('tag_name') # 返回包含所有<tag_name>标签的列表
soup.find_all(['tag1', 'tag2']) # 返回包含所有<tag1>和<tag2>标签的列表
soup.find_all(id='tag_id') # 返回包含所有id属性为'tag_id'的标签的列表
soup.find_all(class_='class_name') # 返回包含所有class属性为'class_name'的标签的列表
soup.find_all(attrs={'attribute_name': 'value'}) # 返回包含所有具有指定属性的标签的列表
soup.find_all(text='text') # 返回包含文本内容为'text'的标签的列表
soup.find_all(limit=2) # 返回最多2个符合条件的标签
4.2 find()

find() 方法与 find_all() 类似,但它只返回找到的第一个符合条件的标签。如果文档中存在多个匹配项,find() 将只返回第一个匹配项。这对于只需要一个元素,或者确定只有一个元素存在时特别有用。

以下是find()的一些基本用法:

soup.find('tag_name') # 返回第一个<tag_name>标签
soup.find(id='tag_id') # 返回第一个id属性为'tag_id'的标签
soup.find(class_='class_name') # 返回第一个class属性为'class_name'的标签
soup.find(attrs={'attribute_name': 'value'}) # 返回第一个具有指定属性的标签
soup.find(text='text') # 返回第一个文本内容为'text'的标签
4.3 使用场景

通常来说,如果你只需要找到一个特定的元素,比如一个具有特定 ID 的元素,你会使用 find()。如果你需要获取多个元素,比如文档中所有的链接,你会使用 find_all()

4.4 举例说明

HTML 文档:

<html>
 <body>
  <h1>Header 1</h1>
  <h2>Header 2</h2>
  <p>First Paragraph.</p>
  <p>Second Paragraph.</p>
 </body>
</html>

如果你使用 find_all()

paragraphs = soup.find_all('p')
# 返回的是包含所有 <p> 标签的列表

如果你使用 find()

first_paragraph = soup.find('p')
# 返回的是第一个 <p> 标签

五、标签Tag对象操作

5.1 获取和设置属性
  • tag['attr']: 获取标签的某个属性值,比如tag['href']获取<a>标签的链接地址。
  • tag.attrs: 获取一个字典,包含了标签的所有属性。
  • tag['attr'] = 'new value': 设置或修改标签的属性值。
5.2 访问标签的内容
  • tag.string: 如果标签只有一个子节点,并且这个子节点是字符串类型,tag.string返回子字符串。如果标签包含多个子节点,tag.string将返回None
  • tag.get_text(): 提取标签内的所有文本内容,包括子标签内的文本。
  • tag.text: 类似tag.get_text(),提取标签内的所有文本内容。
5.3 寻找标签
  • tag.find(name, attrs, recursive, string, **kwargs): 返回匹配查询的第一个标签。
  • tag.find_all(name, attrs, recursive, string, limit, **kwargs): 返回一个包含所有匹配查询的标签的列表。
  • tag.find_parent(name, attrs, string, **kwargs): 查找当前标签的父标签。
  • tag.find_parents(name, attrs, string, limit, **kwargs): 递归查找当前标签的所有父标签。
  • tag.find_next_sibling(name, attrs, string, **kwargs): 查找当前标签的下一个兄弟标签。
  • tag.find_next_siblings(name, attrs, string, limit, **kwargs): 查找当前标签之后的所有兄弟标签。
  • tag.find_previous_sibling(name, attrs, string, **kwargs): 查找当前标签的前一个兄弟标签。
  • tag.find_previous_siblings(name, attrs, string, limit, **kwargs): 查找当前标签之前的所有兄弟标签。
  • tag.find_next(name, attrs, string, **kwargs): 查找当前标签之后的第一个符合条件的标签。
  • tag.find_all_next(name, attrs, string, limit, **kwargs): 查找当前标签之后的所有符合条件的标签。
  • tag.find_previous(name, attrs, string, **kwargs): 查找当前标签之前的第一个符合条件的标签。
  • tag.find_all_previous(name, attrs, string, limit, **kwargs): 查找当前标签之前的所有符合条件的标签。
5.4 修改标签树
  • tag.append(content): 将内容添加到标签的子节点末尾。
  • tag.insert(position, new_child): 在指定位置插入新的子节点。
  • tag.clear(): 移除标签内的所有内容。
  • tag.extract(): 将标签及其内容从文档树中移除,并作为结果返回。
  • tag.replace_with(new_tag): 用新标签替换当前标签。
5.5 其他方法
  • tag.name: 获取或设置标签的名称。
  • tag.copy(): 复制当前标签。

上面这只是Tag对象提供的一部分方法和属性。BeautifulSoup的强大功能在于它可以轻松地导航、搜索和修改HTML或XML文档。每个方法的具体用法和参数,你可以在BeautifulSoup的官方文档中找到更详细的说明。

六、css选择器使用方法

select_one()是Beautiful Soup库中的一个方法,它允许你使用CSS选择器来选择HTML或XML文档中的第一个匹配的元素。

select() 返回的是一个列表,这个列表包含了所有匹配的元素。即使只找到一个匹配的元素,select也会返回一个列表,而select_one仅返回第一个匹配的元素本身。

举例:

from bs4 import BeautifulSoup

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>
"""

soup = BeautifulSoup(html_doc, 'html.parser')

#---------------------使用select()------------------------------

# 使用select查找所有class为sister的a标签
sisters = soup.select('a.sister')
print(sisters)  # 输出是一个包含所有class为sister的a标签的列表

# 同样可以使用更复杂的CSS选择器
titles = soup.select('html head title')
print(titles)  # 输出是一个包含title标签的列表

#---------------------使用select_one()--------------------------

# 使用select_one查找第一个class为sister的a标签
first_sister = soup.select_one('a.sister')
print(first_sister)  # 输出是第一个class为sister的a标签的内容

# 可以使用任意的CSS选择器
title_tag = soup.select_one('head > title')
print(title_tag)  # 输出是title标签的内容

七、解析器

BeautifulSoup使用许多不同的解析器(Python标准库中的html.parser,lxml的HTML和XML解析器,html5lib等),每个解析器都有自己的优点和缺点。例如:

BeautifulSoup(html_doc, 'html.parser') # 使用Python标准库解析
BeautifulSoup(html_doc, 'lxml') # 使用lxml库的HTML解析器,速度快
BeautifulSoup(html_doc, 'lxml-xml') # 使用lxml库的XML解析器
BeautifulSoup(html_doc, 'html5lib') # 使用html5lib库解析,最接近浏览器的方式

选择哪个解析器可能取决于个人偏好和特定任务的需求。

八、输出格式化

BeautifulSoup提供了多种格式化输出的方法,如prettify(),它能够将解析的文档以易读的方式输出。

print(soup.prettify())

九、其他特性

BeautifulSoup还提供了许多高级功能,如CSS选择器,通过它你可以使用CSS选择器语法来查找元素:

soup.select("p:nth-of-type(3)")

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xmp65535

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

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

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

打赏作者

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

抵扣说明:

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

余额充值