bs4,全称BeautifulSoup 4 , 它是Python独有的一种解析方式。也就是说只有Python语言才可以通过这种方式去解析数据。

BeautifulSoup 3 只支持Python2,所以已经被淘汰了。

官网的介绍是这样的

Beautiful Soup 提供一些简单的、python 式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。 Beautiful Soup 自动将输入文档转换为 Unicode 编码,输出文档转换为 utf-8 编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup 就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。 Beautiful Soup 已成为和 lxml、html6lib 一样出色的 python 解释器,为用户灵活地提供不同的解析策略或强劲的速度。

看起来很复杂,我用自己的理解,通俗的解释一下

我们知道一个网页的源代码,是由多个标签组成,比如、

、、等等组成的,而bs4就是用来帮我们精确定位标签位置,从而获取标签或者标签属性中内容的工具。bs4默认自带的解析器,但是官方推荐的是更强大 速度更快的 lxml解析器

其他解析器的优缺点

一、bs4的安装

pip install bs4
pip install lxml

使用bs4解析时,推荐使用lxml解析器。这个在用xpath解析的时候也会用到

二、bs4解析原理

  • 首先实例化一个BeautifulSoup对象,并且将页面源代码加载到这个对象里
  • 调用BeautifulSoup对象中的相关属性或者方法进行标签定位和数据提取
1、如何实例化BeautifuSoup对象
a. 导入bs4包
from bs4 import BeautifulSoup
b.实例化对象

网页源代码,又分为本地已经持久化的HTML文件和网络上直接获取的源代码。

如果是本地已经持久化的文件,可以通过下面的方式将源代码加载到bs4对象中

fp = open('xxx.html', 'r', encoding='utf-8')
# lxml:解析器
soup = BeautifulSoup(fp, 'lxml')

如果是通过requests库获取的网页源代码,通过下面的方式进行加载

response = requests.get(url)
html = response.text
soup = BeautifulSoup(html, 'lxml')

c.数据解析的方法和属性

bs4能够将复杂的HTML转换成一个树形结构,每个节点都是Python对象。

soup.tagName(标签名): 返回的是文档中第一次出现tagName对应的标签及其相应内容

soup.tageName1.tageName2:返回tag1中tage2的标签及其内容

soup.find:等同于soup.tagName,返回第一个匹配到的对象

soup.find_all:返回所有的匹配到的对象。

通过查看源码会发现,find的本质其实就是调用了find_all, 然后返回第一个元素

参数解释:

  • name :要查找的标签名(字符串、正则、方法、True)
  • attrs: 标签的属性
  • recursive: 递归
  • text: 查找文本
  • **kwargs :其它 键值参数
    def find(self, name=None, attrs={}, recursive=True, text=None,
**kwargs):
"""Return only the first child of this Tag matching the given
criteria."""
r = None
l = self.find_all(name, attrs, recursive, text, 1, **kwargs)
if l:
r = l[0]
return r

上图是我从某网站截取的部分画面,翻译成HTML如下(只保留了对本次分析有用的部分,为了方便阅读删除了地址的域名信息)

<html>
<head><titel>测试Title</titel></head>
<body>
<div class="test">
<ul>
<li> <a href="zhaosi.html"><img src="123456789.jpg" /><p>尼古拉斯赵四</p></a> </li>
</ul>
</div>
<div class="nr_zt w1180">
<ul>
<li> <a id="star" href="zhengshuang.html"><img src="5940f2cd6b759.jpg" /><p>郑爽</p></a> </li>
<li> <a id="star" href="zhuyilong.html"><img src="5b56e0fabf5bf.jpg" /><p>朱一龙</p></a> </li>
<li> <a id="star" href="zhoudongyu.html"><img src="5a28b93be8155.jpg" /><p>周冬雨</p></a> </li>
<li> <a id="star" href="huyitian_1.html"><img src="5aa36dfbe5f61.jpg" /><p>胡一天</p></a> </li>
<li> <a id="star" href="yiyangqianxi.html"><img src="5a28d243b0382.jpg" /><p>易烊千玺</p></a> </li>
<li> <a id="star" href="dilireba.html"><img src="5a28b69334087.jpg" /><p>迪丽热巴</p></a> </li>
</ul>
</div>
</body>
</html>

看下面几个例子

# 获取第一个li标签
# <li> <a href="http://www.win4000.com/mt/zhengshuang.html"><img src="http://pic1.win4000.com/tj/2017-06-14/5940f2cd6b759.jpg"/><p>郑爽</p></a> </li>
print(soup.li)
# # 获取第一个li标签中a标签
# <a href="http://www.win4000.com/mt/zhengshuang.html"><img src="http://pic1.win4000.com/tj/2017-06-14/5940f2cd6b759.jpg"/><p>郑爽</p></a>
print(soup.li.a)
#获取第一个li标签中a标签
print(soup.find('li').a)
# 获取所有li标签
print(soup.find_all('li'))
# 获取title标签
print(soup.title)
# 获取a标签的父级标签
print(soup.a.parent)
# 获取a标签的父级标签的名字
print(soup.a.parent.name)

如何获取HTML中的href?

分析:href是a标签中的一个属性,而a标签又在li标签中

在bs4中提取标签中的属性可以通过attrs来获取

from bs4 import BeautifulSoup

fp = open('baidu.html', 'r', encoding='utf-8')
soup = BeautifulSoup(fp, 'lxml') # 如果获取一个可以这样写
result = soup.a.attrs['href']
# zhaosi.html
print(result) # 获取全部,可通过先获取a标签 然后遍历获取
all_result = soup.find_all('a')
for i in all_result:
print(i.attrs['href']) print("* " * 40)
# 如果我只想获取id = star的href,需要先对id进行筛选
# 返回所有包含id=star的a标签
star_result = soup.find_all('a', id='star')
for i in star_result:
print(i.attrs['href']) # 返回包含id的标签(只要有id属性,并且有值的标签都返回)
soup.find_all(id=True) # 假设尼古拉斯赵四 不是第一个a标签中的内容.提取对应的href
# 需要先定位class=‘test’对应div的位置
# 方法一:
result = soup.find('div', 'test')
print(result.a['href']) # 方法二(class为python中关键字,因此查找html中的class属性需要添加个下划线 class_)
result1 = soup.find('div', class_='test')
print(result1.a['href']) # 方法三
result2 = soup.find('div', attrs={'class': 'test'}) # 获取第一个a标签中的文本内容
print(soup.a.text) a_result = soup.find_all('a')
for i in a_result:
# 生成的是一个迭代器
print(i.strings)
print(list(i.strings))
print(i.string)
print(i.text)

其他补充

# 返回子孙节点
# children返回迭代器
result = soup.a.children
for i in result:
print(i) # 返回子孙节点, contents返回列表
r = soup.a.contents
print(r) # 可以通过正则对某个属性进行匹配
# 比如返回href中以zh开头的标签
import re
reg = re.compile('^zh')
result = soup.find_all(href=reg)
print(result)

选择器

bs4非常强大,还支持css选择器。通过select来完成

<html>
<head><titel>测试Title</titel></head>
<body>
<div class="test">
<ul>
<li> <a href="zhaosi.html"><img src="123456789.jpg" /><p>尼古拉斯赵四</p></a> </li>
</ul>
</div>
<div class="nr_zt w1180">
<ul>
<li> <a id="star" href="zhengshuang.html"><img src="5940f2cd6b759.jpg" /><p>郑爽</p></a> </li>
<li> <a id="star" href="zhuyilong.html"><img src="5b56e0fabf5bf.jpg" /><p>朱一龙</p></a> </li>
<li> <a id="star" href="zhoudongyu.html"><img src="5a28b93be8155.jpg" /><p>周冬雨</p></a> </li>
<li> <a id="star" href="huyitian_1.html"><img src="5aa36dfbe5f61.jpg" /><p>胡一天</p></a> </li>
<li> <a id="star" href="yiyangqianxi.html"><img src="5a28d243b0382.jpg" /><p>易烊千玺</p></a> </li>
<li> <a id="star" href="dilireba.html"><img src="5a28b69334087.jpg" /><p>迪丽热巴</p></a> </li>
</ul>
</div>
</body>
</html>
from bs4 import BeautifulSoup

fp = open('baidu.html', 'r', encoding='utf-8')
soup = BeautifulSoup(fp, 'lxml') # 返回一个所有a标签的列表
result = soup.select('a')
# 返回第一个
result1 = soup.select('a')[0] """
class选择器 : .className
"""
# 一层一层的进行选择,用 > 连接 即 > : 表示一个层级
# 输出 class = nr_zt 下ul下的li下的a标签集合
a = soup.select('.nr_zt > ul > li > a')
# 多个层级关联,使用 空格。
# 输出 class= 'nr_zt' 下的a标签集合
b = soup.select('.nr_zt a') """
id选择器: # idName
"""
result = soup.select('#star') # 通过href属性查找,返回列表
soup.select('a[href="zhengshuang.html"]') # 获取对应标签中img标签的src值
a = soup.select('a[href="zhengshuang.html"]')[0]
print(a.img['src']) # 5940f2cd6b759.jpg

以上就是bs4的常用操作代码,实际上在具体的爬虫过程中,匹配的方式比较灵活,所以大家也不用可以的去背,只需要记住其原理即可。

爬虫系列 | 6、详解爬虫中BeautifulSoup4的用法的更多相关文章

  1. CSS学习笔记(9)--详解CSS中:nth-child的用法

    详解CSS中:nth-child的用法 前端的哥们想必都接触过css中一个神奇的玩意,可以轻松选取你想要的标签并给与修改添加样式,是不是很给力,它就是“:nth-child”. 下面我将用几个典型的实 ...

  2. 爬虫系列---selenium详解

    一 安装 pip install Selenium 二 安装驱动 chrome驱动文件:点击下载chromedriver (yueyu下载) 三 配置chromedrive的路径(仅添加环境变量即可) ...

  3. Python Deque 模块使用详解,python中yield的用法详解

    Deque模块是Python标准库collections中的一项. 它提供了两端都可以操作的序列, 这意味着, 你可以在序列前后都执行添加或删除. https://blog.csdn.net/qq_3 ...

  4. Python爬虫系列-Selenium详解

    自动化测试工具,支持多种浏览器.爬虫中主要用来解决JavaScript渲染的问题. 用法讲解 模拟百度搜索网站过程: from selenium import webdriver from selen ...

  5. Python爬虫系列-BeautifulSoup详解

    安装 pip3 install beautifulsoup4 解析库 解析器 使用方法 优势 劣势 Python标准库 BeautifulSoup(markup,'html,parser') Pyth ...

  6. Python爬虫系列-PyQuery详解

    强大又灵活的网页解析库.如果你觉得正则写起来太麻烦,如果你觉得BeautifulSoup语法太难记,如果你熟悉jQuery的语法,那么PyQuery就是你的最佳选择. 安装 pip3 install ...

  7. 详解CSS中:nth-child的用法

    前端的哥们想必都接触过css中一个神奇的玩意,可以轻松选取你想要的标签并给与修改添加样式,是不是很给力,它就是“:nth-child”. 下面我将用几个典型的实例来给大家讲解:nth-child的实际 ...

  8. 详解Lombok中的@Builder用法

    Builder 使用创建者模式又叫建造者模式.简单来说,就是一步步创建一个对象,它对用户屏蔽了里面构建的细节,但却可以精细地控制对象的构造过程. 基础使用 @Builder注释为你的类生成相对略微复杂 ...

  9. 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程

    反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑)   背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...

  10. python 3.x 爬虫基础---Urllib详解

    python 3.x 爬虫基础 python 3.x 爬虫基础---http headers详解 python 3.x 爬虫基础---Urllib详解 前言 爬虫也了解了一段时间了希望在半个月的时间内 ...

随机推荐

  1. SpringBoot集成Swagger2并配置多个包路径扫描

    1. 简介   随着现在主流的前后端分离模式开发越来越成熟,接口文档的编写和规范是一件非常重要的事.简单的项目来说,对应的controller在一个包路径下,因此在Swagger配置参数时只需要配置一 ...

  2. vue 循环结构 v-for

    循环结构 v-for 循环数组 用于循环取得数据,类似于js中for-in循环 ,其中in左侧为值,其名称可以自定义,in后为想要取出数据的变量名 运行可以得到结果 in左侧不仅仅只可以放一个值,不仅 ...

  3. ssh 免密码登陆设置不成功

    记一次centos6设置免密码登陆设置不成功的解决.自己挖的坑自己填. ssh 免密码登陆设置( 正常情况下是这样的,设置成功后登陆主机是不需要密码的) [root@master .ssh]# ssh ...

  4. Python 刷题笔记

    Python 刷题笔记 本文记录了我在使用python刷题的时候遇到的知识点. 目录 Python 刷题笔记 选择.填空题 基本输入输出 sys.stdin 与input 运行脚本时传入参数 Pyth ...

  5. 使用js方法将table表格中指定列指定行中相同内容的单元格进行合并操作。

    前言 使用js方法对html中的table表格进行单元格的行列合并操作. 网上执行此操作的实例方法有很多,但根据实际业务的区别,大多不适用. 所以在网上各位大神写的方法的基础上进行了部分修改以适合自己 ...

  6. 将.Net Core发布至Docker,并连接 Redis、上传文件到本机、连接sqlserver数据库

    此片文章目标是将 .Net Core 发布到 Docker 上,并且连接到在 Docker上的 Redis .上传文件到本机文件夹和连接 sqlserver 数据库. 创建项目 创建项目就不用说了,我 ...

  7. Python基础(上篇)

    本篇文章主要内容:变量.注释.运算符.关键字.数据类型. 在入手变量之前我们先来看看经典的编程语句 → hello world 在python3中输出到控制台的函数是print() print(&qu ...

  8. 实体类转json 和 json转实体类

    1.new JSONObject().toJSONString(rootEntity) JSONObject.toJSONString(specPrices)//specPrices实体类   2. ...

  9. maven 父子项目 pom

    父项目 <!--项目 id--> <artifactId>expressway-cloud-travel</artifactId> <!-- 子模块--> ...

  10. CTF:从0到1 -> zero2one

    本篇blog首发0xffff论坛(CTF:从0到1->zero2one - 0xFFFF),中间有各位大佬补充,搬到了个人博客CTF:从0到1 -> zero2one | c10udlnk ...