一文入门BeautifulSoup4-3

239 阅读4分钟

搜索文档树🌲

在BS4中搜索文档树🌲主要是有两种方法:

  • find_all()
  • find()

前者用的比较更为广泛

find_all()

find_all(name, attrs, recursive, text, **kwargs)
name

find_all() 方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件。

过滤器贯穿整个搜索的API。它们可以被使用在tag的name中,节点的属性中,字符串或者它们的混合中,具体见下面的实例

传入字符串

直接传入需要查找的某个标签,会将结果以列表的形式展示出来

image-20200808100830578
image-20200808100830578

!!!!!!需要注意的点:

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

image-20200808103620660
image-20200808103620660

但是如果使用的是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”属性

  1. 查找id='link2',自动查找id属性
image-20200808104518683
image-20200808104518683
  1. 如果传入 href 参数,Beautiful Soup会搜索每个tag的”href”属性
  1. 使用多个参数同时指定
  1. 使用class标签过滤,需要加上下划线(同上面的道理)
attrs

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

image-20200808105813813
image-20200808105813813
text

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

limit

find_all() 方法返回全部的搜索结构,如果文档树很大那么搜索会很慢。如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数。

效果与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果。

recursive

调用tagfind_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方法获取具体内容