Python爬虫——BautifulSoup 常用函数

76 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详情

1、find_all()函数

find_all() 函数(常用):搜索当前标签的所有子节点,并判断这些节点是否符合过滤条件,将所有符合条件的结果以列表形式返回

使用语法:

find_all(name=None, attrs={}, recursive=True, text=None,limit=None, **kwargs)

参数介绍:

  • name:标签名,如a,img,字符串对象会被自动忽略掉。
  • attributes:定义一个字典来搜索包含特殊属性的标签。
  • recursive:是否递归。如果是,就会查找tag的所有子孙标签,默认true。
  • text:标签的文本内容去匹配,而不是标签的属性。
  • limit: 限制搜索的数据个数,其实find() 函数就是limit=1。
  • keyword:选择那些具有指定属性的标签。

待解析的html文本文件:

<!DOCTYPE html>
<html lang="en">
  <head>
   <title>
   </title>
  </head>
  <body>
   <p class="title"/>

   <a href="http://localhost:8080"/>
   <p class="story">
        <a class="s1" href="www.baidu.com" id="l1"></a>
        <a class="s2" href="" id="l2"></a>
        <a class="s3" href="" id="l3"></a>
       <span> span </span>
   </p>
  </body>
</html>

使用实例:

使用 lxml 解析器实例化BeautifulSoup对象:

from bs4 import BeautifulSoup

#使用 lxml 解析器
soup = BeautifulSoup(open('test.html',encoding='utf-8'),'lxml')

查找所有a标签并返回:

print(soup.findAll('a'))

查找所有a标签和span标签并返回:

print(soup.findAll(['a','span']))

查找所有a标签,只返回前3条数据:

print(soup.find_all("a",limit=3))

根据标签属性以及属性值查找内容:

print(soup.find_all("a",class_="s2"))
print(soup.find_all("a",id="l3"))
print(soup.find_all("a",id="id"))

执行结果:

第一个输出:
[<a href="http://localhost:8080"></a>, <a class="s1" href="www.baidu.com" id="l1"></a>, <a class="s2" href="" id="l2"></a>, <a class="s3" href="" id="l3"></a>]

第二个输出:
[<a href="http://localhost:8080"></a>, <a class="s1" href="www.baidu.com" id="l1"></a>, <a class="s2" href="" id="l2"></a>, <a class="s3" href="" id="l3"></a>, <span> span </span>]

第三个输出:
[<a href="http://localhost:8080"></a>, <a class="s1" href="www.baidu.com" id="l1"></a>, <a class="s2" href="" id="l2"></a>]

第四个输出:
[<a class="s2" href="" id="l2"></a>]

第五个输出:
[<a class="s3" href="" id="l3"></a>]

第六个输出:没找到返回空列表[]
[]

2、find()函数

find() 函数:搜索当前标签的所有子节点,返回一个符合过滤条件的结果

使用语法:

find(name=None, attrs={}, recursive=True, text=None,**kwargs)

参数介绍:

  • name:标签名,如a,img,字符串对象会被自动忽略掉。

  • attributes:定义一个字典来搜索包含特殊属性的标签。

  • recursive:是否递归。如果是,就会查找tag的所有子孙标签,默认true。

  • text:标签的文本内容去匹配,而不是标签的属性。

  • keyword:选择那些具有指定属性的标签。

  • 因为find()函数仅返回一个符合过滤条件的结果,所以find() 没有limit参数

待解析的html文本文件:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>
        </title>
    </head>
    <body>
        <p class="title"/>
        <a href="http://localhost:8080"/>
        <p class="story">
            <a class="s1" href="www.baidu.com" id="l1"></a>
            <a class="s2" href="" id="l2"></a>
            <a class="s3" href="" id="l3"></a>
        </p>
        <p class="story"/>
    </body>
</html>  

使用实例:

使用 lxml 解析器实例化BeautifulSoup对象:

import urllib.request
from bs4 import BeautifulSoup
import re

#使用 lxml 解析器
soup = BeautifulSoup(open('test.html',encoding='utf-8'),'lxml')

获取第一个标签并返回结果:

print(soup.find('a'))

根据指定href属性值查找a标签并返回结果,没找到返回None:

print(soup.find('a',href='www.baidu.com'))
print(soup.find('a',href='www.alibaba.com'))

根据属性选择器查找,查找有class属性的a标签:

print(soup.select('a[class]'))

根据指定class属性值查找a标签并返回结果,class为python关键字,使用时要加下划线区分:

print(soup.find('a',class_='s2'))

根据属性值正则匹配:

print(soup.find(class_=re.compile('le')))

attrs参数值匹配:

print(soup.find(attrs={'class':'title'}))
print(soup.find(attrs={'id':'l3'}))

执行结果:

第一个输出:
<a href="http://localhost:8080"></a>

第二个输出:
<a class="s1" href="www.baidu.com" id="l1"></a>

第三个输出:找不到目标时None
None

第四个输出:
<a class="s2" href="" id="l2"></a>

第五个输出:
<p class="title"></p>

第六个输出:
<p class="title"></p>

第七个输出:
<a class="s3" href="" id="l3"></a>

find() 函数和 find_all() 函数的区别

  • find_all() 函数的返回结果类型是列表类型,find() 函数返回的结果是找到的第一个节点

  • find_all() 函数没有找到目标时返回空列表 [],find() 函数没有找不到目标时返回的是 None

  • 使用attributes参加检索时,有些标签属性在检索时不能使用,如 HTML5 中的 data-* 属性,像下面这样就会报错:

    soup.find_all(data-foo='value')
    

    但是可以通过 find_all() 函数的 attributes参数定义一个字典参数来检索包含特殊属性的标签,如下:

    soup.find_all(attrs={"data-foo": "value"})
    

3、select()函数

BeautifulSoup 支持大部分的 CSS 选择器,比如常见的标签选择器、类选择器、id 选择器,以及层级选择器。向BeautifulSoup 的select() 函数中传入CSS 选择器作为参数,就可以在 HTML 文档中检索到与之对应的内容,返回类型为列表类型。

待解析的html文本文件:

<!DOCTYPE html>
<html lang="en">
<head>
<title>test</title>
</head>
<body>
<p class="title"/>

<a href="http://localhost:8080"/>
<div>
    <p class="story">
        <a class="s1" href="www.baidu.com" id="l1"></a>
        <a class="s2" href="" id="l2"></a>
        <a class="s3" href="" id="l3"></a>
        <span> span </span>
    </p>
</div>
</body>
</html>

使用实例:

使用 lxml 解析器实例化BeautifulSoup对象:

from bs4 import BeautifulSoup

#使用 lxml 解析器
soup = BeautifulSoup(open('test.html',encoding='utf-8'),'lxml')

根据元素标签查找:

print(soup.select('a'))

根据多个元素标签查找:

print(soup.select('a,span'))

根据属性选择器查找,查找有class属性的a标签:

print(soup.select('a[class]'))

查找class属性值为s3的a标签:

print(soup.select('a[class="s3"]'))

根据class选择器查找:

print(soup.select('.s1'))

通过id选择器查找:

print(soup.select('#l1'))

后代选择器查找,查找html下面的head下面的title标签:

print(soup.select('html head title'))

子代选择器(一级子标签),查找div下面的p下面的span标签,在bs4中可以不加空格:

print(soup.select('div > p > span'))

执行结果:

第一个输出:
[<a href="http://localhost:8080"></a>, <a class="s1" href="www.baidu.com" id="l1"></a>, <a class="s2" href="" id="l2"></a>, <a class="s3" href="" id="l3"></a>]

第二个输出:
[<a href="http://localhost:8080"></a>, <a class="s1" href="www.baidu.com" id="l1"></a>, <a class="s2" href="" id="l2"></a>, <a class="s3" href="" id="l3"></a>, <span> span </span>]

第三个输出:
[<a class="s1" href="www.baidu.com" id="l1"></a>, <a class="s2" href="" id="l2"></a>, <a class="s3" href="" id="l3"></a>]

第四个输出:
[<a class="s3" href="" id="l3"></a>]

第五个输出:
[<a class="s1" href="www.baidu.com" id="l1"></a>]

第六个输出:
[<title>test</title>]

第七个输出:
[<a href="http://localhost:8080"></a>]

第八个输出:
[<span> span </span>]