0

0

爬虫的解析方式二:Beautifulsoup

爱喝马黛茶的安东尼

爱喝马黛茶的安东尼

发布时间:2019-06-05 13:25:34

|

2713人浏览过

|

来源于CSDN

转载

众多语言都能进行爬虫,但基于python的爬虫显得更加简洁,方便。爬虫也成了python语言中必不可少的一部分。爬虫的解析方式也是多种多样。

Requests库的用法大家肯定已经熟练掌握了,但是当我们使用Requests获取到网页的 HTML 代码信息后,我们要怎样才能抓取到我们想要的信息呢?我相信大家肯定尝试过很多办法,比如字符串的 find 方法,还有高级点的正则表达式。虽然正则可以匹配到我们需要的信息,但是我相信大家在匹配某个字符串一次一次尝试着正则匹配的规则时,一定很郁闷。

那么,我们就会想有没有方便点的工具呢。答案是肯定的,我们还有一个强大的工具,叫BeautifulSoup。有了它我们可以很方便地提取出HTML或XML标签中的内容,这篇文章就让我们了解下BeautifulSoup的常用方法吧。

上一篇给大家讲解的是爬虫的解析方式一:JOSN解析,本篇给大家带来Beautifulsoup解析。

zz.jpg


什么是BeautifulSoup?

Python的网页解析可以用正则表达式去完成,那么我们在写的时候,要挨个的去把代码拿出来匹配,而且还要写匹配的规则,整体实现起来就很复杂。BeautifulSoup呢,它是一个方便的网页解析库,处理高效,支持多种解析器。大部分情况下,利用它我们不在需要编写正则表达式就可以方便的实现网页信息的提取。

官方文档

安装:$ pip install beautifulsoup4

BeautifulSoup是一个网页解析库,它支持很多解析器,不过最主流的有两个。一个是Python标准库,一个是lxml HTML 解析器。两者的使用方法相似:

from bs4 import BeautifulSoup
 
# Python的标准库
BeautifulSoup(html, 'html.parser')
 
# lxml
BeautifulSoup(html, 'lxml')

   

Python内置标准库的执行速度一般,但是低版本的Python中,中文的容错能力比较差。lxmlHTML 解析器的执行速度快,但是需要安装 C语言的依赖库。

lxml的安装

由于lxml安装需要依赖C语言库,所以当lxml在Windows上安装时,我们会发现各种奇怪的报错,当然脸好的使用pip install lxml

安装也是可以成功的。不过大部分人都是会倒在这里。

这里推荐大家使用lxml的.whl文件来安装。首先我们需要安装一下wheel库,有了这个库我们才可以正常安装.whl文件。pip install wheel

从官方网站下载与系统,Python版本匹配的lxml文件。

另外,不知道自己系统和python版本信息的伙伴。需要进入系统管理员工具(CMD)或者python的 IDLE,输入以下代码:

import pip
 
print(pip.pep425tags.get_supported())

   

这时我们就可以看到打印出来的Python版本信息了。
下载好lxml的文件后,我们需要找到文件的位置,然后进入管理员工具,使用pip安装:pip install whl文件的全名

安装完成后,可以进入Python,import一下,如果没有报错,那么恭喜你安装成功。
如果有的伙伴觉得麻烦,那我推荐大家安装anaconda 下载地址(如果安装速度慢,可以找国内镜像),不知道是什么的小伙伴可以谷歌一下,有了他,那些在windows上pip安装出错的问题将不再存在。


BeautifulSoup的基本标签选择方法

虽然Python内置的标准库解析器还不错,但是我还是推荐大家使用lxml,因为它够快。那么后面的代码我们都是用lxml解析器来进行演示。
我们先导入官方文档的例子:

html_doc = """
The Dormouse's story

The Dormouse's story

Once upon a time there were three little sisters; and their names were Elsie, Lacie and Tillie; and they lived at the bottom of a well.

...

"""

   

HTML 代码,我们能够得到一个BeautifulSoup的对象,并能按照标准的缩进格式的结构输出:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'lxml')

   

我们可以看到上面的 HTML 代码并不完整,接下来我们使用prettify()方法来进行自动补全,注释部分就是运行的输出:

print(soup.prettify())
# 
#  
#   
#    The Dormouse's story
#   
#  
#  
#   

# # The Dormouse's story # #

#

# Once upon a time there were three little sisters; and their names were # # Elsie # # , # # Lacie # # and # # Tillie # # ; and they lived at the bottom of a well. #

#

# ... #

# #

   

获取标签

print(soup.title)
# The Dormouse's story

   

通过输出结果,我们可以看到获取内容的属性,实际上就是 HTML 代码里的一个title标签。

获取名称

print(soup.title.name)
# 'title'

   

实际上就是标签的名称。

获取属性

print(soup.p.attrs['class'])
# 'title'
 
print(soup.p['class'])
# 'title'

   

获取标签的属性我们可以使用attrs方法,传给他属性名,就可以得到标签的属性。通过结果我们可以看到,直接传给p标签属性名,一样可以获取到标签属性。

获取内容

print(soup.title.string)
# 'The Dormouse's story'

   

我们还可以使用嵌套的选择,比如我们获得body标签里面p标签的内容:

print(soup.body.p.string)
# 'The Dormouse's story'

   

常见用法

标准选择器

虽然BeautifulSoup的基本用法,标签获取,内容获取,可以解析一些 html代码。但是在遇到很多复杂的页面时,上面的方法是完全不足的,或者是很繁琐的,因为有时候有的标签会有几个属性(class、id等)。

索性BeautifulSoup给我们提供了很方便的标准选择器,也就是 API 方法,这里着重介绍2个: find() 和 find_all() 。其它方法的参数和用法类似,大家举一反三吧。

find_all()

find_all(name, attrs, recursive, text, **kwargs)可以根据标签,属性,内容查找文档。
find_all()其实和正则表达式的原理很相似,他能找出所有能满足匹配模式的结果,在把结果以列表的形式返回。
仍然是文档的例子:

html_doc = """
The Dormouse's story

The Dormouse's story

Once upon a time there were three little sisters; and their names were Elsie, Lacie and Tillie; and they lived at the bottom of a well.

...

""" from bs4 import BeautifulSoup soup = BeautifulSoup(html_doc, 'lxml')

   

过滤器

海螺AI
海螺AI

MiniMax平台的AI对话问答工具,你的AI伙伴

下载

文档参考
介绍 find_all() 方法前,大家可以参考一下过滤器的类型。过滤器只能作为搜索文档的参数,或者说应该叫参数类型更为贴切。这些过滤器贯穿整个搜索的API。过滤器可以被用在 tag 的name中,节点的属性中,字符串中或他们的混合中。

find_all() 方法搜索当前 tag 的所有 tag 子节点,并判断是否符合过滤器的条件。这里有几个例子:

soup.find_all("title")
# [The Dormouse's story]
 
soup.find_all("p", "title")
# [

The Dormouse's story

] soup.find_all("a") # [Elsie, # Lacie, # Tillie] soup.find_all(id="link2") # [Lacie]

   

有几个方法很相似,还有几个方法是新的,参数中的 string 和id是什么含义? 为什么 find_all("p", "title") 返回的是CSS Class为”title”的标签? 我们来仔细看一下find_all()的参数:

name参数

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

soup.find_all("title")
# [The Dormouse's story]

   

搜索 name 参数的值可以使任一类型的过滤器,字符窜,正则表达式,列表,方法或是True 。
我们常用的 name 参数是搜索文档的标签名。

keyword参数

如果我们的 HTML代码中有几个div标签,但是我们只想获取到class属性为top的div标签,我们怎么出来呢。

soup.find_all('div', class_='top')

# 这里注意下,class是Python的内部关键词,我们需要在css属性class后面加一个下划线'_',不然会报错。

   

仍然以上面的代码实例:

soup.find_all('a', id='link2')
# [Lacie]

   

这样我们就只获取到id为link2的a标签。

limit参数

find_all() 方法返回全部的搜索结构,如果文档树很大那么搜索会很慢。如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数量。效果与 SQL 中的limit关键字类似,当搜索到的结果数量达到limit的限制时,就停止搜索返回结果。

比如我们要搜索出a标签,但是满足的有3个,我们只想要得到2个:

soup.find_all("a", limit=2)
# [Elsie,
# Lacie]

   

其他的参数,不是经常用到,大家如需了解可以参考官方文档。

find()

find_all()返回的是所有元素列表,find()返回单个元素。

find( name , attrs , recursive , string , **kwargs )

find_all()方法将返回文档中符合条件的所有 tag,尽管有时候我们只想得到一个结果。比如文档中只有一个标签,那么使用find_all()方法来查找标签就不太合适, 使用find_all方法并设置limit=1参数不如直接使用find()方法。下面两行代码是等价的:

soup.find_all('title', limit=1)
# [The Dormouse's story]
 
soup.find('title')
#The Dormouse's story

   

唯一的区别是find_all()方法的返回结果是值包含一个元素的列表,而find()方法直接返回结果。find_all()方法没有找到目标是返回空列表, find()方法找不到目标时,返回None。

CSS选择器

Beautiful Soup支持大部分的 CSS选择器。在Tag或BeautifulSoup对象的.select()方法中传入字符串参数, 即可使用 CSS选择器的语法找到 tag。我们在写 css 时,标签 class类名加”.“,id属性加”#“。

soup.select("title")
# [The Dormouse's story]

   

通过 tag标签逐层查找:

soup.select("body a")
# [Elsie,
#  Lacie,
#  Tillie]
 
soup.select("html head title")
# [The Dormouse's story]

   

找到某个 tag标签下的直接子标签:

soup.select("head > title")
# [The Dormouse's story]
 
soup.select("p > a")
# [Elsie,
#  Lacie,
#  Tillie]
 
soup.select("p > #link1")
# [Elsie]
 
soup.select("body > a")
# []

   

通过 CSS 的 class类名查找:

soup.select(".sister")
# [Elsie,
#  Lacie,
#  Tillie]

   

通过 tag 的 id 查找:

soup.select("#link1")
# [Elsie]
 
soup.select("a#link2")
# [Lacie]

   

同时用多种 CSS选择器查询元素,使用逗号隔开:

soup.select("#link1,#link2")
# [Elsie,
#  Lacie]

   

提取标签内容

如果我们得到了几个标签:

list = [百度,
 
网易,
 
]

   

我们要怎样提取他里面的内容呢。我们开始的时候有提及。

for i in list:
    print(i.get_text()) # 我们使用get_text()方法获得标签内容
    print(i.get['href'] # get['attrs']方法获得标签属性
    print(i['href']) # 简写结果一样

   

结果:

百度
网易
新浪
http://www.baidu.com/
http://www.163.com/
http://www.sina.com/
http://www.baidu.com/
http://www.163.com/
http://www.sina.com/

   

总结

BeautifulSoup的解析库,推荐使用lxml,如果出现乱码的情况下,可以使用html.parser;BeautifulSoup的标签选择筛选方法,虽然弱但是速度快;推荐使用find_all(),find()方法搜索标签,当然如果对css选择器熟悉,推荐使用.select()方法;get_text()方法获取标签文本内容,get[attrs]方法获取标签属性值。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

707

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

625

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

735

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

616

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1234

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

573

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

695

2023.08.11

虚拟号码教程汇总
虚拟号码教程汇总

本专题整合了虚拟号码接收验证码相关教程,阅读下面的文章了解更多详细操作。

25

2025.12.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 2.5万人学习

SciPy 教程
SciPy 教程

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号