2020/04/01 03-Bs4遍历文档树和搜索过滤器

在这里插入图片描述
在这里插入图片描述
soup.div深度优先找第一个div
在这里插入图片描述
soup.div深度优先找第一个div,在它下面找深度优先第一个p标签在这里插入图片描述
深度优先
在这里插入图片描述
它是要把你的整个结构解析了才开始找的,不是按照读取的顺序来的,是有顺序的

遍历直接节点需要一些东西
在这里插入图片描述
现在玩的是标签element,标签就是元素
在这里插入图片描述
这里有一个contents
在这里插入图片描述
attrs用字典包了下,说明是字典
在这里插入图片描述
告诉你是个标签,来源页面中的类,来自于页面中的元素的类

在这里插入图片描述
数逗号就是三个元素

在这里插入图片描述
应该是5个元素
在这里插入图片描述
找div下面的子把这个包含进来了
在这里插入图片描述
所以现在就被几个换行符断开了,所以这里面元素比我们想象的要多
在这里插入图片描述
打印孩子节点看看有没有什么区别
在这里插入图片描述
看看写成一个对象,是在bs4的element下
在这里插入图片描述
把div叫tag,下面写起来就方便了,写成对象的方式
在这里插入图片描述

看看这两个有什么区别
在这里插入图片描述
看一下contents

在这里插入图片描述
拿contents包了一下

在这里插入图片描述
contents应告诉我们是个列表,children,iter一包立马告诉我们是个生成器了
在这里插入图片描述
所以我们要用的时候就需要进行迭代,外面套个list,套了list就完全一样了

在这里插入图片描述
这里是一个子节点的迭代器,看到children下次访问的时候,里面是对contents的包装
在这里插入图片描述
遍历所有子孙节点,descendants后代,往下走,去看他的子子孙孙,告诉我们又是一个迭代器

在这里插入图片描述
看到yield了,又是遍历contents
在这里插入图片描述
contents去找,下面的一个个元素找,找完之后

在这里插入图片描述
找完之后把当前元素改改,我们再递归的时候也这么做,每次都把当前节点迭代出来
在这里插入图片描述
把子子孙孙全部打印出来
在这里插入图片描述
所以子孙,h3打印完,把h3内部的也打印了,递归将里面的文本类型的标签还有type类型的标签,以及字标签,和文本内容全部作为子孙打印

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
soup.div.string,这种方式是取里面的内容的,如果div有很多子孙节点,该如何提取内容

现在这样取是none

在这里插入图片描述
现在拿不到div里的汉字

在这里插入图片描述
试试div下的h3里的string,还是没拿到
在这里插入图片描述
h3里有个a就拿到了

在这里插入图片描述
h3的a里就一个python所以就取到了

在这里插入图片描述
这是取到一个标签的文本,但是要求这个里面只剩文本,有其他任何东西都不显示,里面只能是文本

在这里插入图片描述
看一下源码

在这里插入图片描述
tag下的string
在这里插入图片描述
这是一个便利的属性去拿到一个在标签内单独的string,也就是这个标签要求是单独的string

在这里插入图片描述
如果这里面的内容不是1,直接return none,如果不是文本型的也就没什么可看的

在这里插入图片描述
这里是唯一的文本标签就可以拿到内容

在这里插入图片描述
有很多子孙节点就提供了strings在这里插入图片描述
查看源码
在这里插入图片描述
strings是个属性,这就是调用一个get方法,property第一个是get方法
在这里插入图片描述
访问这个属性就访问上面的all_strings了

在这里插入图片描述
遍历子子孙孙,最后把子子孙孙一个个yield出来了,把一个个子子孙孙内容往外抛出,这相当于递归所有元素的内部当中去,然后把里面的内容提取出来
在这里插入图片描述
还提供了另一个方法stripped_strings,剥离掉什么东西

在这里插入图片描述
我们当时在写property属性装饰器的时候,发现自己要定义一个函数,反复使用,而且里面的参数可以变化,有的时候就写成这样来定义一个属性
在这里插入图片描述
调用这个方法把true传进去,相当于告诉你必须把某些内容剥离,tripped掉

在这里插入图片描述

string是把无用的空白字符去掉,这样得到又是个迭代器,是 yield出来的

在这里插入图片描述
第一个是将所有的文本都提取出来,包括换行符。
第二个是将所有的空白字符stripped掉,空字符串之后就不输出了

在这里插入图片描述
这样就连成一体了,这些都是从contents基础上迭代下来的

在这里插入图片描述
在这里插入图片描述
如果想要h3的所有文本
在这里插入图片描述
最后把迭代器一连接就可以了

在这里插入图片描述
孩子叫children,祖先就是parent,提供了parent和parents
在这里插入图片描述
在这里插入图片描述
第一个p标签的parent
在这里插入图片描述
看一下parents

在这里插入图片描述
parents又是yield了
在这里插入图片描述
把自己的parent变成i,下回迭代后,又找到它的parent,变成i,parents是离自己最近的父打印,是个由近及远的过程
在这里插入图片描述
这样去迭代就可以打印了,最后一层到了html
在这里插入图片描述
如果想打印他们标签的名字,list包一下,把里面的每一个元素拿出来把name拿一下,拿标签名称,它的父一定是个标签,文本不作数

在这里插入图片描述
这里可以看的清除是谁
在这里插入图片描述
在这里插入图片描述
遍历兄弟节点

在这里插入图片描述
这个是容易出问题的地方
在这里插入图片描述
在这里插入图片描述
第一个p 标签下一个兄弟
在这里插入图片描述
两次
在这里插入图片描述
其实i中间加了一些东西,打印name看看,一个文本标签\N,就是换行符,没有标签名就是none
在这里插入图片描述
再下一个就是p标签了

在这里插入图片描述
它的父标签是div,div下的div要知道它的children有哪些,contents立即给一个列表,看的清楚点
在这里插入图片描述
p标签的下一个兄弟是它

在这里插入图片描述

再下一个才是p标签
在这里插入图片描述

在这里插入图片描述
意思是兄弟们,还是个迭代器,想要看还得套一个list

在这里插入图片描述
它向后的兄弟们,指的是这个意思

在这里插入图片描述
容易混淆的,下一个元素 next_element
在这里插入图片描述

在这里插入图片描述
再打印一次看看
在这里插入图片描述
再打印一个看看
在这里插入图片描述
刚才是按子的意思来next_sibling,这就有点像按所有子孙后代来的

在这里插入图片描述
在这里插入图片描述
换一h3看的清楚点
在这里插入图片描述
如果是h3的话,下一个,应该是a标签,下一个的下一个应该是python,再下一个就是高级班,再下一个就没了
在这里插入图片描述
相当于子子孙孙的标签都走一遍

在这里插入图片描述
如果有换行符,第一个就要走换行符,没有就是a标签,a标签内又是深度优先,下一步就要指的是a标签内部的元素,a标签后就是高级班。
所以是深度优先在里面去搜索的

在这里插入图片描述
这个就是看子子孙孙,把所有的遍历出来

在这里插入图片描述
更多场景下使用的是next_sibling,看的是下一个子,更多是这个,但是问题在于经常带上换行符
在这里插入图片描述
一个是子子孙孙都出来,一个是出来子

在这里插入图片描述
遍历文档数,就是往下遍历所有子孙,父,兄弟节点

在这里插入图片描述
在python还是用下划线,看到小驼峰比较变扭

在这里插入图片描述
看一下find_all源码

在这里插入图片描述
name里直接写标签名即可
在这里插入图片描述
这就是三个p标签全部返回了,find_all是理解返回
在这里插入图片描述
返回的是列表,.点相当于对列表进行操作

在这里插入图片描述
深度优先,跟soup.p一个道理
在这里插入图片描述
找一个就等于一个元素,就可以找下一个

在这里插入图片描述
找下面的一批
在这里插入图片描述
如果是find_all,这是个列表就不能像之前那样操作,只能for循环一个个拿出来操作
在这里插入图片描述
现在返回了三个

在这里插入图片描述
这里可以放5个参数,1名称(就是标签),2。

在这里插入图片描述
把name称为过滤器,赛到这里就是想要定位出,过滤出想要的标签,可以写字符串,还可以写正则表达式对象
在这里插入图片描述
下一个正则表达式,re.compile,以h开头数字结尾看看,这样就可以把找到的对象用列表返回
在这里插入图片描述
这是find_all

在这里插入图片描述
find_all里面去调用了下划线find_all

在这里插入图片描述
这些属性整在一起做判断,不同的方式做不同的处理
在这里插入图片描述
主要它是解决了不同的问题,解决不同参数配合之后如何去替你去搜索你要的标签了。
里面还可以写列表

在这里插入图片描述
正好是按照你的要求来的

在这里插入图片描述
现在这么写,列表是个容器里面写元素,这里就是写了一堆的,前面只是写单个标签搜索方法
在这里插入图片描述
这样也是可以的,这一块p标签就打印出来了
在这里插入图片描述
这里可以把你想要的对象都放进来

在这里插入图片描述
还可以这么写,看不到\n
在这里插入图片描述
也就是到目前为止打印出来的都是所有的tag对象,去源码看看
在这里插入图片描述
很多地方做了判断,如果是它才可以,迭代要求元素是tag才可以,现在text,limit,attrs,kwargs都没有传进来
在这里插入图片描述
随意这里返回一个tag实例是很正常的

在这里插入图片描述
如果是true和none都进这个
在这里插入图片描述
在这里插入图片描述
写成false也一样在这里插入图片描述
默认值是none,不要写false,在后面一些操作回阻止它
在这里插入图片描述
过滤器除了name还有一种,如果要返回的标签必须是多值的,要求必须class必须多值
在这里插入图片描述
如果要找class多值的,现有基础上是要把所有标签都拿一遍,拿完之后遍历,遍历之后每个都是元素对象,元素对象class就可以拿到,用attrs就可以拿到,attrs拿到之后就需要判断class是不是一个列表,长度是不是大于1 的。(要求是要多个值的)

需要写一个函数
在这里插入图片描述
缺一个参数
在这里插入图片描述
这个参数叫tag
在这里插入图片描述
打印name
在这里插入图片描述
这个类型在上面引入过了
在这里插入图片描述
现在已经拿到tag对象,get class,相当于attr.get(class),拿它的属性,len包一下,最后应该返回true和false。
字典的get方法不抛出异常,没有就拿到none,none取长度len(不会这么写)

在这里插入图片描述
所以现在get拿不到给个缺省值,给个空,有就取出来看谁打

在这里插入图片描述
这样就拿到了

在这里插入图片描述其他就返回false即可,就是所谓的增强功能
在这里插入图片描述
过滤器里面,5种类型,标签本身,正则表达式,列表(里面可以写正则表达式可以写标签),复杂的时候会提供一个函数,这个函数经过测试需要有一个参数,这个参数类型实际上可以变的,由于find_all并没有提供其他参数,目前迭代都是tag类型,如果写严格就要判断 类型,然后再进一步的判断,字典的操作和逻辑表达式的比较,谁通过谁不通过就用true和false进行判断
在这里插入图片描述
这里就对所有标签都开绿灯

在这里插入图片描述
many_class相当于有选择性的开绿灯
在这里插入图片描述
现在用beatifulsoup提供的方法在遍历的时候,也是比较方便的,用这种也是比较容易搜索的,最后获得的都是元素对象,对元素(tag)对象进行操作

这就是过滤器如何去使用

在这里插入图片描述

发布了243 篇原创文章 · 获赞 6 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_42227818/article/details/105248447