第14.12节 Python中使用BeautifulSoup解析http报文:使用select方法快速定位内容
一、 引言
在《第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问》和《第14.11节 Python中使用BeautifulSoup解析http报文:使用查找方法快速定位内容》介绍了通过属性和查找方法定位HTML报文的内容的方法,除了这两种方法还有一种方法就是通过使用CSS选择器的语法找到tag,关于css选择器老猿在此不进行介绍,大家可以自行查找文档了解,老猿推荐W3School 的《CSS 选择器参考手册》。其实不了解也问题不大,本节的内容绝大部分还是很好理解的。
二、 select方法
语法调用:
select(selector,namespace=None,limit=None,**kwargs)语法释义
1)参数selector为css选择器,关于CSS 选择器,请参考W3School 的《CSS 选择器参考手册》,具体应用方法请见第三部分;
2)namespace:为一个映射css选择器名字空间到名字空间URIs的字典,老猿对css选择器没有研究过,使用时一般用缺省参数
3)limit:限制查找到的内容个数,缺省不限制个数;
4)kwargs:老猿没有查到相关资料,暂时不使用;
5)返回值为一个列表,里面包含所有满足条件的html元素。
关于select的参数,官网上没有列出,只在举例中使用了第一个参数,老猿是通过help查出来的参数。不过也说明其他参数不重要,我们也就不关注了。
三、 使用select的几种场景及方法
- 本部分的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')
>>>
- 查找某个名称的所有标签
要查找某个名称的所有标签,直接在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>]
>>>
- 查找某个符合要求的所有标签
这个功能是“查找某个名称的所有标签”的扩展,也可以说“查找某个名称的所有标签”是本功能的一个特例。
语法为:
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方法快速定位内容的更多相关文章
- 第14.11节 Python中使用BeautifulSoup解析http报文:使用查找方法快速定位内容
一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>介绍了BeautifulSoup对象的主要属性,通过这些属性可以访 ...
- 第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问
一. 引言 在<第14.8节 Python中使用BeautifulSoup加载HTML报文>中介绍使用BeautifulSoup的安装.导入和创建对象的过程,本节介绍导入后利用Beauti ...
- 第14.8节 Python中使用BeautifulSoup加载HTML报文
一. 引言 BeautifulSoup是一个三方模块bs4中提供的进行HTML解析的类,可以认为是一个HTML解析工具箱,对HTML报文中的标签具有比较好的容错识别功能.阅读本节需要了解html相关的 ...
- 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解
第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一. 引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...
- 第8.23节 Python中使用sort/sorted排序与“富比较”方法的关系分析
一. 引言 <第8.21节 Python中__lt__.gt__等 "富比较"("rich comparison")方法用途探究>和<第8.2 ...
- 第14.9节 Python中使用urllib.request+BeautifulSoup获取url访问的基本信息
利用urllib.request读取url文档的内容并使用BeautifulSoup解析后,可以通过一些基本的BeautifulSoup对象输出html文档的基本信息.以博文<第14.6节 使用 ...
- 第9.12节 Python中其他文件操作方式
一. 引言 本章老猿主要介绍了Python 内置io模块的文件操作相关功能,其实除了内置io模块可以进行文件操作外,Python的不同模块还提供了多种文件操作方式,下面简单将这些模块和方法介绍一下. ...
- 第9.10节 Python中IO模块其他文件操作属性和方法简介
本文中所有案例中的fp都是使用open函数打开文件返回的一个文件对象,为了节省篇幅,大部分没有提供文件打开的代码. 一. 文件是否关闭的属性 属性名:closed 功用:判断文件是否关闭 示例: &g ...
- 第8.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析
一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...
随机推荐
- Unity正交相机智能包围物体(组)方案
Unity正交相机智能包围物体(组)方案 目录 Unity正交相机智能包围物体(组)方案 一.技术背景 二.相关概念 2.1 正交摄像机 2.2 正交相机的Size 2.3 相机的Aspect 2.4 ...
- 基于gin的golang web开发:mysql增删改查
Go语言访问mysql数据库需要用到标准库database/sql和mysql的驱动.标准库的Api使用比较繁琐这里再引入另一个库github.com/jmoiron/sqlx. go get git ...
- Numpy_01
# 引子: # ndarray 是一个 numpy库提供的 同构数据多维模型 import numpy as np list=[1,2,3,4,5,6] myndarray=np.array(list ...
- 仿select下拉框
默认状态下,灰色面板出现.当点击页面按钮以及灰色面板外区域时,面板消失;点击按钮,灰色面板出现;点击灰色面板区域,面板不能消失. 主要考察:事件冒泡与取消事件冒泡. 代码: <!DOCTYPE ...
- IDEA与Eclipse创建struts项目
1.IDEA创建struts项目 这里再构建struts项目是选择jar包出问题了,可以重新配置 创建页面和action配置struts.xml 启动tomcat,浏览器中运行 具体参考: https ...
- linux中suid/sgid/sticky及扩展属性(attr)
suid只适用于命令文件.(如/usr/bin/passwd) 当命令文件上有suid权限时,则操作用户的权限变成属主权限.命令文件上无suid权限则操作用户的权限不变. 查看suid权限: [roo ...
- mon的稳定性问题
MON的稳定性问题: mon的选举风暴影响客户端IO LevelDB的暴涨 频繁的客户端请求的DDOS mon选举风暴: monmap会因为mon之间或者mon与客户端之间网络的影响或者消息传递的异常 ...
- 设计模式(一)--工厂模式(Go实现)
package Factory import "fmt" type Restaurant interface { GetFood() } type Donglaishun stru ...
- rootfs如何取消登录超时
一种简便的办法,在etc/inittab文件中,增加一行::respawn:-/bin/login.之后当登录超时后,还会在进入到登录界面,就不会出现登录超时后无法在登录的问题了. #first:ru ...
- 使用Actor模型管理Web Worker多线程
前端固有的编程思维是单线程,比如JavaScript语言的单线程.浏览器JS线程与UI线程互斥等等,Web Woker是HTML5新增的能力,为前端带来多线程能力.这篇文章简单记录一下搜狗地图WebG ...