搜索文档树🌲
在BS4中搜索文档树🌲主要是有两种方法:
- find_all()
- find()
前者用的比较更为广泛
find_all()
find_all(name, attrs, recursive, text, **kwargs)
name
find_all() 方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件。
过滤器贯穿整个搜索的API。它们可以被使用在tag的name中,节点的属性中,字符串或者它们的混合中,具体见下面的实例
传入字符串
直接传入需要查找的某个标签,会将结果以列表的形式展示出来

!!!!!!需要注意的点:
由于HTML中class标签和Python中的class关键字相同,为了不产生冲突,如果遇到要查询class标签的情况,使用class_来代替,这点和XPATH中的写法类似,举个列子:

但是如果使用的是attrs参数,则不用加下划线:

传入正则表达式
如果传入的正则表达式作为参数,BS会通过表达式的match()来匹配内容。
比如我们现在想找所有以b开头的标签,这个时候结果应该是<body>和<b>都被找到,使用的是re模块中的compile()方法


传入列表
如果想同时查找某几个标签,可以通过列表的形式

传入True
True 可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点

传入方法
如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数。
如果这个方法返回 True ,表示当前元素匹配并且被找到,如果不是则反回 False
下面的方法校验了当前元素中包含class属性却不包含id属性,那么返回True
def has_class_no_id(tag):
return tag.has_attr('class') and not tag.has_attr('id')
将上面的方法传入到find_all方法中,将得到全部的<p>标签,因为它满足上面的要求

keyword
注意:如果一个指定名字的参数不是搜索内置的参数名,搜索时会把该参数当作指定名字tag的属性来搜索,如果包含一个名字为
id的参数,Beautiful Soup会搜索每个tag的”id”属性
- 查找id='link2',自动查找id属性

- 如果传入
href参数,Beautiful Soup会搜索每个tag的”href”属性

- 使用多个参数同时指定

- 使用class标签过滤,需要加上下划线(同上面的道理)

attrs
该参数用来定义一个字典来搜索包含特殊属性的tag,当然也能搜索普通的属性

text
通过text参数来搜索文档中的字符串内容。与name参数的可选值相同:字符串、正则表达式、列表、True

limit
find_all() 方法返回全部的搜索结构,如果文档树很大那么搜索会很慢。如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数。
效果与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果。

recursive
调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False,则BS4不会搜索子标签

find()
find(name,attrs,text,recursive,**kwargs)
它与 find_all() 方法唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果。

CSS选择器
在写CSS的时候,类名前加上点,id名前加上#。
使用soup.select()的方法类筛选元素,返回的类型是list
标签名查找

类名查找

id名查找

组合查找
组合查找即和写 class 文件时,标签名与类名、id名进行的组合原理是一样的,例如查找 p 标签中,id 等于 link1的内容,二者需要用空格分开
- 标签
- 属性

直接查找子标签

属性查找
查找时还可以加入属性元素,属性需要用中括号括起来,注意属性和标签属于同一节点,所以中间不能加空格,否则会无法匹配到。

同样,属性仍然可以与上述查找方式组合,不在同一节点的空格隔开,同一节点的不加空格

注意点:select 方法返回的都是列表形式的内容,可以遍历获取,通过get_text方法获取具体内容
