【python】爬虫系列之爬虫解析器BeautifulSoup4

目录

 一、BeautifulSoup4库简单介绍

二、beautifulsoup4的使用

1. 基础操作

2. 对象种类

3. find_all()搜索文档树

4. CSS选择器


活动地址:CSDN21天学习挑战赛

**

学习日记 Day18

**

 一、BeautifulSoup4库简单介绍

BeautifulSoup4是一个可以从HTML或XML中提取数据的python库。它能够通过你喜欢的转换器实现管用的文档导航、查找、修改文档的方式。BeautifulSoup会帮你节省数小时甚至数天的工作时间。

BeautifulSoup4将网页转换为一颗DOM树:

 ⚪ 下载BeautifulSoup4模块

在cmd命令中输入pip install beautifulsoup4命令,安装即可。

⚪ beautifulsoup4解析库

BeautifulSoup在解析时实际上依赖解析器,它除了支持python标准库中的HTML解析器外,还支持一些第三方解析器(比如xml):

解析器使用方法优势劣势
python标准库BeautifulSoup(html,'html.parser')pyhton内置标准库、执行速度适中、文档容错能力强python2.7.3及python3.2.2之前的版本文档容错能力差

lxml

HTML解析库

BeautifulSoup(html,'lxml')速度快、文档容错能力强需要安装C语言库
lxml XML解析库BeautifulSoup(html,'xml')速度快、唯一支持的XML的解析器需要安装C语言库
htm5lib解析库BeautifulSoup(html,'html5llib')最好的容错性、以浏览器的方式解析文档、生成HTMLS格式的文档速度慢、不依赖外部扩展

常用的解析器是lxml HTML解析器,其次是html5lib。

二、beautifulsoup4的使用

1. 基础操作

⚪ 读取HTML字符串

from bs4 import BeautifulSoup

html='''
<div class="panel">
    <div class="panel-heading">
        <h4>Hello</h4>
    </div>
    <div class="panel-body">
        <ul class="list" id="list-1" name="element">
            <li class="element">Foo</li>
            <li class="element">Bar</li>
            <li class="element">Jay</li>
        </ul>
        <ul class="list list-small" id="list-2">
            <li class="element">Foo</li>
                <a href="https://www.baidu.com">百度官网</a>
            <li class="element">Bar</li>
        </ul>
    </div>
</div>
'''

# 创建对象
soup = BeautifulSoup(html,'lxml')

⚪ 读取HTML文件

from bs4 import BeautifulSoup

# 创建对象
soup = BeautifulSoup(open('test.html'),'lxml')

⚪ 基本方法

from bs4 import BeautifulSoup

html='''
<div class="panel">
    <div class="panel-heading">
        <h4>Hello</h4>
    </div>
    <div class="panel-body">
        <ul class="list" id="list-1" name="element">
            <li class="element">Foo</li>
            <li class="element">Bar</li>
            <li class="element">Jay</li>
        </ul>
        <ul class="list list-small" id="list-2">
            <li class="element">Foo</li>
                <a href="https://www.baidu.com">百度官网</a>
            <li class="element">Bar</li>
        </ul>
    </div>
</div>
'''

# 创建对象
soup = BeautifulSoup(html,'lxml')

# 缩进格式
print(soup.prettify())  # 以缩进格式打印html字符串
print('*'*50)
# 获取title标签的所有内容
print(soup.title)

# 获取title标签的名称
print(soup.title.name)

# 获取title标签的文本内容
print(soup.title.string)

# 获取head标签的所有内容
print(soup.head)

# 获取第一个div标签中的所有内容
print(soup.div)

# 获取第一个div标签的id的值
print(soup.div['id'])

# 获取第一个a标签中的所有内容
print(soup.a)

# 获取所有的a标签中的所有的内容
print(soup.find_all('a'))

# 获取id='ul
print(soup.find(id='ul'))

# 获取所有的a标签,并遍历打印a标签的文本值
for item in soup.find_all('a'):
    print(item.get('href'))

# 获取所有的a标签,并遍历打印a标签的文本值
for item in soup.find_all('a'):
    print(item.get_text())

2. 对象种类

BeautifulSoup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是python对象,所有对象可以归纳为4种:Tag,NavigableString,BeautifulSoup,Comment。

⚪ Tag,通俗说就是HTML种的一个个标签,比如:

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>','lxml')
tag = soup.b
print(tag)
print(type(tag))

显示结果:

<b class="boldest">Extremely bold</b>
<class 'bs4.element.Tag'>

Tag有很多方法和属性,这里介绍tag种最重要的属性name和attributes。

name属性:

# 输出tag的name
print(tag.name)  # 打印 b
# 如果改变了tag的name,将影响所有通过当前Beautiful Soup对象生成的HTML文档
tag.name='b1'
print(tag)  # 打印 <b1 class="boldest">Extremely bold</b1>

Attributes属性:

# 获取class属性
print(tag['class'])  # 输出 ['boldest']

# 直接获取属性
print(tag.attrs)  # 输出 {'class': ['boldest']}

tag的属性可以被添加、修改和删除:

# 添加 id 属性
tag['id'] = 1
print(tag)

# 修改 class  属性
tag['class'] = 'tl1'
print(tag)

# 删除 class 属性
del tag['class']
print(tag)

显示结果:

<b1 class="boldest" id="1">Extremely bold</b1>
<b1 class="tl1" id="1">Extremely bold</b1>
<b1 id="1">Extremely bold</b1>

⚪ NavigableString,用.string获取标签内部的文字。

print(soup.b.string)  # 输出 Extremely bold
print(type(soup.b.string))  # 输出 <class 'bs4.element.NavigableString'>

⚪ BeautifulSoup,表示一个文档的内容,可以获取它的类型、名称以及属性。

print(soup.name)  # 输出 [document]
print(type(soup.name))  # 输出 <class 'str'>
print(soup.attrs)  # 文档本身的属性为空  输出 {}

⚪ Comment,是一个特殊类型的NavigableString对象,其输出的内容不包括注释符号。

print(soup.b)  # 输出 <b class="boldest">Extremely bold</b>
print(soup.b.string)  # 输出 Extremely bold
print(type(soup.b.string))  # 输出 <class 'bs4.element.NavigableString'>

3. find_all()搜索文档树

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

⚪  参数name :查找所有名字为name的tag,字符串对象会被自动忽略掉。

  • 匹配字符串:查找与字符串完整匹配的内容,如下用于查找文档中所有的<a>标签。
  • 匹配正则表达式:如果传入正则表达式作为参数,BeautifulSoup会通过正则表达式的match()来匹配内容。
  • 匹配列表:如果传入列表参数,BeautifulSoup会将与列表中任一元素匹配的内容返回
  • 示例:
  • from bs4 import BeautifulSoup
    import re
    
    html = '''
    <div class="panel">
        <div class="panel-heading">
            <h4>Hello</h4>
        </div>
        <div class="panel-body">
            <ul class="list" id="list-1" name="element">
                <li class="element">Foo</li>
                <li class="element">Bar</li>
                <li class="element">Jay</li>
            </ul>
            <ul class="list list-small" id="list-2">
                <li class="element">Foo</li>
                    <a href="https://www.baidu.com">百度官网</a>
                <li class="element">Bar</li>
            </ul>
        </div>
    </div>
    '''
    
    soup = BeautifulSoup(html,'lxml')
    
    # 查找与字符串完整匹配的内容
    a_list = soup.find_all('a') 
    print(a_list) 
    
    #  返回所有表示<body>和<b>标签
    for tag in soup.find_all(re.compile('^b')):
        print(tag.name) 
    
    # 返回所有<ul>标签和<a>标签
    print(soup.find_all(['ul','a']))

    显示结果:

  • [<a href="https://www.baidu.com">百度官网</a>]
    body
    PS E:\1_tempFile\1_learn_code\VSCode\python_test> & D:/IDE/Python/python.exe e:/1_tempFile/1_learn_code/VSCode/python_test/python_beautifulsoup4/read_html.py
    [<a href="https://www.baidu.com">百度官网</a>]
    body
    [<ul class="list" id="list-1" name="element">
    <li class="element">Foo</li>
    <li class="element">Bar</li>
    <li class="element">Jay</li>
    </ul>, <ul class="list list-small" id="list-2">
    <li class="element">Foo</li>
    <a href="https://www.baidu.com">百度官网</a>
    <li class="element">Bar</li>
    </ul>, <a href="https://www.baidu.com">百度官网</a>]

    ⚪  参数kwargs :可以以标签=值的方式查找所有该标签下的内容。

  • from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(open('test.html'),'lxml')
    
    print(soup.find_all(id='list-1'))

    显示结果:

  • [<ul class="list" id="list-1" name="element">
    <li class="element">Foo</li>
    <li class="element">Bar</li>
    <li class="element">Jay</li>
    </ul>]

    ⚪ 参数text:通过text参数可以搜索文档中的字符串内容,于name参数的可选值一样,text参数接受字符串,正则表达式、列表。

  • soup = BeautifulSoup(open('test.html'),'lxml')
    
    # 匹配字符串
    print(soup.find_all(text='a'))
    
    # 匹配正则表达式
    print(soup.find_all(text=re.compile('^b')))
    
    # 匹配列表
    print(soup.find_all(text=['ui','li']))

    4. CSS选择器

在使用BeautifulSoup解析库时,经常结合CSS选择器来提取数据。

⚪ 根据标签名查找:比如传递 li 就会选择所有 li 标签

soup = BeautifulSoup(open('test.html'),'lxml')

print(soup.select('li'))

显示结果:

[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>, <li class="element">Foo</li>, <li class="element">Bar</li>]

⚪ 根据类名class查找:.line  表示选择class="line"的所有标签。用 . 代表class。

soup = BeautifulSoup(open('test.html'),'lxml')

print(soup.select('.panel-heading'))

显示结果:

[<div class="panel-heading">
<h4>Hello</h4>
</div>]

⚪ 根据id查找:#box 表示选取id=box的所有标签,#代表id

soup = BeautifulSoup(open('test.html'),'lxml')

print(soup.select('#list-1'))

显示结果:

[<ul class="list" id="list-1" name="element">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>]

⚪ 根据属性的名字查找:class和id分别使用 . 和#代表它们。其它的属性可以按照 input[name="username"]的格式查找 name="username"的标签。

soup = BeautifulSoup(open('test.html'),'lxml')

print(soup.select('ul[name="element"]'))

显示结果:

[<ul class="list" id="list-1" name="element">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>]

⚪ 标签+类名或id的形式

soup = BeautifulSoup(open('test.html'),'lxml')

print(soup.select('ul#list-1'))
# 查找id为list-1的ul标签
print('='*40)
# 查找class为list的ul标签
print(soup.select('ul.list'))

显示结果:

[<ul class="list" id="list-1" name="element">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>]
========================================
[<ul class="list" id="list-1" name="element">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>, <ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<a href="https://www.baidu.com">Baidu</a>
<li class="element">Bar</li>
</ul>]

Process finished with exit code 0

⚪ 查找直接子元素

soup = BeautifulSoup(open('test.html'),'lxml')

# 查找id="list-1"的标签下的直接子标签li
print(soup.select('#list-1>li'))

⚪ 查找子孙标签

soup = BeautifulSoup(open('test.html'),'lxml')

# .panel_body 与 li之间是空格,表示查找class=panel_body的标签下的子标签或孙标签li
print(soup.select('.panel_body li'))

显示结果:

[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>, <li class="element">Foo</li>, <li class="element">Bar</li>]

⚪ 获取某个标签的属性

soup = BeautifulSoup(open('test.html'),'lxml')

# 先获取到 <div class="panel_body">
div=soup.select('.panel_body')[0]
# 再获取a标签下的href属性
print(div.select('a')[0]['href'])

显示结果:

https://www.baidu.com

⚪ 获取文本内容

■ 使用string属性:获取某个标签下的文本内容,强调一个标签,不含嵌套内容,返回字符串

soup = BeautifulSoup(open('test.html'),'lxml')

# 先获取到<div class="panel_body">
div = soup.select('.panel_body')[0]
# 再获取下面的<a>标签下的内容
print(div.select('a')[0].string)

显示结果:

Baidu

■ 使用strings属性:获得某个标签下的所有文本内容,可以嵌套,返回一个生成器,可以用list转换为列表

soup = BeautifulSoup(open('test.html'),'lxml')

# 先获取到<div class="panel_body">
div = soup.select('.panel_body')[0]
print(div.strings)
print(list(div.strings))

显示结果:

<generator object Tag._all_strings at 0x000001BE4A405CF0>
['\n', '\n', 'Foo', '\n', 'Bar', '\n', 'Jay', '\n', '\n', '\n', 'Foo', '\n', 'Baidu', '\n', 'Bar', '\n', '\n']

■ 使用stripped_strings:和strings属性类似,不同在于stripped_strings会去掉字符串头部和尾部的空格和换行符

soup = BeautifulSoup(open('test.html'),'lxml')

# 先获取到<div class="panel_body">
div = soup.select('.panel_body')[0]

print(div.stripped_strings)
print(list(div.stripped_strings))

显示结果:

<generator object Tag.stripped_strings at 0x0000026D05935CF0>
['Foo', 'Bar', 'Jay', 'Foo', 'Baidu', 'Bar']

■ 使用get_text():获取所有字符串,包含嵌套,不过会把所有字符串拼接为一个再返回。

soup = BeautifulSoup(open('test.html'),'lxml')

# 先获取到<div class="panel_body">
div = soup.select('.panel_body')[0]

print(div.get_text())

显示结果:



Foo
Bar
Jay


Foo
Baidu
Bar

全文参考:100天精通Python(爬虫篇)——第46天:爬虫解析器BeautifulSoup4_无 羡ღ的博客-CSDN博客一、BeautifulSoup4库介绍 1. 介绍 2. 下载模块 3. 解析库二、上手操作 1. 基础操作 2. 对象种类 3. 搜索文档树 4. css选择器https://blog.csdn.net/yuan2019035055/article/details/125695337

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值