2021/5/7爬虫第九次课(BeautifulSoup4)

本文介绍了BeautifulSoup库的基础使用,包括其解析HTML文档、对象类型、操作方法如遍历和搜索,重点讲解了find_all()和find()函数在实际爬虫中的应用。适合理解HTML结构并想要高效抓取数据的开发者。
摘要由CSDN通过智能技术生成

一、bs4简介

  • 是什么?
    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的网页信息提取库
  • 有什么作用?
    解析和提取网页中的数据
  • 运用场景
    PC端 网站中去爬取数据 百度网站 腾讯的网站
    随着网站的种类增多,去寻找最适合解决这个网站的技术
    正则 正则表达式有的时候不太好写 容易出错
    xpath 要记住一些语法,后期可以直接copy xpath
    bs4的特点 只需要记住一些方法就可以了

二、bs4源码分析

我们为什么要学习看源码?

  • 了解原理、了解使用
  • 学习思路
  • 开发者必备的一项技能

pycharm左侧的一些小图标
c Class 类
m Method 方法
f Field 字段
p Property 装饰器
v Variable 变量

三、bs4的对象种类

  • tag : 标签
  • NavigableString : 可导航的字符串
  • BeautifulSoup : bs对象
  • Comment : 注释
from bs4 import BeautifulSoup
# from bs4.element import NavigableString
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,"lxml")
print(type(soup.title)) # <class 'bs4.element.Tag'>
# # print(type(soup.a)) # <class 'bs4.element.Tag'>
# # print(type(soup.p)) # <class 'bs4.element.Tag'>
#
print(type(soup.title.string)) # <class 'bs4.element.NavigableString'>
print(type(soup)) # <class 'bs4.BeautifulSoup'>

html = '<a><!--大家慢慢来,好饭不怕晚,先把知识点掌握--></a>'
soup2 = BeautifulSoup(html,'lxml')
print(type(soup2.string)) # <class 'bs4.element.Comment'>

四、bs4操作

bs里面有三种操作,第一个是遍历,第二个是查找,第三个是修改

五、遍历文档树

from bs4 import BeautifulSoup
# from bs4.element import NavigableString
html_doc = """
<html><head><title>The Dormouse1's story</title></head>
<body>
<p class="title"><b>The Dormouse2'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,"lxml")
'''
contents 返回的是一个所有子节点的列表
children 返回的是一个子节点的迭代器
descendants 返回的是一个生成器遍历子子孙孙

面试的问题:迭代器 生成器 可迭代对象它们之间的关系
'''
# head_tag = soup.head
# print(head_tag.contents)
# print(head_tag.children)
# for i in head_tag.children:
#     print(i)

# html_tag = soup.html
# for i in html_tag.children:
#     print(i)
# for i in html_tag.descendants:
#     print(i)

'''
听懂了
string获取标签里面的内容
strings 返回是一个生成器对象用过来获取多个标签内容
stripped_strings 和strings基本一致 但是它可以把多余的空格去掉
'''

# title_tag = soup.title
# print(title_tag.string)

# head_tag = soup.head
# print(head_tag.string)
#
# print(soup.html.strings)
# s = soup.html.strings
# for i in s:
#     print(i)

#
# s = soup.html.stripped_strings
# for i in s:
#     print(i)

'''
parent直接获得父节点
parents获取所有的父节点
'''

# title_tag = soup.title
# print(title_tag)
# print(title_tag.parent)
# print(soup.html.parent) #整个html文档

# a_tag = soup.a
# # print(a_tag.parents)
#
# for p in a_tag.parents:
#     print(p)
#     print('-'*50)

'''
next_sibling 下一个兄弟结点
previous_sibling 上一个兄弟结点
next_siblings 下一个包含所有兄弟结点的生成器
previous_siblings上一个包含所有兄弟结点的生成器
'''
# html2 = '<a><b>bbb</b><c>ccc</c><d>ddd</d></a>'
# soup2 = BeautifulSoup(html2,'lxml')
# # print(soup2.prettify())
# b_tag = soup2.b
# print(b_tag)
# print(b_tag.next_siblings)

# c_tag = soup2.c
# print(c_tag.previous_sibling)

总结:
遍历 标签(一个或多个)【父、兄弟、子】
查找标签
查找文本
查找属性

六、搜索文档树

• 字符串过滤器
• 正则表达式过滤器
我们用正则表达式里面compile方法编译一个正则表达式传给 find 或者 findall这个方法可以实现一个正则表达式的一个过滤器的搜索
• 列表过滤器
• True过滤器

七、find_all() 和 find()

这是在这三者中最为重要的,;要熟练掌握,另外两个只需掌握

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,"lxml")
# 需求:找a标签
# a_tag = soup.find('a') # 此时这个a就代表的是字符串过虑器
# print(a_tag)
# a_tas = soup.find_all('a')
# print(a_tas)

# print(soup.find_all(['a','p']))
# print(soup.find_all(['title','b'])) # 此时['title','b'] 列表过滤器

html = """
<table class="tablelist" cellpadding="0" cellspacing="0">
    <tbody>
        <tr class="h">
            <td class="l" width="374">职位名称</td>
            <td>职位类别</td>
            <td>人数</td>
            <td>地点</td>
            <td>发布时间</td>
        </tr>
        <tr class="even">
            <td class="l square"><a target="_blank" href="position_detail.php?id=33824&keywords=python&tid=87&lid=2218">22989-金融云区块链高级研发工程师(深圳)</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-25</td>
        </tr>
        <tr class="odd">
            <td class="l square"><a target="_blank" href="position_detail.php?id=29938&keywords=python&tid=87&lid=2218">22989-金融云高级后台开发</a></td>
            <td>技术类</td>
            <td>2</td>
            <td>深圳</td>
            <td>2017-11-25</td>
        </tr>
        <tr class="even">
            <td class="l square"><a target="_blank" href="position_detail.php?id=31236&keywords=python&tid=87&lid=2218">SNG16-腾讯音乐运营开发工程师(深圳)</a></td>
            <td>技术类</td>
            <td>2</td>
            <td>深圳</td>
            <td>2017-11-25</td>
        </tr>
        <tr class="odd">
            <td class="l square"><a target="_blank" href="position_detail.php?id=31235&keywords=python&tid=87&lid=2218">SNG16-腾讯音乐业务运维工程师(深圳)</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-25</td>
        </tr>
        <tr class="even">
            <td class="l square"><a target="_blank" href="position_detail.php?id=34531&keywords=python&tid=87&lid=2218">TEG03-高级研发工程师(深圳)</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
        <tr class="odd">
            <td class="l square"><a target="_blank" href="position_detail.php?id=34532&keywords=python&tid=87&lid=2218">TEG03-高级图像算法研发工程师(深圳)</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
        <tr class="even">
            <td class="l square"><a target="_blank" href="position_detail.php?id=31648&keywords=python&tid=87&lid=2218">TEG11-高级AI开发工程师(深圳)</a></td>
            <td>技术类</td>
            <td>4</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
        <tr class="odd">
            <td class="l square"><a target="_blank" href="position_detail.php?id=32218&keywords=python&tid=87&lid=2218">15851-后台开发工程师</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
        <tr class="even">
            <td class="l square"><a target="_blank" href="position_detail.php?id=32217&keywords=python&tid=87&lid=2218">15851-后台开发工程师</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
        <tr class="odd">
            <td class="l square"><a id="test" class="test" target='_blank' href="position_detail.php?id=34511&keywords=python&tid=87&lid=2218">SNG11-高级业务运维工程师(深圳)</a></td>
            <td>技术类</td>
            <td>1</td>
            <td>深圳</td>
            <td>2017-11-24</td>
        </tr>
    </tbody>
</table>
"""
soup = BeautifulSoup(html,"lxml")

# 1 获取所有的tr标签
# print(soup.tr) print(soup.find('tr'))  #效果相同
# trs = soup.find_all('tr')
# for tr in trs:
#     print(tr)
#     print('*'*80)

# 2 获取第二个tr标签的内容
# tr = soup.find_all('tr')[1]
# print(tr)

# 3 获取所有class等于even的tr标签 注:class被Python团队所使用了 class_ 等价于class
# trs = soup.find_all('tr',class_='even')
# for tr in trs:
#     print(tr)
#     print('*' * 80)


# trs = soup.find_all('tr',attrs={'class':'even'})
# for tr in trs:
#     print(tr)
#     print('*' * 80)

# 两种方式效果一致

# 4 获取id等于test class等于test的a标签的数据
# lst = soup.find_all('a',id='test',class_='test')
# for a in lst:
#     print(a)

# 5 获取所有a 标签的href属性
# a_lst = soup.find_all('a')
# for a in a_lst:
#     href = a.get('href')
#     print(href)
# for a in a_lst:
#     href = a['href']
#     print(href)

# 6 获取所有的职位信息 其他的方式也可以下课自己去试
# trs = soup.find_all('tr')[1:]

# for tr in trs:
#     tds = tr.find_all('td')
#     job_name = tds[0].string
#     print(job_name)

# for tr in trs:
#     print(tr.a.string)

find_all源码:

def find_all(self, name=None, attrs={}, recursive=True, text=None,
                 limit=None, **kwargs):

name : tag名称
attr : 标签的属性
recursive : 是否递归搜索
text : 文本内容
limli : 限制返回条数
kwargs : 关键字参数

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

笔记本IT

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

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

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

打赏作者

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

抵扣说明:

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

余额充值