Python爬虫入门——BeautifulSoup库

news2024/11/19 14:52:12

一、前言

这篇来演示如何使用BeautifulSoup模块来从HTML文本中提取我们想要的数据。

update on 2016-12-28:之前忘记给BeautifulSoup的官网了,今天补上,顺便再补点BeautifulSoup的用法。

update on 2017-08-16:很多网友留言说Unsplash网站改版了,很多内容是动态加载的。所以建议动态加载的内容使用PhantomJS而不是Request库进行请求,如果使用PhantomJS请看我的下一篇博客,如果是定位html文档使用的class等名字更改的话,建议大家根据更改后的内容进行定位,学爬虫重要的是爬取数据的逻辑,逻辑掌握了网站怎么变都不重要啦。

二、运行环境


我的运行环境如下:

  • 系统版本
    Windows10。

  • Python版本
    Python3.5,推荐使用Anaconda 这个科学计算版本,主要是因为它自带一个包管理工具,可以解决有些包安装错误的问题。去Anaconda官网,选择Python3.5版本,然后下载安装。

  • IDE
    我使用的是PyCharm,是专门为Python开发的IDE。这是JetBrians的产品,点我下载。

三、模块安装


BeautifulSoup 有多个版本,我们使用BeautifulSoup4。详细使用看BeautifuSoup4官方文档。
使用管理员权限打开cmd命令窗口,在窗口中输入下面的命令即可安装:
conda install beautifulsoup4

直接使用Python3.5 没有使用Anaconda版本的童鞋使用下面命令安装:
pip install beautifulsoup4

然后我们安装lxml,这是一个解析器,BeautifulSoup可以使用它来解析HTML,然后提取内容。

Anaconda 使用下面命令安装lxml:
conda install lxml

使用Python3.5 的童鞋们直接使用pip安装会报错(所以才推荐使用Anaconda版本)

如果不安装lxml,则BeautifulSoup会使用Python内置的解析器对文档进行解析。之所以使用lxml,是因为它速度快。

文档解析器对照表如下:

解析器使用方法优势劣势
Python标准库BeautifulSoup(markup,"html.parser")1. Python的内置标准库
2. 执行速度适
3. 中文档容错能力强
Python 2.7.3 or 3.2.2)前 的版本中文档容错能力差
lxml HTML 解析器BeautifulSoup(markup,"lxml")1. 速度快
2. 文档容错能力强
需要安装C语言库
lxml XML 解析器BeautifulSoup(markup,["lxml-xml"])
BeautifulSoup(markup,"xml")
1. 速度快
2. 唯一支持XML的解析器
需要安装C语言库
html5libBeautifulSoup(markup,"html5lib")1. 最好的容错性
2. 以浏览器的方式解析文档
3. 生成HTML5格式的文档
速度慢,不依赖外部扩展

四、BeautifulSoup 库的使用


不同版本的用法差不多,几个常用的语法都一样。

首先来看BeautifulSoup的对象种类,在使用的过程中就会了解你获取到的东西接下来应该如何操作。

4.1 BeautifulSoup对象的类型

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象。所有对象可以归纳为4种类型: Tag , NavigableString , BeautifulSoup , Comment 。下面我们分别看看这四种类型都是什么东西。

4.1.1 Tag

这个就跟HTML或者XML(还能解析XML?是的,能!)中的标签是一样一样的。我们使用find()方法返回的类型就是这个(插一句:使用find-all()返回的是多个该对象的集合,是可以用for循环遍历的。)。返回标签之后,还可以对提取标签中的信息。

提取标签的名字:

tag.name

提取标签的属性:

tag['attribute']
我们用一个例子来了解这个类型:

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')  #声明BeautifulSoup对象
find = soup.find('p')  #使用find方法查到第一个p标签
print("find's return type is ", type(find))  #输出返回值类型
print("find's content is", find)  #输出find获取的值
print("find's Tag Name is ", find.name)  #输出标签的名字
print("find's Attribute(class) is ", find['class'])  #输出标签的class属性值

4.1.2 NavigableString

NavigableString就是标签中的文本内容(不包含标签)。获取方式如下:
tag.string
还是以上面那个例子,加上下面这行,然后执行:
print('NavigableString is:', find.string)

4.1.3 BeautifulSoup

BeautifulSoup对象表示一个文档的全部内容。支持遍历文档树和搜索文档树。

4.1.4 Comment

这个对象其实就是HTML和XML中的注释。

markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
soup = BeautifulSoup(markup)
comment = soup.b.string
type(comment)
# <class 'bs4.element.Comment'>

有些时候,我们并不想获取HTML中的注释内容,所以用这个类型来判断是否是注释。

if type(SomeString) == bs4.element.Comment:
    print('该字符是注释')
else:
    print('该字符不是注释')

4.2 BeautifulSoup遍历方法

4.2.1 节点和标签名

可以使用子节点、父节点、 及标签名的方式遍历:

soup.head #查找head标签
soup.p #查找第一个p标签

#对标签的直接子节点进行循环
for child in title_tag.children:
    print(child)

soup.parent #父节点

# 所有父节点
for parent in link.parents:
    if parent is None:
        print(parent)
    else:
        print(parent.name)

# 兄弟节点
sibling_soup.b.next_sibling #后面的兄弟节点
sibling_soup.c.previous_sibling #前面的兄弟节点

#所有兄弟节点
for sibling in soup.a.next_siblings:
    print(repr(sibling))

for sibling in soup.find(id="link3").previous_siblings:
    print(repr(sibling))

4.2.2 搜索文档树

最常用的当然是find()和find_all()啦,当然还有其他的。比如find_parent() 和 find_parents()、 find_next_sibling() 和 find_next_siblings() 、find_all_next() 和 find_next()、find_all_previous() 和 find_previous() 等等。
我们就看几个常用的,其余的如果用到就去看官方文档哦。

  • find_all()
    搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件。返回值类型是bs4.element.ResultSet。
    完整的语法:
    find_all( name , attrs , recursive , string , **kwargs )
    这里有几个例子
soup.find_all("title")
# [<title>The Dormouse's story</title>]
#
soup.find_all("p", "title")
# [<p class="title"><b>The Dormouse's story</b></p>]
# 
soup.find_all("a")
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
#  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
#  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
#
soup.find_all(id="link2")
# [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
#
import re
soup.find(string=re.compile("sisters"))
# u'Once upon a time there were three little sisters; and their names were\n'

name 参数:可以查找所有名字为 name 的tag。
attr 参数:就是tag里的属性。
string 参数:搜索文档中字符串的内容。
recursive 参数: 调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点。如果只想搜索tag的直接子节点,可以使用参数 recursive=False 。

  • find()
    与find_all()类似,只不过只返回找到的第一个值。返回值类型是bs4.element.Tag。
    完整语法:
    find( name , attrs , recursive , string , **kwargs )
    看例子:
soup.find('title')
# <title>The Dormouse's story</title>
#
soup.find("head").find("title")
# <title>The Dormouse's story</title>

基本功已经练完,开始实战!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/112302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搜索(5):迭代加深、双向dfs

活动 - AcWing 算法竞赛进阶指南 一、迭代加深概述 dfs每次选定一个分支&#xff0c;直到抵达递归边界才回溯&#xff0c;这种策略有一定缺陷。当搜索树的某个分支情况非常多&#xff0c;并且问题的答案在一个较浅的分支上时&#xff0c;如果一开始就选错了分支&#xff0…

在宜宾,看见未来中国的产融平台样本

在被验证的京东西南数字化产融协同平台背后&#xff0c;恰证明着在京东这样的新型实体企业支持下&#xff0c;中国的区域产业经济已经出现星星之火&#xff0c;而这些星星之火正在帮助成千上万的企业走出固有的销售渠道和销售模型&#xff0c;成为新时代数字经济和产业经济的一…

单芯片快速以太网MAC控制器DM9000介绍

DM9000简介 DM9000是一款完全集成的和符合成本效益单芯片快速以太网MAC控制器与一般处理接口&#xff0c;一个10/100M 自适应的PHY 和4K DWORD 值的SRAM。它的目的是在低功耗和高性能进程的3.3V与5V的支持宽容。 DM9000 还提供了介质无关的接口&#xff0c;来连接所有提供支持介…

javaee之spring2

基于注解的IOC配置 一、先来说一下放在对象上面的注解 Component: * 作用&#xff1a;用于把当前类对象存入spring容器中 * 属性&#xff1a; * value&#xff1a;用于指定bean的id。当我们不写时&#xff0c;它的默认值是当前类名&#xf…

RabbitMQ 第一天 基础 5 Spring 整合RabbitMQ 5.2 Spring 整合 RabbitMQ【消费者】 5.3 小结

RabbitMQ 【黑马程序员RabbitMQ全套教程&#xff0c;rabbitmq消息中间件到实战】 文章目录RabbitMQ第一天 基础5 Spring 整合RabbitMQ5.2 Spring 整合 RabbitMQ【消费者】5.2.1 消费者5.3 小结第一天 基础 5 Spring 整合RabbitMQ 5.2 Spring 整合 RabbitMQ【消费者】 5.2.1…

白话说Java虚拟机原理系列【第五章】:内存结构之堆详解

文章目录堆(Heap)对象在堆中的存储结构垃圾收集器详解对象存活判断算法引用的种类对象最终判定死亡之两次标记规则方法区的垃圾回收原则垃圾收集算法分代收集模型垃圾收集器对象分配原则垃圾收集触发方式垃圾收集器的参数异常前导说明&#xff1a; 本文基于《深入理解Java虚拟机…

大数据分析案例-基于逻辑回归算法构建垃圾邮件分类器模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【Django】第二课 基于Django超市订单管理系统开发

概念 本文在上一文之上&#xff0c;针对管理员&#xff0c;经理&#xff0c;普通员工身份的用户操作用户管理模块功能。 功能实现 1.普通员工登录系统后&#xff0c;对于用户管理模块不具备操作其他用户信息的权限。因此当普通员工登录后&#xff0c;弹出对话框提示用户。 2…

【Linux】Linux编辑器---vim的使用

等老了就养只柴犬&#xff0c;相依为命。 文章目录一、命令模式1.光标定位操作2.文本复制、粘贴、剪切、撤销3.文本编辑二、插入模式三、底行模式四、vim配置原理五、解决普通用户无法使用sudo提权一、命令模式 刚打开vim时&#xff0c;默认就是命令模式&#xff0c;命令模式的…

C++STL之string的使用

对于C语言中的字符串&#xff0c;我们只能使用char类型数组保存&#xff0c;并且是以\0结尾的. 操作起来非常不方便而且底层空间需要用户自己访问&#xff0c;非常造成容易越界访问. 这个时候&#xff0c;C的STL中的string类就很好解决了这些. 目录 string的使用 1.string…

mqtt的使用与二次封装

前提&#xff1a;先安装Mosquitto并启动服务&#xff0c;可使用mqttx进行接收发送的测试。 Mosquitto以配置启动命令 mosquitto -c mosquitto.conf -v原文链接&#xff1a;mqtt的使用 本文为测试使用固无账号密码&#xff0c;可在原文查看 封装后实现效果&#xff0c;加入一个…

LeetCode题解 16(15,22) 三数之和,括号生成

文章目录三数之和(15)代码解答:括号生成(22)代码解答:三数之和(15) 该题是让从1个数组中找到和为0的不重复的三个数,这次我们使用排序和指针的方法来解决 先将该数组从小到大进行排序 Arrays.sort(nums);我们需要遍历一遍该数组,同时我们还要去重的操作(例如[-1,-1,-1,2],这里面…

helm本地debug template渲染小记

前提条件 1&#xff0c; 安装helm 2&#xff0c;要能连接的k8s 3&#xff0c;本地有完成charts文件目录 具体步骤 本文因为是在项目流程中helm渲染出的deployment语法报错或者最终生成的不符合预期&#xff0c;因此本地使用helm命令进行debug验证测试。 我们先看一下基本的c…

怎么把word里面的彩色图转化为灰度图,直接在word里面操作,无需转其他软件,超简单!(位图和矢量图都可以)

怎么把word里面的彩色图转化为灰度图&#xff0c;直接在word里面操作&#xff0c;无需转其他软件&#xff0c;超简单&#xff01;&#xff08;位图和矢量图都可以&#xff09; Microsoft Office Word是微软公司的一个文字处理器应用程序。它最初是由Richard Brodie为了运行DOS…

深入理解自编码器(用变分自编码器生成图像)

文章目录自编码器欠完备自编码器正则自编码器稀疏自编码器去噪自编码器收缩自编码器变分自编码器References内容总结自花书《Deep Learning》以及《Python 深度学习》。 自编码器 自编码器&#xff08;autoencoder&#xff09;是神经网络的一种&#xff0c;经过训练后能尝试将…

机器学习经典算法:决策树(2)

1. 概述 决策树&#xff08;Decision Tree&#xff09;是有监督学习中的一种算法&#xff0c;并且是一种基本的分类与回归的方法。决策树有两种&#xff1a;分类树和回归树。 决策树是用于分类和回归的工具&#xff0c;它将数据特征值拆分为决策节点处的分支&#xff08;例如&a…

六、Kubernetes核心技术Pod详解、实例

1、概述 Pod 是 k8s 系统中可以创建和管理的最小单元&#xff0c;是资源对象模型中由用户创建或部署的最 小资源对象模型&#xff0c;也是在 k8s 上运行容器化应用的资源对象&#xff0c;其他的资源对象都是用来支 撑或者扩展 Pod 对象功能的&#xff0c;比如控制器对象是用来管…

某大型政务网站的优化咨询案例(视频点播VOD+GZIP压缩+静态文件CDN+Redis缓存+全文索引)

2022年圣诞节到来啦&#xff0c;很高兴这次我们又能一起度过~ 这次分享关于一个对某大型政务网站的优化咨询的案例&#xff0c;发生在今年的下半年&#xff0c;已过去一段时间&#xff0c;并取得了良好的成果&#xff01;* 项目背景 某大型政务网站准备上线&#xff0c;需要…

08-Golang中的运算符

[TOC](Golang中的运算符运算符介绍算数运算符基本介绍细节说明关系运算符(比较运算符&#xff09;基本介绍细节说明逻辑运算符基本介绍细节说明赋值运算符基本介绍细节说明运算符优先级运算符介绍 运算符是一种特殊的符号&#xff0c;用来表示数据的运算、赋值和比较 1.算数运…

Vue事件处理的基本使用

前言 事件处理在vue中也是非常重要的一项技术&#xff0c;它类似于js的事件处理&#xff0c;但是也有不同&#xff0c;下面就简单介绍一下在vue中如何进行事件使用以及一些要点 1 事件基本使用 在这里我们使用单击事件为例&#xff0c;简单讲讲在vue中单击事件的编写以及细节…