python爬虫----BeautifulSoup模块的介绍和使用

本文介绍BeautifulSoup模块,一种高效、灵活的网页解析库,用于替代正则表达式进行网页信息抓取。涵盖解析器的选择、基本使用方法、标签选择、属性与内容获取、子节点及子孙节点操作,以及标准选择器和CSS选择器的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python爬虫----BeautifulSoup的介绍和使用

环境:python3.6

BeautifulSoup是什么?

在我之前文章中使用的爬虫,我习惯使用正则表达式来提取网页中有用的信息,因为正则表达式的准确性和快速性是可以保证的,但是对于一些界面使用正则表达式进行信息提取又显得很麻烦,而且正则表达式要记很多规则,所以就降低了写代码时的效率。这篇博文主要记录了BeautifulSoup模块的使用,它是一个灵活并且方便的网页解析库,支持多种解析器。使用这个就不需要使用正则表达式也能方便地进行网页信息的抓取。

BeautifulSoup模块的使用

解析器

Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装。Python版本的标准库中内置了HTML的解析器,但是解析方法不稳定,所以最好使用lxml解析器。
使用方法:

from bs4 import BeautifulSoup
html_text='''
<p class="title"><b>This is title one</b></p>
'''
soup=BeautifulSoup(html_text,"lxml")#lxml HTML解析器

其他几种解析器使用的方法:
python标准库:soup=BeautifulSoup(html_text,"html.parser")
lxml XML解析器(唯一支持XML的解析器):soup=BeautifulSoup(markup,"lxml","xml")
html5lib解析器:soup=BeautifulSoup(html_text,"html5lib")

基本使用方法

标签选择

通过soup.标签名来获得这个标签的内容,比如soup.a就可以获得标签a中的内容,比如说soup.p就可以获得标签p中的内容,但是如果html中有多个一样的标签,返回的结果是第一个标签的内容,其他标签的内容不会得到。这时候就要用soup.find_all(标签名)方法来得到一个所有含有这个标签的列表。

获得名称

我们通过soup.title.name可以获得该title的标签名称,即title。(感觉这个很鸡肋啊喂)

获取属性

print(soup.a.attrs['href'])
print(soup.a['href'])
通过以上两种方法都可以得到a标签中href的属性值。

获取内容

print(soup.p.string)
可以获得第一个p标签中的内容
除了直接使用soup.标签名,还可以嵌套获取标签中的内容,比如说soup.html.head.title.string

子节点和子孙节点

contents

先看实例:

html = """
<html>
    <head>
        <title>The Dormouse's story</title>
    </head>
    <body>
        <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">
                <span>Elsie</span>
            </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>
"""

from bs4 import BeautifulSoup

soup = BeautifulSoup(html,'lxml')
print(soup.p.contents)

输出:

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

使用contents可以把p标签里面的所有内容都以列表的形式返回出来,包含了所有的子节点
从小细节可以看出,经过lxml解析后,标签内的属性按照lxml规定的顺序显示,可以参考以上代码中的a标签,可以看到输出的标签的属性是经过统一重新排列的。

children的使用

通过children也可以获得p标签下所有子节点内容,就和使用contents获取的结果是一样的,但是不同的是soup.p.children是一个迭代对象,而不是一个列表,只能通过循环的方式获得信息。

html = """
<html>
    <head>
        <title>The Dormouse's story</title>
    </head>
    <body>
        <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">
                <span>Elsie</span>
            </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>
"""

from bs4 import BeautifulSoup

soup = BeautifulSoup(html,'lxml')
print(soup.p.children)
for child in soup.p.children:
    print(child)

输出:

<list_iterator object at 0x000001FD9FF79BE0>

            Once upon a time there were three little sisters; and their names were

<a class="sister" href="http://example.com/elsie" id="link1">
<span>Elsie</span>
</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
descendants

通过以上contents和children获取的都是子节点,如果想要获取子孙节点可以通过使用** descendants **。
若想获得子孙节点的单独的内容,上面的代码就可以写为soup.p.descendants,同样,这种获取方法返回的是一个迭代器。

父节点和祖先节点

soup.a.parent可以获取父节点的信息.
通过soup.a.parents可以获得祖先节点,同样返回的是一个迭代器,需要通过迭代的方法来获取内容,通常使用list(soup.a.parents)获取一个列表,会分别将a标签的父节点的信息存放到列表中,以及父节点的父节点也放到列表中,并且最后还会讲整个文档放到列表中,所有列表的最后一个元素以及倒数第二个元素都是存的整个文档的信息。

兄弟节点

soup.a.next_siblings获取后面的兄弟节点
soup.a.previous_siblings获取前面的兄弟节点
soup.a.next_sibling获取下一个兄弟节点
souo.a.previous_sinbling获取上一个兄弟节点
兄弟节点只能是同级别的节点。

标准选择器

find_all

find_all(name,attrs,recursive,text,**kwargs)
可以根据标签名,属性,内容查找文档,把这些参数构成一个字典传入。(*arg是传入一个列表或者元组)find_all方法可以将所有符合条件的对象都找出,返回一个对象列表,可以对这些对象再使用find、find_all、find_parents等函数。
name表示标签,找到所有符合条件的标签返回一个列表,当attrs不为空时,可以直接写成’’,表示从所有的标签中寻找有特定标签属性的标签。
attrs可以传入字典的方式来查找标签,比如:attrs={'class':'element'}或者soup.find_all('',{"class":"element"}),特殊的标签属性可以不写attrs,例如soup.find_all(id='link2')
text表示查找对应的文本。

find

find(name,attrs,recursive,text,**kwargs)
find返回匹配到的第一个对象

其他一些类似的用法:
find_parents()返回所有祖先节点,find_parent()返回直接父节点。
find_next_siblings()返回后面所有兄弟节点,find_next_sibling()返回后面第一个兄弟节点。
find_previous_siblings()返回前面所有兄弟节点,find_previous_sibling()返回前面第一个兄弟节点。
find_all_next()返回节点后所有符合条件的节点, find_next()返回第一个符合条件的节点
find_all_previous()返回节点后所有符合条件的节点, find_previous()返回第一个符合条件的节点.

CSS选择器

通过select()直接传入CSS选择器就可以完成选择
熟悉前端的人对CSS可能更加了解,其实用法也是一样的
.表示class #表示id
标签1,标签2 找到所有的标签1和标签2
标签1 标签2 找到标签1内部的所有的标签2
[attr] 可以通过这种方法找到具有某个属性的所有标签
[atrr=value] 例子[target=_blank]表示查找所有target=_blank的标签
比如:print(soup.select('.sister'))可以打印出所有class是sister的标签对。
使用get_text()可以获取文本内容
或者属性的时候可以通过[属性名]或者.attrs[属性名]。

差不多这就是全部了,可以看到,BeautifulSoup无疑比正则表达式要方便快捷的多,看完这篇文章不妨试试用bs爬取一个网站。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值