爬虫时如何利用BeautifulSoup获取我们需要的数据?

news/2024/7/19 9:28:14 标签: 爬虫, beautifulsoup, python, html, find_all

html" title=爬虫>爬虫大致可以分为三步:

  • 第一步,发送request请求获得html内容
  • 第二步,清洗数据,即从html原网页数据中筛选我们需要的数据
  • 第三步,将需要的数据储存
    在第二步筛选数据是,我们往往可以利用BeautifulSoup来完成,下面就如何利用BeautifulSoup来解析原html网页数据并获取我们需要的内容进行讲解。

1 认识HMTL的结构 – 预备知识

html中有两个很重要的概念就是标签属性,可以说html就是有一个一个的标签和标签之间的内容构成的,标签位于<>之后,通常都是成对出现。
详细内容参可以参考:菜鸟教程html

1.1 标签

标签位于<>之中,一般都是成对出现,格式如下:
<标签>内容</标签>

直接上上一段html代码,所有红色字体部分都是标签:

html"><!DOCTYPE html>
<html>
<head>
	<title>The Dormouse's story</title>
</head>
<body>
	<!-- a href="http://example.com/elsie" class="sister" id="link0">link0</a -->
	<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
	<p>一个图像:<img src="smiley.gif" alt="Smiley face" width="32" height="32"></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">this a new story</p>
</body>
</html>

代码中,所有红色字体的都是标签,比如、

,并且标签都是成对出现, 起始标签和结束标签之间的白色字体部分(可能嵌套了其他标签)就是文本内容。这段html的显示效果如下:
在这里插入图片描述

1.2 属性

属性,就是用来描述标签的一些特性,比如 < a>标签代表是链接,href属性就是给定了这个标签链接的具体地址。再比如,标签代表图像,src代表了图片的路径,width和height属性分别指定了图片的宽度和高度。属性位于起始所在的<>中,并且跟在起始标签的后面,格式如下:
<标签 属性名1= 属性值1 属性名2 = 属性值2>内容</标签>
上面html代码中,橘黄色部分就是属性名,绿色部分就是对应的属性值,中间用=连接

1.3 文本内容与标签内容

这两个概念可能并不准确,只是为了方便后续描述。因为使用BeautifulSoup方法时,返回的内容基本上都是标签内容文本内容
这简单来说,起始标签和结束标签之间的所有部分(包含起始标签和结束标签)就是这个标签对应的标签内容。而文本内容就是位于起始标签和结束标签之间<>之外的的部分。这句话感觉有点奇怪,该怎么理解呢?
举个例子:

html"><title>The Dormouse's story</title>

对于title来说,标签内容是:<title>The Dormouse's story</title>
文本内容就是:The Dormouse's story

html"><p class="title" name="dromouse"><b>The Dormouse's story</b></p>

对于标签p来说,文本内容就是:The Dormouse’s story,因为中间嵌套了另外一个标签b,但是内容是不算b的,因为b属于标签,位于<>之中。当然也可以说标签b的文本内容是:The Dormouse’s story。这个标签的标签内容就是:<p class="title" name="dromouse"><b>The Dormouse's story</b></p>

为上面要强调这个概念呢?因为html" title=爬虫>爬虫很多时候都是需要获取文本内容,BeautifulSoup很多方法返回的就是标签内容标签内容组成的列表,标签内容进一步通过**.string或者.text就可以得到文本内容**。

2 初识BeautifuSoup

2.1 BeautifulSoup四大对象

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

  • Tag, 标签,即对应html中的标签
  • NavigableString,遍历字符串,即对应html中的内容
  • BeautifulSoup,soup对象,可以看作是一个特殊的tag,代表文档的全部内容
  • Comment,可以看作是特殊的NavigableString,代表文档中注释的字符串

由于BeautifulSoup将html文档转化成立包含四种对象的复杂树形结构,因此,可以利用着四种对象来获取html中不同的内容。

2.2 .tag获取一个标签内容

< 标签>起止标签以及这部分就是标签内容< /标签>, 很多时候我们需要先提取两个标签之间的那部分内容,为了方便叙述,成为标签内容。注意,这部分内容可能还嵌套了其它的标签。
假如我们已经构造了一个BeautifulSoup对象soup,那么就可以利用soup.tag的方式获取标签对应的那部分内容,注意这个内容是包含标签本身的。
废话少说,直接上html" title=python>python代码演示:

html" title=python>python">import requests
from bs4 import BeautifulSoup
html = """
<html>
<head>
	<title>The Dormouse's story</title>
</head>
<body>
	<!-- a href="http://example.com/elsie" class="sister" id="link0">link0</a -->
	<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
	<p>一个图像:<img src="smiley.gif" alt="Smiley face" width="32" height="32"></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">this is a new story</p>
</body>
</html>
"""

soup = BeautifulSoup(html, 'xml')
print(soup.head)
print(soup.p)
print(soup.b)

显示结果如下:
在这里插入图片描述
对比原来的html代码可以知道,soup.tag可以提取html中tag对应的那部分内容,并且保留了原来的格式。需要注意的是,如果html中有多个相同的标签,soup.tag只能提取里面的第一个标签对应的内容
比如原html中有多个p标签,soup.p只是提取了第一个p标签代表的内容。如果要获取每个标签对应内容怎么办呢?可以使用find_all()函数,后面再讲。
html代码我们可以知道,第一个p标签对应的内容如下:

html"><p class="title" name="dromouse"><b>The Dormouse's story</b></p>

我们还可以进一步提取里里面的属性值,方法如下:
soup.tag[属性名]:

html" title=python>python">print(soup.p['class'])
print(soup.p['name'])

上面两行代码显示如下:
title
dromouse
当然也可以用get函数来获取属性值
soup.p.get(‘name’) 与 soup.p[‘name’] 效果是一样的。

另外需要说明的时,如果利用soup.tag获取某个标签内容,还可以对里面的标签内容进行遍历:
假如获取了某个个p标签内容如下:

html"><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标签内容余下按部分按照嵌套的标签内容文本内容可以分为7个部分:

html"><p class="story">【1 Once upon a time there were three little sisters; and their names were】
		【2 <a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>】【3 ,】
		【4 <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>】 【5 and】
		【6 <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>】【7 ;
		and they lived at the bottom of a well.】
	</p>

划分的依据就是,如果是新的标签或文本就是一个单独的元素。这样我们可以通过遍历的方式得到里面的每一个元素:

html" title=python>python"># 假如已经通过BeautifulSoup获取上面p标签内容tag_pContent,就可以遍历里面的7个元素了
for t in tag_pContent:
	print(t)

2.3 .string或.text获取标签中间的文本内容

前面专门强调了文本内容这个概念,因为很多时候我们就是要获取标签之外的文本内容。
利用2.2中方法获取了标签内容之后,要获取文本内容就很简单了,因为文本内容包含在起始标签与结束标签之间。方法:
soup.tag.stringsoup.tag.text, 其中,soup.tag获取了标签内容,再加上**.string.text**就可以获取里面的文本内容了。
接着上面的例子:
print(soup.p.string) 或print(soup.p.text)就会显示如下:
The Dormouse’s story

2.4 BeautifulSoup可以看作是特殊的tag

BeautifulSoup 对象表示的是一个文档的全部内容.大部分时候,可以把它当作 Tag 对象,是一个特殊的 Tag,我们可以分别获取它的类型,名称,以及属性来感受一下:

html" title=python>python">print type(soup.name)
#<type 'unicode'>
print soup.name 
# [document]
print soup.attrs 
#{} 空字典

2.5 Comment

Comment 对象是一个特殊类型的 NavigableString 对象,其实输出的内容仍然不包括注释符号,但是如果不好好处理它,可能会对我们的文本处理造成意想不到的麻烦。
加入soup.a对应的内容如下:

html"><a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>

那么soup.a.string输出如下:
Elsie
实际上,Elsie是注释内容!,因此Comment可以看作是特殊的NavigableString对象。但是和类型不同,soup.a.string的类型为<class ‘bs4.element.Comment’>,因此为了造成意想不到的麻烦,可以用如下判断进行区分:

html" title=python>python">if type(soup.a.string)==bs4.element.Comment:
  print("这是注释")

3 BeautifulSoup常用的一些函数或属性

find_all_184">3.1 find以及find_all函数返回标签内容

BeafutifulSoup中有很多函数,但是这个两个函数几乎是用得最多的,所以重点讲一下。find和find_all这两个函数和soup.tag获取的内容的形式都是一样,都是获取标签内容
先看下函数原型吧:

html" title=python>python">find_all( tag_name , attrs , recursive , text , **kwargs ) # 返回列表
find( tag_name , attrs , recursive , text , **kwargs ) # 返回一找到的一个元素

这个两个函数区别就是,find只会返回满足条件的第一个标签内容,而find_all会将所有满足条件的标签内容以列表的形式返回。当find函数只使用第一个参数tag_name时,和soup.tag_name的效果时一样的。
比如:
soup.p和soup.find(‘p’)的结果是一样的。
比如对于下面这3个p标签,如何得到最后一个标签内容呢?可以利用标签属性进行过滤,第三个p标签具有class=’story‘的属性,但是前两个没有。
于时:
soup.find(‘p’, class_ =‘story’)

html"><p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p>一个图像:<img src="smiley.gif" alt="Smiley face" width="32" height="32"></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>	
html" title=python>python">print(soup.find('p'))
# 特别需要注意,由于class是html" title=python>python内置关键字,这里参数中需要用class_代替class
print(soup.find('p', class_='story'))

上面两行代码代码打印如下:
在这里插入图片描述
特别需要注意,由于class是html" title=python>python内置关键字,这里参数中需要用class_代替class

3.2 .strings 或.stripped_strings 属性获取所有的文本内容

.strings可以获取所有的文本内容组成的列表(需要通过遍历来访问),但是这个包含了一些原来文本中的一些空白字符,而.stripper_strings可以也是获取所有的文本内容,但是去掉了很多空格或空行。

html" title=python>python">soup = BeautifulSoup(html, 'xml')
for text in soup.strings:   # 遍历所有的文本内容
	print(text)

输出结果如下:
在这里插入图片描述

html" title=python>python">soup = BeautifulSoup(html, 'xml')
for text in soup.stripped_strings:   # 遍历所有的文本内容
	print(text)

在这里插入图片描述

【参考文章】
1、Python中使用Beautiful Soup库的超详细教程


http://www.niftyadmin.cn/n/1074420.html

相关文章

Keepalived模式LVS高可用群集部署

Keepalived模式LVS高可用群集部署一、Keepalived模式LVS高可用群集1. Keepalived2. Keepalived实现原理二、Keepalived模式LVS高可用集群1. NFS共享服务器配置2. 配置节点服务器2.1 配置虚拟IP地址2.2 调整内核ARP响应参数2.3 编辑网页内容3. 配置负载调度器4. 验证一、Keepali…

Haproxy Nginx搭建Web集群部署

Haproxy & Nginx搭建Web集群部署一、Haproxy应用二、Haproxy调度算法三、Haproxy搭建Web集群1. 部署haproxy服务器1.1 关闭防火墙&#xff0c;编译安装Haproxy1.2 Haproxy服务器配置2. 编译安装Nginx服务器3. 启动Haproxy服务4. 测试Web集群一、Haproxy应用 二、Haproxy调度…

编程为什么要使用设计模式?使用设计模式的好处有哪些?

1、 编写什么样的软件&#xff1f; 我们编写的代码除了要实现基本的功能之外&#xff0c;我们肯定希望代码不仅实现了基本的功能&#xff0c;还具有如下优点&#xff1a; 代码结构清晰、易于理解代码易于易于维护代码功能容易扩展良好的复用性以及可移植性…… 1.1 高内聚、…

Redis简介、常用命令及优化

Redis简介、常用命令及优化一、Redis简介Redis优点二、Redis安装部署三、Redis命令工具3.1 redis-cli命令行工具2. redis-benchmark测试工具3. Redis数据库常用命令4. Redis多数据库常用命令四、Redis性能管理一、Redis简介 Redis 是一个开源的、使用C语言编写的NoSQL数据库实…

RSA加密原理与RSA公钥加密系统、数字签名

通过公钥加密系统&#xff0c;可以对传输于两个通信单位之间的消息进行加密&#xff0c;即使窃听者窃听到加密之后的消息&#xff0c;也不能对其破译。 1、RSA公钥加密原理 1.1 几个核心概念 公钥P与公钥函数P()密钥S与密钥函数S() 可以简单理解&#xff0c;一个公钥对应一个…

Nginx Tomcat之负载均衡与动静分离集群部署

Nginx & Tomcat之负载均衡与动静分离集群部署一、Nginx负载均衡与动静分离原理二、实验实验环境1. Nginx服务器配置2. Tomcat服务器配置3. 动静分离配置4. Nginx server配置5. 测试一、Nginx负载均衡与动静分离原理 首页使用精准匹配静态页面使用正则匹配自己处理动态页面…

Linux环境运行mysql脚本

在学习《MySQL 必知必会》这本书时&#xff0c;里面用到了一些样例表&#xff0c;这些表需要我们在自己的环境执行通过执行脚本填充。然后就可以使用mysql语句进行查询和修改了。在填充时需要用到两个脚本&#xff1a; create.sql populate.sql在linux环境下运行的方法如下&am…

Squid代理服务部署

Squid代理服务部署一、Squid服务器二、部署Squid服务1. 编译安装Squid2. 修改Squid配置文件3. Squid运行控制4. 创建Squid服务脚本三、构建传统代理服务器1. Squid服务器配置2. 客户机配置3. Web1服务器配置4. 测试四、构建透明代理服务器1. Web服务器配置2. Squid服务器配置3.…