一、 引言

在《第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问》和《第14.11节 Python中使用BeautifulSoup解析http报文:使用查找方法快速定位内容》介绍了通过属性和查找方法定位HTML报文的内容的方法,除了这两种方法还有一种方法就是通过使用CSS选择器的语法找到tag,关于css选择器老猿在此不进行介绍,大家可以自行查找文档了解,老猿推荐W3School 的《CSS 选择器参考手册》。其实不了解也问题不大,本节的内容绝大部分还是很好理解的。

二、 select方法

  1. 语法调用:

    select(selector,namespace=None,limit=None,**kwargs)

  2. 语法释义

    1)参数selector为css选择器,关于CSS 选择器,请参考W3School 的《CSS 选择器参考手册》,具体应用方法请见第三部分;

    2)namespace:为一个映射css选择器名字空间到名字空间URIs的字典,老猿对css选择器没有研究过,使用时一般用缺省参数

    3)limit:限制查找到的内容个数,缺省不限制个数;

    4)kwargs:老猿没有查到相关资料,暂时不使用;

    5)返回值为一个列表,里面包含所有满足条件的html元素。

关于select的参数,官网上没有列出,只在举例中使用了第一个参数,老猿是通过help查出来的参数。不过也说明其他参数不重要,我们也就不关注了。

三、 使用select的几种场景及方法

  1. 本部分的html文本及BeatifulSoap对象定义如下:
>>> html='''<html><head><title>老猿Python</title></head>
<body><div>
<h1 id="l1" class='t1' name="line1">老猿Python第1行</h1>
<h2 id="l2" class='t2' name="line2">老猿Python第2行</h2>
<h3 id="l3" class='t3' name="line3">老猿Python第3行</h3>
<div>
<h1 id="l4" class='t1' name="line4">LaoYuanPython第1行</h1>
<h2 id="l5" class='t2' name="line5">LaoYuanPython第2行</h2>
<h3 id="l6" class='t3' name="line6">LaoYuanPython第3行</h3>
</div>
</div></body></html>'''
>>> soup = BeautifulSoup(html, 'lxml')
>>>
  1. 查找某个名称的所有标签

    要查找某个名称的所有标签,直接在BeatifulSoap对象下调用select,语法如下:

    select(“标签名”)

    如:
>>> soup.select('h1')
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h1 class="t1" id="l1" name="line1">LaoYuanPython第1行</h1>]
>>>

soup.select(‘h1’)效果与soup.find_all(‘h1’)相同。当然调用也可以从某个标签对象发起,这样是查的该标签对象下所有指定名称的标签。如:

>>> soup.div.div.select('h1')
[<h1 class="t1" id="l1" name="line1">LaoYuanPython第1行</h1>]
>>>
  1. 查找某个符合要求的所有标签

    这个功能是“查找某个名称的所有标签”的扩展,也可以说“查找某个名称的所有标签”是本功能的一个特例。

语法为:

select(“css选择器”)

其中css选择器可以是如下内容:

1)标签名:等同于功能“查找某个名称的所有标签”

2)css类名:查找css类名为指定类名的所有html元素,语法为:

select(”.类名”)

注意类名前有个小数点

>>> soup.select('.t1')
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h1 class="t1" id="l1" name="line1">LaoYuanPython第1行</h1>]
>>>

3)属性名:查找存在属性为指定属性名的所有html元素,语法为:

select(”[属性名]”),如:

>>> soup.select('[class]')
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h2 class="t2" id="l2" name="line2">老猿Python第2行</h2>, <h3 class="t3" id="l3" name="line3">老猿Python第3行</h3>, <h1 class="t1" id="l1" name="line1">LaoYuanPython第1行</h1>, <h2 class="t2" id="l2" name="line2">LaoYuanPython第2行</h2>, <h3 class="t3" id="l3" name="line3">LaoYuanPython第3行</h3>]
>>> soup.select('[name]')
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h2 class="t2" id="l2" name="line2">老猿Python第2行</h2>, <h3 class="t3" id="l3" name="line3">老猿Python第3行</h3>, <h1 class="t1" id="l1" name="line1">LaoYuanPython第1行</h1>, <h2 class="t2" id="l2" name="line2">LaoYuanPython第2行</h2>, <h3 class="t3" id="l3" name="line3">LaoYuanPython第3行</h3>]
>>>

4)属性名+属性值查找:

>>> soup.select("[name='line5']")
[<h2 class="t2" id="l5" name="line5">LaoYuanPython第2行</h2>]
>>>

属性名值支持首字符串(使用^符号)匹配、尾字符串匹配(使用$符号)和包含字符串(使用*符号)匹配:

>>> soup.select("[name^='line']") #属性名+属性值开始字符串匹配

[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h2 class="t2" id="l2" name="line2">老猿Python第2行</h2>, <h3 class="t3" id="l3" name="line3">老猿Python第3行</h3>, <h1 class="t1" id="l4" name="line4">LaoYuanPython第1行</h1>, <h2 class="t2" id="l5" name="line5">LaoYuanPython第2行</h2>, <h3 class="t3" id="l6" name="line6">LaoYuanPython第3行</h3>]
>>> soup.select("[name$='e5']") #属性名+属性值尾字符串匹配 [<h2 class="t2" id="l5" name="line5">LaoYuanPython第2行</h2>]
>>> soup.select("[name*='e5']") #属性名+属性值字符串包含内容匹配 [<h2 class="t2" id="l5" name="line5">LaoYuanPython第2行</h2>]
>>>
>>>

5)id名:查找id为指定名字的所有html元素,语法为:

select(”#id名”),如:

>>> soup.select('#l1')
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h1 class="t1" id="l1" name="line1">LaoYuanPython第1行</h1>]
>>>

6)叠加标签:

上述第2-4种方法,可以在选择器前面叠加一个标签名,就可以实现在上述方法的基础上叠加需要满足标签名的要求的查找条件,如:

>>> soup.select("h1.t1") #标签名+css类名
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h1 class="t1" id="l4" name="line4">LaoYuanPython第1行</h1>]
>>> soup.select("h1[name]") #标签名+属性名
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h1 class="t1" id="l4" name="line4">LaoYuanPython第1行</h1>]
>>> soup.select("h1[name=line1]") #标签名+属性名+属性值
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>]
>>> soup.select("h1#l4") #标签名+id值
[<h1 class="t1" id="l4" name="line4">LaoYuanPython第1行</h1>]

注意以上条件组合时,如果标签和后面叠加内容要求是同一个标签下的内容时,标签和后面内容不能加空格,如果加了空格,就是到标签下的子标签中查找后面叠加内容的元素。如:

>>> soup.select("h1#l4") #查找标签为h1且id为l4的标签
[<h1 class="t1" id="l4" name="line4">LaoYuanPython第1行</h1>]
>>> soup.select("h1 #l4") #查找父标签为h1且其下id为l4的子孙标签
[]
>>> soup.select("div #l4") #查找父标签为div且其下id为l4的子孙标签
[<h1 class="t1" id="l4" name="line4">LaoYuanPython第1行</h1>]
>>>

属性名查找支持模糊查找

>>> soup.select("h3[class$='3']") #标签名+属性名1+属性名+属性值尾字符匹配
[<h3 class="t3" id="l3" name="line3">老猿Python第3行</h3>, <h3 class="t3" id="l6" name="line6">LaoYuanPython第3行</h3>]
>>> soup.select("h1[name^='line']") #标签名+属性名+属性值开始字符串匹配
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h1 class="t1" id="l4" name="line4">LaoYuanPython第1行</h1>]
>>>

4. 在某个标签下查找所有子孙节点标签

其中的selector参数填写父标签和子标签名,使用空格分隔,selector参数的实参内容为:“父标签名 子孙标签1 … 子孙标签n”,每个标签鉴间用空格分隔。父标签可以从HTML报文的任意一个标签开始,子孙标签1可以是父标签的直接子标签也可以是更低层次的子孙标签,后面每个子孙标签都是前一个标签的直接子标签或更低层次的子孙标签。如:

>>> soup.div.div.select('h1')
[<h1>LaoYuanPython第一行</h1>]
>>> soup.select('body h2')
[<h2>老猿Python第二行</h2>, <h2>老猿Python第三行</h2>, <h2>LaoYuanPython第二行</h2>, <h2>LaoYuanPython第三行</h2>]
>>> soup.select('body div h2 ')
[<h2>老猿Python第二行</h2>, <h2>老猿Python第三行</h2>, <h2>LaoYuanPython第二行</h2>, <h2>LaoYuanPython第三行</h2>]
>>> soup.select('body div div h2 ')
[<h2>LaoYuanPython第二行</h2>, <h2>LaoYuanPython第三行</h2>]

5. 在某个标签下查找所有直接子标签

其中的selector参数填写父标签和子标签名,使用大于号分隔,selector参数的实参内容为:“父标签名>子孙标签1> …> 子孙标签n”,每个标签鉴间用大于号分隔。父标签可以从HTML报文的任意一个标签开始,子孙标签1必须是父标签的直接子标签,后面每个子孙标签都是前一个标签的直接子标签。如:

>>> soup.select('body>div>h2 ')
[<h2>老猿Python第二行</h2>, <h2>老猿Python第三行</h2>]
>>>

6. 查找解析的某个标签后面的兄弟标签

此功能与《第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问》、《第14.11节 Python中使用BeautifulSoup解析http报文:使用查找方法快速定位内容

》介绍的兄弟标签有所不同。

语法如下:

BeautifulSoup.select(“css选择器1 ~ css选择器2”)

该方法是查找css选择器1确认的首个标签后,到该标签后面内容中的兄弟标签中查找满足css选择器2的兄弟标签。如:

>>> soup.select("[name^='line']")

[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h2 class="t2" id="l2" name="line2">老猿Python第2行</h2>, <h3 class="t3" id="l3" name="line3">老猿Python第3行</h3>, <h1 class="t1" id="l4" name="line4">LaoYuanPython第1行</h1>, <h2 class="t2" id="l5" name="line5">LaoYuanPython第2行</h2>, <h3 class="t3" id="l6" name="line6">LaoYuanPython第3行</h3>]
>>> soup.select("[name^='line'] ~ [class='t2']") [<h2 class="t2" id="l2" name="line2">老猿Python第2行</h2>, <h2 class="t2" id="l5" name="line5">LaoYuanPython第2行</h2>]
>>>

7. 一次查找多个标签

要查找的标签间用逗号分隔,如:

>>> soup.select("h3.t3,h1#l4")

[<h3 class="t3" id="l3" name="line3">老猿Python第3行</h3>, <h1 class="t1" id="l4" name="line4">LaoYuanPython第1行</h1>, <h3 class="t3" id="l6" name="line6">LaoYuanPython第3行</h3>]
>>>

四、 select查找的总结

上面罗列了很多html元素通过css选择器来查找的场景,老猿总结select的使用方法如下:

1、 select可以通过只传递一个”css选择器”参数来调用;

2、 ”css选择器”参数可以支持嵌套多个子选择器组合,每个子选择器的构成方式包括:

1)单个标签;

2)单个属性;

3)单个属性值;

4)单个css类;

5)单个id;

6)以上内容的组合,组合时多个组合项之间不能有空格,如:

>>> soup.select("h1#l1[name$='1'].t1")#标签+id+属性尾字符匹配+CSS类的组合查找
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>]
>>> soup.select("h1#l1[name$='1'] .t1") #css类前有空格,会认为是两个子选择器,且相互之间是祖先节点与孙节点的关系
[]
>>>

且这些子选择器每相邻的两个子选择器之间可以支持不同的关系组合,包括:

1)父子关系组合:不同的选择器之间用大于号(>)分隔,后一个选择器查找html元素时只能到前一个选择器定位的标签内的直接子节点内查找。如:

>>> soup.select("body>div>h1[class='t1']")
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>]
>>>

2)子孙关系组合:不同的选择器之间用空格分隔,后一个选择器查找html元素时只能到前一个选择器定位的首个标签的子孙节点内查找。如:

>>> soup.select("body div>h1[class='t1']")
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h1 class="t1" id="l4" name="line4">LaoYuanPython第1行</h1>]
>>>

3)兄弟关系组合:不同的选择器之间用波浪线(~)分隔,后一个选择器查找html元素时只能到前一个选择器定位的首个标签的后面的兄弟节点内查找。如:

>>> soup.select("div>h1~#l3") #查找div节点的直接子节点h1的后面的id为l3兄弟节点
[<h3 class="t3" id="l3" name="line3">老猿Python第3行</h3>]
>>> soup.select("div h1~[class='t3']") #查找div节点的子孙节点h1后面的class属性值为t3的兄弟节点
[<h3 class="t3" id="l3" name="line3">老猿Python第3行</h3>, <h3 class="t3" id="l6" name="line6">LaoYuanPython第3行</h3>]
>>>

4)并列关系组合:不同的选择器之间用逗号(,)分隔,查找时两个选择器之间是或的关系,即只要满足任意一个选择器的条件都认为符合查找要求。

>>> soup.select("div>h1#l1,div>div>h3.t3")
[<h1 class="t1" id="l1" name="line1">老猿Python第1行</h1>, <h3 class="t3" id="l6" name="line6">LaoYuanPython第3行</h3>]
>>>

五、 select_one

除了使用select找出所有满足条件的html元素外,select还有一个姊妹方法select_one,使用方法与select是一样的,只是返回值不同,select_one返回第一个满足条件的html元素,而不是一个列表。

本节详细介绍了使用BeautifulSoup的select方法解析html报文的各种场景,并在介绍各种场景的基础上老猿将select支持的css选择器模式进行了归类总结,包括单个子选择器的组成方式以及多个子选择器两两之间的关系进行了分类。通过这些知识总结,就算对css选择器不熟悉的人也能熟练掌握BeautifulSoup的select解析方法。

老猿Python,跟老猿学Python!

博客地址:https://blog.csdn.net/LaoYuanPython


老猿Python博客文章目录:https://blog.csdn.net/LaoYuanPython/article/details/98245036

请大家多多支持,点赞、评论和加关注!谢谢!

第14.12节 Python中使用BeautifulSoup解析http报文:使用select方法快速定位内容的更多相关文章

  1. 第14.11节 Python中使用BeautifulSoup解析http报文:使用查找方法快速定位内容

    一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>介绍了BeautifulSoup对象的主要属性,通过这些属性可以访 ...

  2. 第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问

    一. 引言 在<第14.8节 Python中使用BeautifulSoup加载HTML报文>中介绍使用BeautifulSoup的安装.导入和创建对象的过程,本节介绍导入后利用Beauti ...

  3. 第14.8节 Python中使用BeautifulSoup加载HTML报文

    一. 引言 BeautifulSoup是一个三方模块bs4中提供的进行HTML解析的类,可以认为是一个HTML解析工具箱,对HTML报文中的标签具有比较好的容错识别功能.阅读本节需要了解html相关的 ...

  4. 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解

    第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一.    引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...

  5. 第8.23节 Python中使用sort/sorted排序与“富比较”方法的关系分析

    一. 引言 <第8.21节 Python中__lt__.gt__等 "富比较"("rich comparison")方法用途探究>和<第8.2 ...

  6. 第14.9节 Python中使用urllib.request+BeautifulSoup获取url访问的基本信息

    利用urllib.request读取url文档的内容并使用BeautifulSoup解析后,可以通过一些基本的BeautifulSoup对象输出html文档的基本信息.以博文<第14.6节 使用 ...

  7. 第9.12节 Python中其他文件操作方式

    一. 引言 本章老猿主要介绍了Python 内置io模块的文件操作相关功能,其实除了内置io模块可以进行文件操作外,Python的不同模块还提供了多种文件操作方式,下面简单将这些模块和方法介绍一下. ...

  8. 第9.10节 Python中IO模块其他文件操作属性和方法简介

    本文中所有案例中的fp都是使用open函数打开文件返回的一个文件对象,为了节省篇幅,大部分没有提供文件打开的代码. 一. 文件是否关闭的属性 属性名:closed 功用:判断文件是否关闭 示例: &g ...

  9. 第8.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析

    一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...

随机推荐

  1. pytest框架执行自动化测试时使用pycharm正常运行,使用cmd或Terminal报错:Hint: make sure your test modules/packages have valid Python names.

    问题描述: 使用pytest框架做接口自动化测试时,在测试用例所在的.py文件下使用pycharm的run功能可以正常跑用例,使用cmd运行窗口或Terminal则报下图中的错误: Hint: mak ...

  2. 使用switch计算出某年某月某日是今年的第几天,输出一直是当月天数

    package com.cx.Switch; import java.util.Scanner; /** * 计算出某年某月某日是今年的第几天 * 使用switch */ public class S ...

  3. File 方法

    File类说明 存储在变量,数组和对象中的数据是暂时的,当程序终止时他们就会丢失.为了能够永 久的保存程序中创建的数据,需要将他们存储到硬盘或光盘的文件中.这些文件可以移动,传送,亦可以被其他程序使用 ...

  4. 性能问题eg

    线上问题 ./pidstat -w Linux 3.6.5-Broadcom Linux ((none)) 03/21/20 _armv7l_ (1 CPU) 15:04:17 UID PID csw ...

  5. TCP协议原理与格式初探

    目录 可靠数据传输原理 停等传输下的情况 1.经过完全可靠信道的可靠数据传输 2.经具有比特差错信道的可靠数据传输 3.经具有比特差错的丢包信道的可靠数据传输 流水线传输 1.回退N步(Go-Back ...

  6. ssh配好无密码登录(RSA公钥)后,还要密码登录的问题的解决办法

    首先删除 /root/.ssh目录 然后ssh-keygen 生成新的认证目录 然后检查能否免密码登陆 如果还不能可能是/root/目录的权限不对了 可能被异常改到777了 做操作 chmod 650 ...

  7. Nacos服务发现源码解析

    1.Spring服务发现的统一规范 Spring将这套规范定义在Spring Cloud Common中 discovery包下面定义了服务发现的规范 核心接口:DiscoveryClient 用于服 ...

  8. 01、Spring环境搭建

    环境:SpringSource-Tool-3.9.9.Eclipse4.10.0 首先,我们需要解决的是Spring包的问题,我看了百度.CSDN很多都是直接一上来随便丢个包就可以安装了,搞得我弄了一 ...

  9. JWT(JSON Web Token)入门

    简介 JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案 一.跨域认证的问题 互联网服务离不开用户认证.一般流程是下面这样. 1.用户向服务器发送用户名和密码. 2.服务器验证 ...

  10. 学习笔记:[算法分析]数据结构与算法Python版

    什么是算法分析 对比程序,还是算法? ❖如何对比两个程序? 看起来不同,但解决同一个问题的程序,哪个" 更好"? ❖程序和算法的区别 算法是对问题解决的分步描述 程序则是采用某种编 ...