资讯专栏INFORMATION COLUMN

Python爬虫笔记4-BeautifulSoup使用

fobnn / 1324人阅读

摘要:方法作用查找所有符合条件的元素,返回的是列表形式参数可以根据节点名来查找元素。示例查询第一个标签查找第一个节点内容中有字符串的节点内容运行结果关于的使用就这样吧,常用个人就觉得用好即可参考链接崔庆才网络爬虫开发实战使用

BeautifulSoup介绍

lxml一样,BeautifulSoup也是一个HTML/XML的解析器,主要功能也是如何解析和提取HTML/XML数据。

几种解析工具的对比

工具 速度 难度
正则表达式 最快 困难
BeautifulSoup 最简单
lxml 简单
lxml 只会局部遍历,而Beautiful Soup 是基于HTML DOM的,会载入整个文档,解析整个DOM树,因此时间和内存开销都会大很多,所以性能要低于lxml。

安装
我的环境是Python 3.6.5,windows下cmd里执行pip安装即可。

pip3 install beautifulsoup4

测试
python终端里导入beautifulsoup,无报错信息即安装成功。

>>from bs4 import BeautifulSoup
>>
BeautifulSoup对象

BeautifulSoup将复杂的HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

Tag

NavigableString

BeautifulSoup

Comment

BeautifulSoup 对象表示的是一个文档的内容。大部分时候,可以把它当作 Tag 对象,是一个特殊的 Tag。
Comment 对象是一个特殊类型的 NavigableString 对象,其输出的内容不包括注释符号。

Tag

Tag可以简单理解为HTML文档中的一个个的标签,比如:

The Dormouse"s story
  • first item
  • 上面HTML文档中的head、title、ur、li都是HTML标签(节点名称),这些标签加上里面的内容就是tag。

    获取Tags

    # 导入模块
    from bs4 import BeautifulSoup
    
    html = """
    The Dormouse"s story
    
    

    The Dormouse"s story

    Once upon a time there were three little sisters; and their names were , Lacie and Tillie; and they lived at the bottom of a well.

    ...

    """ # 初始化BeautifulSoup对象,指定lxml解析器 soup = BeautifulSoup(html, "lxml") # prettify()方法格式化soup的内容 print(soup.prettify()) # soup.title选出title节点 print(soup.title) # The Dormouse"s story print(type(soup.title)) # print(soup.head) # The Dormouse"s story print(soup.p) #

    The Dormouse"s story

    说明:使用soup加节点名称可以获取节点内容,这些对象的类型是bs4.element.Tag,但是它查找的是在内容中第一个符合要求的节点。比如上面代码有多个p标签,但是它只查找了第一个p标签。

    对于Tag有两个重要的属性,nameattrs。当选择一个节点后,name属性获取节点的名称,attrs属性获取节点的属性(以字典形式返回)。

    print(soup.name)
    # [document] #soup 对象本身比较特殊,它的 name 即为 [document]
    print(soup.head.name)
    # head #对于其他内部标签,输出的值便为标签本身的名称
        
    print(soup.p.attrs)
    # {"class": ["title"], "name": "dromouse"}
    # 在这里,我们把 p 标签的所有属性打印输出了出来,得到的类型是一个字典。
    
    # 下面三种方法都可以获取字典里的值,是等价的,结果都一样
    print(soup.p.get("class"))
    # ["title"]
    print(soup.p["class"])
    # ["title"]
    print(soup.p.attrs["class"])
    # ["title"]
    
    # 还可以针对属性或者内容进行修改
    soup.p["class"] = "newClass"
    print (soup.p)
    # 

    The Dormouse"s story

    NavigableString

    获取了Tag,也就是获取了节点内容,但是只想要获取节点内部的内容怎么办?只需使用.string即可。

    # 获取节点内容
    print(soup.p.string)
    # The Dormouse"s story
    
    print(type(soup.p.string))
    # 
    遍历文档树

    在选取节点的时候,也可以先选取一个节点,然后以这个节点为基准选取它的子节点,父节点,子孙节点等等,下面就介绍常用的选取方法。

    获取直接子节点.contents .children属性

    .contents

    tag的.contents属性可以将tag的直接子节点以列表的方式输出。
    下面例子选取head节点为基准,.contents选取head的子节点title,然后以列表返回。

    print(soup.head.contents)
    # [The Dormouse"s story]

    输出方式为列表,可以用列表索引来获取它的某一个元素.

    print(soup.head.contents[0])
    # The Dormouse"s story
    

    .children

    children属性和contents属性不同的是它返回的不是一个列表,而是一个生成器。可用for循环输出结果。

    print(soup.head.children)
    # 
    
    for i in soup.head.children:
        print(i)
    # The Dormouse"s story    
    
    获取所有子孙节点:.descendants属性

    上面两个属性都只能获取到基准节点的下一个节点,要想获取节点的所有子孙节点,就可以使用descendants属性了。它返回的也是一个生成器。

    print(soup.descendants)
    # 
    

    还有其他属性如查找父节点,组父节点的属性就不记录了(平时很少用)。

    搜索文档树

    BeautifulSoup提供了一些查询方法(find_all,find等),调用对应方法,输入查询参数就可以得到我们想要的内容了,可以理解为搜索引擎的功能。(百度/谷歌=查询方法,查询内容=查询参数,返回的网页=想要的内容)
    下面介绍最常用的find_all方法。

    find_all方法

    作用:查找所有符合条件的元素,返回的是列表形式
    API:find_all(name, attrs, recursive, text, **kwargs)
    1. name
    name 参数可以根据节点名来查找元素。
    A. 传字符串
    最简单的过滤器是字符串.在搜索方法中传入一个字符串参数,BeautifulSoup会查找与字符串完整匹配的内容,下面的例子用于查找文档中所有的

    标签

    print(soup.find_all("p"))
    # 通常以下面方式写比较好
    print(soup.find_all(name="p"))
    

    B.传正则表达式
    如果传入正则表达式作为参数,Beautiful Soup会通过正则表达式的 match() 来匹配内容.下面例子中找出所有以p开头的标签。

    import re
    print(soup.find_all(re.compile("^p")))
    

    C.传列表
    如果传入列表参数,BeautifulSoup会将与列表中任一元素匹配的内容返回。下面代码会找到HTML代码中的head标签和b标签。

    print(soup.find_all(["head","b"]))
    # [The Dormouse"s story, The Dormouse"s story]
    

    2. attrs
    find_all中attrs参数可以根据节点属性查询。
    查询时传入的参数是字典类型。比如查询id=link1的节点

    print(soup.find_all(attrs={"id":"link1"}))
    # []

    对于常见的属性,可以不用以attrs来传递,直接传入查询参数即可。比如id,class_(class为Python关键字,使用下划线区分),如下:

    print(soup.find_all(id="link1"))
    print(soup.find_all(class_="sister"))

    运行结果:

    []
    
    [, Lacie, Tillie]
    

    3. text
    text 参数可以搜搜文档中的字符串内容,与 name 参数的可选值一样, text 参数接受 字符串 , 正则表达式 , 列表。下面代码查找节点里内容中有story字符串的节点,并返回节点的内容。

    print(soup.find_all(text=re.compile("story")))
    # ["The Dormouse"s story", "The Dormouse"s story"]
    
    
    find方法

    find方法与find_all方法的区别:
    find_all:查询符合所有条件的元素,返回列表。
    find:只查找第一个匹配到的元素,返回单个元素,类型tag。
    查询方法与find_all大同小异。示例:

    print(soup.find(name="p")) # 查询第一个p标签
    print(soup.find(text=re.compile("story"))) # 查找第一个节点内容中有story字符串的节点内容

    运行结果:

    The Dormouse"s story

    The Dormouse"s story
    关于BeautifulSoup的使用就这样吧,常用个人就觉得用好find_all即可(=.=~)
    参考链接

    崔庆才 [Python3网络爬虫开发实战]:4.2-使用Beautiful Soup

    文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/43388.html

    相关文章

    • 首次公开,整理12年积累的博客收藏夹,零距离展示《收藏夹吃灰》系列博客

      摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...

      Harriet666 评论0 收藏0
    • SegmentFault 技术周刊 Vol.30 - 学习 Python 来做一些神奇好玩的事情吧

      摘要:学习笔记七数学形态学关注的是图像中的形状,它提供了一些方法用于检测形状和改变形状。学习笔记十一尺度不变特征变换,简称是图像局部特征提取的现代方法基于区域图像块的分析。本文的目的是简明扼要地说明的编码机制,并给出一些建议。 showImg(https://segmentfault.com/img/bVRJbz?w=900&h=385); 前言 开始之前,我们先来看这样一个提问: pyth...

      lifesimple 评论0 收藏0
    • Python爬虫笔记1-爬虫背景了解

      摘要:学习爬虫的背景了解。但是搜索引擎蜘蛛的爬行是被输入了一定的规则的,它需要遵从一些命令或文件的内容,如标注为的链接,或者是协议。不同领域不同背景的用户往往具有不同的检索目的和需求,搜索引擎无法提供针对具体某个用户的搜索结果。 学习python爬虫的背景了解。 大数据时代数据获取方式 如今,人类社会已经进入了大数据时代,数据已经成为必不可少的部分,可见数据的获取非常重要,而数据的获取的方式...

      oujie 评论0 收藏0
    • 学习笔记 | HTML 基本结构和基本标签 ——前端学习第一步!

      摘要:基本结构语言中,一个页面是由四个部分组成文档声明标签对标签对标签对图示文档声明这是一个文档声明,表示这是一个页面。标签标签表示页面内容的范围。 HTML HTML ...

      sPeng 评论0 收藏0

    发表评论

    0条评论

    fobnn

    |高级讲师

    TA的文章

    阅读更多
    最新活动
    阅读需要支付1元查看
    <