bs4
bs4简介
一、bs4是什么?
beautifulsoup4
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的网页信息提取
二、基本概念
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的网页信息提取库
三、有什么意义?
1、PC端 网站中去爬取数据 百度网站 腾讯的网站
随着网站的种类增多,去寻找最适合解决这个网站的技术
2、正则: 正则表达式有的时候不太好写 容易出错
3、xpath: 记住一些语法
4、bs4它的特点 只需要同学们记住一些方法就可以了
四、bs4源码分析
我们为什么要学习看源码?
1、了解原理、了解使用
2、学习思路
3、开发者必备的一项技能
4、源码当中有一些小图标
c Class 类
m Method 方法
f Field 字段
p Property 装饰器
v Variable 变量
bs4的快速入门
1 安装
pip install lxml
pip install bs4
2 导入
form bs4 import BeautifulSoup
3 创建soup对象
soup = BeautifulSoup(tag)
4 可以使用对象当中的方法
例如 find() find_all()
5、bs4的种类
'''
tag : 标签
NavigableString : 可导航的字符串
BeautifulSoup : soup对象
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>
"""
# # tag : 标签
# 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'>
#
# # NavigableString : 可导航的字符串
# print(type(soup.title.string)) # 结果为 <class 'bs4.element.NavigableString'>
#
# # BeautifulSoup : soup对象
# print(type(soup)) # 结果为 <class 'bs4.BeautifulSoup'># Comment : 注释
html = '<a><!--我爱python--></a>'
soup2 = BeautifulSoup(html, 'lxml')
print(type(soup2.string)) # 结果为 <class 'bs4.element.Comment'>
快速入门
# pip install lxml 安装lxml 要安装bs4要先安装lxml
# pip install bs4 安装bs4
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, features="lxml")
soup = BeautifulSoup(html_doc, "lxml")
# 打印文档内容(把我们的标签更加规范的打印)
print(soup.prettify())# 需求:获取title标签里面的文本 The Dormouse's story
# 通过标签获取数据 然后在解析数据
# print(soup.title) # 结果为<title>The Dormouse's story</title>
# print(soup.title.string) # 结果为The Dormouse's story
# 获取title标签名称 title
# print(soup.title.name) # title# 需求:获取所有的p段落
# print(soup.p) # 结果为 <p class="title"><b>The Dormouse's story</b></p>
# r = soup.findAll('p') # 返回一个列表
# r = soup.find_all('p') # 和上面代码的效果原因
# print(len(r), r) # len为3,# 需求: 找到a标签当中的href链接
links = soup.find_all('a')
for link in links:print(link.get('href')) # 进行遍历取出a里面href中的数据
遍历文档树
一、遍历子节点
1、contents 返回的是一个所有子节点的列表
2、children 返回的是一个子节点的迭代器通
3、descendants 返回的是一个生成器遍历子子孙孙
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")
'''
contents 返回的是一个所有子节点的列表
children 返回的是一个子节点的迭代器
descendants 返回的是一个生成器遍历子子孙孙
'''
# head_tag = soup.head
# contents 返回的是一个所有子节点的列表
# print(head_tag.contents) # 结果为 [<title>The Dormouse's story</title>]
# children 返回的是一个子节点的迭代器
# print(head_tag.children) # 结果为 <list_iterator object at 0x00000209775B41F0>
# descendants 返回的是一个生成器遍历子子孙孙
# for i in head_tag.children: # 结果为 <title>The Dormouse's story</title> 因为head中只有一个使用遍历出一个
# print(i)
# html_tag = soup.html
# for i in html_tag.descendants: # 全部的节点都打印出来
# print(i)
string获取标签里面的内容
strings 返回是一个生成器对象用过来获取多个标签内容
stripped_strings 和strings基本一致 但是它可以把多余的空格去掉
'''
string获取标签里面的内容
strings 返回是一个生成器对象用过来获取多个标签内容
stripped_strings 和strings基本一致 但是它可以把多余的空格去掉
'''
# string获取标签里面的内容第一种写法
# title_tag = soup.title # 获取title标签里的内容
# print(title_tag.string) # 结果为 The Dormouse's story
# 第二种写法
# print(soup.title.string) # 结果为 The Dormouse's story
# print(soup.head.string) # 结果为 The Dormouse's story
# strings 返回是一个生成器对象用过来获取多个标签内容
# print(soup.html.strings)
# s = soup.html.strings # 用s来接收soup.html.strings
# for i in s: # 进行遍历
# print(i) 结果有空格
#
# stripped_strings 和strings基本一致 但是它可以把多余的空格去掉
# print(soup.html.stripped_strings)
# s = soup.html.stripped_strings # 用s来接收soup.html.strings
# for i in s: # 进行遍历
# print(i) 将空格去掉了
二、遍历父节点
1、parent直接获得父节点
2、parents获取所有的父节点
'''
parent直接获得父节点
parents获取所有的父节点
'''
# title_tag = soup.title
# print(title_tag) # <title>The Dormouse's story</title>
# # parent直接获得父节点
# print(title_tag.parent) # 获取了title的父节点 <head><title>The Dormouse's story</title></head>
# print(soup.html.parent) # 获取了html的父节点 整个文档# parents获取所有的父节点
a_tag = soup.a
# print(a_tag.parents) # 结果为<generator object PageElement.parents at 0x000002102E6BB200>的生成器对象for p in a_tag.parents:print(p)print('-'*50)
三、遍历兄弟结点
1、next_sibling 下一个兄弟结点
2、previous_sibling 上一个兄弟结点
3、next_siblings 下一个所有兄弟结点
4、previous_siblings上一个所有兄弟结点
'''
next_sibling 下一个兄弟结点
previous_sibling 上一个兄弟结点
next_siblings 下一个所有兄弟结点
previous_siblings上一个所有兄弟结点
'''
# html2 = '<a><b>bbb</b><c>ccc</c></a>'
# soup2 = BeautifulSoup(html2, 'lxml')
# print(soup2.prettify())
# b_tag = soup2.b
# print(b_tag)
# # next_sibling 下一个兄弟结点
# print(b_tag.next_sibling) # 结果为 <c>ccc</c>
# previous_sibling 上一个兄弟结点
# c_tag = soup2.c
# print(c_tag.previous_sibling) # 结果为 <b>bbb</b>
# next_siblings 下一个所有兄弟结点
# a_tag = soup.a
# print(a_tag.next_siblings) # 结果为 <generator object PageElement.next_siblings at 0x000002A0DFF6C270>生成器对象
# # previous_sibling
# for p in a_tag.next_siblings: # 遍历获取
# print(p)
# print('-'*50)
# previous_siblings上一个所有兄弟结点
# a_tag = soup.a
# print(a_tag.previous_siblings) # 结果为 <generator object PageElement.previous_siblings at 0x00000256929DC270>生成器对象
# # previous_sibling
# for p in a_tag.previous_siblings: # 遍历获取
# print(p)
# print('-'*50)
搜索树
1、字符串过滤器
2、列表过滤器
print(soup.find('a')) # 此时'a'是字符串过滤器
print(soup.find_all(['title','b'])) # 此时['title','b'] 列表过滤器
select()方法
我们也可以通过css选择器的方式来提取数据。但是需要注意的是这里面需要我们掌握css语法
https://www.w3school.com.cn/cssref/css_selectors.asp
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,features="lxml")
# soup = BeautifulSoup(html_doc,"lxml")# 1 找a标签
# print(soup.select('a')) # 通过标签的名称查找# 2 通过类名来查找class="sister"
'''
选择 class="intro" 的所有元素。.intro
class="sister" .sister
'''
# print(soup.select(class_='sister'))
# print(soup.select('.sister'))# 3 通过id查找
'''
选择 id="firstname" 的元素。
#firstnameid="link1" --> #link1
'''
# print(soup.select('#link1'))# 特殊的查找方式
# print(soup.select('head > title'))# 获取文本内容
# print(soup.select('title')[0].string)
# print(soup.select('title')[0].get_text())
修改文档树
1、修改tag的名称和属性
2、修改string 属性赋值,就相当于用当前的内容替代了原来的内容
3、append() 像tag中添加内容,就好像Python的列表的 .append() 方法
4、decompose() 修改删除段落,对于一些没有必要的文章段落我们可以给他删除掉
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,features="lxml")
soup = BeautifulSoup(html_doc,"lxml")
'''
• 修改tag的名称和属性
• 修改string 属性赋值,就相当于用当前的内容替代了原来的内容
• append() 像tag中添加内容,就好像Python的列表的 .append() 方法
• decompose() 修改删除段落,对于一些没有必要的文章段落我们可以给他删除掉
'''# tap_p = soup.p
# print(tap_p) # 结果为 <p class="title"><b>The Dormouse's story</b></p> 原内容
# #修改tag的名称和属性
# tap_p.name = 'w' # 修改名称
# tap_p['class'] = 'content'
# print(tap_p) # 结果为 <w class="content"><b>The Dormouse's story</b></w> 修改后# tap_p = soup.p
# print(tap_p.string) # 结果为 The Dormouse's story 原内容
# # 修改string 属性赋值,就相当于用当前的内容替代了原来的内容
# tap_p.string = 'you need python'
# print(tap_p.string) # 结果为 you need python 修改后# tap_p = soup.p
# print(tap_p) # 结果为 <p class="title"><b>The Dormouse's story</b></p> 原内容
# # append() 像tag中添加内容,就好像Python的列表的 .append() 方法
# tap_p.append('123')
# print(tap_p) # 结果为 <p class="title"><b>The Dormouse's story</b>123</p> 修改后# decompose() 修改删除段落,对于一些没有必要的文章段落我们可以给他删除掉
r = soup.find(class_='title')
r.decompose()
print(soup)