爬虫 BeautifulSoup模块

爬虫 BeautifulSoup模块

【一】介绍

【1】说明

  • BeautifulSoup库是python的一个第三方库,主要用于处理HTML和XML文档
  • 他提供了一些简单的、python式的函数来解析、导航、搜索以及修改分析树,使得从网页抓取的数据变得简单高效
  • BeautifulSoup自动将输入文档的转换为Unicode编码,输出文档转换为UTF8编码,用户无需担心编码问题
  • BeautifulSoup将复杂HTML文档转换成一个复杂的树形结构,并将每个节点表示为Python对象

【2】安装引入

  • 安装:注意是4
pip install BeautifulSoup4
  • 导入
from bs4 import BeautifulSoup

【3】解析器

解析器使用方法特点
自带html.parserBeautifulSoup(页面源码,‘html.parser’)简单易用:标准库的一部分,无需安装
速度适中:性能不是最快的,但对于大所数常见任务足以
功能基础:提供了基本的HTML解析功能,对复杂的HTML或错误会吃力
第三方lxmlBeautifulSoup(页面源码,‘lxml’)性能优越:所有python HTML/XML解析器中性能最好的
功能丰富:支持Xpath和CSS选择器
需要自行导入安装
第三方html5libBeautifulSoup(页面源码,‘html5lib’)兼容性好:能够处理不符合规范的HTML代码
纯Python实现:无需任何外部依赖,可在任何支持Python的环境中使用
速度相对较慢:兼容性和纯Python导致
它符合HTML5规范

【4】四种主要对象

  • BeautifulSoup 对象

    • 当使用Beautiful Soup解析一个HTML或XML文档时,会得到一个BeautifulSoup对象。
    • 这个对象基本上是一个包含了整个解析后的文档内容的容器。
    • 可以通过BeautifulSoup对象来访问和搜索文档中的其他对象,如TagNavigableStringComment
  • Tag 对象

    • Tag 对象对应于HTML或XML文档中的标签。
    • 例如,在<p>This is a paragraph.</p>中,<p></p>是标签,它们会被解析为Tag对象。
    • 每个Tag对象都有名称和属性,可以通过.name.attrs来访问。
    • 此外,Tag对象还可以包含其他Tag对象、NavigableString对象或Comment对象,这些可以通过.contents.children等属性来访问。
    • tag的属性可以被添加、删除或修改
      • tag的属性操作方法与字典一样
  • NavigableString 对象

    • NavigableString 对象代表标签之间的文本内容。
    • 在上面的例子中,“This is a paragraph.”就是一个NavigableString对象。
    • 与普通的Python字符串不同,NavigableString对象可以与文档中的其他部分(如Tag对象)进行交互和搜索。
  • Comment 对象

    • Comment 对象代表HTML或XML文档中的注释。
    • 在HTML中,注释以<!--开始,以-->结束。
    • 这些注释在解析时会被转换为Comment对象。
    • TagNavigableString对象类似,Comment对象也是文档树的一部分,可以通过Beautiful Soup进行搜索和访问。

【二】文档树操作

【1】基础方法

  • soup.tag.name

    • 获取标签的名称
  • soup.tag.attrs

    • 获取标签的所有属性,返回一个字典
    • 没有属性就是None
  • soup.tag[attribute]

    • 获取标签的指定属性
    • 属性有多个值的返回一个列表
  • soup.tag.string

    • 获取标签中的单个字符串的内容
    • 如果标签内含有多个子节点(包括其他标签或字符串),则结果为None
  • soup.tag.strings

    • 返回一个生成器
    • 可以遍历标签及所有其子节点的字符串内容
  • soup.tag.text

    • 获取标签及其所有子节点的文本内容
  • soup.tag.stripped_strings

    • 返回一个生成器
    • 可以遍历标签及其所有子节点的非空白字符串(空格换行都可以去掉)内容
  • soup.tag.tag.tag

    • 可以嵌套选择
    • 类似于链式操作
from bs4 import BeautifulSouphtml = """
<p class='btn btn-primary' id='b1'>
&nbsp;&nbsp;前面几个空格<b>后面有空格&nbsp;</b>
&nbsp;前面有空格</p>
"""
soup = BeautifulSoup(html, 'lxml')# 获取标签的名称
print(soup.p.name)
# 获取标签所有属性
print(soup.p.attrs)
# 获取指定属性
print(soup.p['class'])
# 获取标签下单个字符串内容
print(soup.p.string)  # 因为含有子标签,为None
print(soup.b.string)
# 获取标签和子节点的所有文本内容
print(soup.p.text)
# 获取标签下的所有文本内容,生成器
print(soup.p.strings)
for string in soup.p.strings:print(string)
# 去除空行和空格
print(soup.p.stripped_strings)
for string in soup.p.stripped_strings:print(string)

【2】遍历文档树

  • 按照某种顺序(如深度优先或广度优先)访问文档树中的每个节点

  • soup.tag.contents

    • 当前标签的直接 子节点列表(包括子标签和字符串内容)
  • soup.tag.children

    • 当前标签的直接 子节点生成器
  • soup.tag.descendants

    • 当前标签的所有 子节点生成器
    • 深度优先遍历会识别换行和空格
  • soup.tag.parent

    • 当前节点的父节点
  • soup.tag.parents

    • 当前节点的所有祖先节点生成器
  • soup.tag.next_sibling

    • 当前节点的上一个兄弟节点**(会识别到换行和空格)**
  • soup.tag.previous_sibling

    • 当前节点的上一个兄弟节点**(会识别到换行和空格)**
  • soup.tag.next_siblings

    • 当前节点之后的所有兄弟节点迭代器
  • soup.tag.previous_siblings

    • 当前节点之前的所有兄弟节点迭代器
from bs4 import BeautifulSouphtml = """
<html lang="en">
<body><b>...</b><p class="story">Once upon a time there were three little sisters; and their names were  
<a href="http://example.com/elsie" class="sister" id="link">Elsie</a>,   
and they lived at the bottom of a well.</p><p>...</p>  
</body>
</html>
"""
soup = BeautifulSoup(html, 'lxml')# 直接子节点列表
print(soup.p.contents)
print(soup.p.children) # <list_iterator object at 0x0000016CFBEE9750>
# 父节点列表
print(soup.p.parent)
print(soup.p.parents)
# 兄弟节点
print(soup.p.next_sibling)
print(soup.p.previous_sibling)
# 所有兄弟节点
print(soup.p.next_siblings)
print(soup.p.previous_siblings)

【3】搜索文档树

  • 根据某些条件(如标签、属性、文本内容等)在文档树中查找节点

(1)查找多个find_all

  • 语法
find_all(name, attrs, recursive, limit, string, **kwargs)
  • name:

    • 字符串

      • 传入标签名,返回所有对应的标签
      • 例如:name='a' 拿到所有的a标签
    • 正则表达式

      • 根据正则表达式匹配标签
      • 例如:name=re.compile("^b") 拿到所有的b开头的标签
    • 列表

      • 匹配列表中的元素,满足一个的就可以
      • 例如:name=[‘a’, ‘p’] 拿到所有的a标签和p标签
    • 方法

      • 自定义方法匹配元素

      • 例如:匹配含有class属性且没有ID属性的标签

      • def has_class_but_no_id(tag):return tag.has_attr('class') and not tag.has_attr('id')soup.find_all(name=has_class_but_not_id)
        
    • True

      • 返回所有的标签
      • 不会返回的当前标签的字符串内容
      • 默认就是True
  • attrs和**kwargs

    • 根据属性进行查找,多个属性之间是与的关系

      • 也可以使用正则
      • class属性的特殊,一空格分割多个且需要写成class_
      • 自定义属性可以使用attrs,也可以直接写
      • arrts属性直接是与的关系
    • 例如:

    • # 查找含有href属性,值是指定网址的标签
      soup.find_all(href="http://example.com/")
      soup.find_all(attrs={'href': "http://example.com/"})
      
    • # 也可以使用正则
      soup.find_all(href=re.compile("http://"))
      
    • # class属性的特殊,一空格分割多个且需要写成class_
      # id属性就不能空格分隔多个
      from bs4 import BeautifulSoup
      html = """
      <p class="c1 c2" id='id 1' >...</p>
      """
      soup = BeautifulSoup(html, 'lxml')
      print(soup.find_all(class_='c1', id='id 1'))
      
    • # 自定义属性可以使用attrs,也可以直接写
      from bs4 import BeautifulSoup
      html = """
      <p special='ss' >...</p>
      """
      soup = BeautifulSoup(html, 'lxml')
      print(soup.find_all(special='ss'))
      print(soup.find_all(attrs={'special': 'ss'}))
      
    • # arrts属性直接是与的关系
      from bs4 import BeautifulSoup
      html = """
      <p ss='ss' aa='aa' >...</p>
      """
      soup = BeautifulSoup(html, 'lxml')
      print(soup.find_all(attrs={'ss': 'ss', 'aa': 'aa'}))
      print(soup.find_all(attrs={'ss': 'ss', 'aa': 'a'}))
      
  • recursive

    • 用于控制是否递归往下查询
    • 默认为True,会遍历当前tag的所有子孙节点
    • 想要直接子节点,可设置recursive =Fasle
  • limit

    • 限制返回的结果数量
    • 达到一定数量直接停止,消耗资源较少
    • 和Sql的limit一样
  • string

    • 根据内容搜索标签
    • 可以是字符串、列表、正则表达式等
    • 和name属性一样

(2)查找单个find

  • 和find_all()的参数一样
  • 区别在于
    • 数量
      • find返回第一个满足条件的
      • find_all返回所有满足条件
      • find_all(limit=1)等价于find()
    • 格式:如果为空
      • find返回None
      • find_all返回空列表

(3)拓展

  • find_parents() 和 find_parent()

    • find_parents():返回所有符合条件的父级tag,结果是一个生成器。
    • find_parent():返回第一个符合条件的父级tag。
  • find_next_siblings() 和 find_next_sibling()

    • find_next_siblings():返回所有符合条件的后续兄弟tag,结果是一个列表。
    • find_next_sibling():返回第一个符合条件的后续兄弟tag。
  • find_all_next() 和 find_next()

    • find_all_next():返回所有符合条件的后续tag和文本内容,结果是一个生成器。
    • find_next():返回第一个符合条件的后续tag或文本内容。

【三】CSS选择器

  • 官网:CSS 选择器参考手册 (w3school.com.cn)

  • 使用方法:基本都是页面复制selector

    • soup.select_one():返回查找的第一个
    • soup.select()[0].attrs:获取属性
    • soup.select()[0].get_text()
      在这里插入图片描述
  • CSS 选择器

    选择器例子例子描述
    .class.intro选择 class=“intro” 的所有元素。
    .class1.class2.name1.name2选择 class 属性中同时有 name1 和 name2 的所有元素。
    .class1 .class2.name1 .name2选择作为类名 name1 元素后代的所有类名 name2 元素。
    #id#firstname选择 id=“firstname” 的元素。
    **选择所有元素。
    elementp选择所有

    元素。

    element.classp.intro选择 class=“intro” 的所有

    元素。

    element,elementdiv, p选择所有
    元素和所有

    元素。

    element elementdiv p选择
    元素内的所有

    元素。

    element>elementdiv > p选择父元素是
    的所有

    元素。

    element+elementdiv + p选择紧跟
    元素的首个

    元素。

    element1~element2p ~ ul选择前面有

    元素的每个

    • 元素。

    [attribute][target]选择带有 target 属性的所有元素。
    [attribute=value][target=_blank]选择带有 target=“_blank” 属性的所有元素。
    [attribute~=value][title~=flower]选择 title 属性包含单词 “flower” 的所有元素。
    [attribute|=value][lang|=en]选择 lang 属性值以 “en” 开头的所有元素。
    [attribute^=value]a[href^=“https”]选择其 src 属性值以 “https” 开头的每个 元素。
    [attribute$=value]a[href$=“.pdf”]选择其 src 属性以 “.pdf” 结尾的所有 元素。
    [attribute*=value]a[href*=“w3school”]选择其 href 属性值中包含 “abc” 子串的每个 元素。
    :activea:active选择活动链接。
    ::afterp::after在每个

    的内容之后插入内容。

    ::beforep::before在每个

    的内容之前插入内容。

    :checkedinput:checked选择每个被选中的 元素。
    :defaultinput:default选择默认的 元素。
    :disabledinput:disabled选择每个被禁用的 元素。
    :emptyp:empty选择没有子元素的每个

    元素(包括文本节点)。

    :enabledinput:enabled选择每个启用的 元素。
    :first-childp:first-child选择属于父元素的第一个子元素的每个

    元素。

    ::first-letterp::first-letter选择每个

    元素的首字母。

    ::first-linep::first-line选择每个

    元素的首行。

    :first-of-typep:first-of-type选择属于其父元素的首个

    元素的每个

    元素。

    :focusinput:focus选择获得焦点的 input 元素。
    :fullscreen:fullscreen选择处于全屏模式的元素。
    :hovera:hover选择鼠标指针位于其上的链接。
    :in-rangeinput:in-range选择其值在指定范围内的 input 元素。
    :indeterminateinput:indeterminate选择处于不确定状态的 input 元素。
    :invalidinput:invalid选择具有无效值的所有 input 元素。
    :lang(language)p:lang(it)选择 lang 属性等于 “it”(意大利)的每个

    元素。

    :last-childp:last-child选择属于其父元素最后一个子元素每个

    元素。

    :last-of-typep:last-of-type选择属于其父元素的最后

    元素的每个

    元素。

    :linka:link选择所有未访问过的链接。
    :not(selector):not§选择非

    元素的每个元素。

    :nth-child(n)p:nth-child(2)选择属于其父元素的第二个子元素的每个

    元素。

    :nth-last-child(n)p:nth-last-child(2)同上,从最后一个子元素开始计数。
    :nth-of-type(n)p:nth-of-type(2)选择属于其父元素第二个

    元素的每个

    元素。

    :nth-last-of-type(n)p:nth-last-of-type(2)同上,但是从最后一个子元素开始计数。
    :only-of-typep:only-of-type选择属于其父元素唯一的

    元素的每个

    元素。

    :only-childp:only-child选择属于其父元素的唯一子元素的每个

    元素。

    :optionalinput:optional选择不带 “required” 属性的 input 元素。
    :out-of-rangeinput:out-of-range选择值超出指定范围的 input 元素。
    ::placeholderinput::placeholder选择已规定 “placeholder” 属性的 input 元素。
    :read-onlyinput:read-only选择已规定 “readonly” 属性的 input 元素。
    :read-writeinput:read-write选择未规定 “readonly” 属性的 input 元素。
    :requiredinput:required选择已规定 “required” 属性的 input 元素。
    :root:root选择文档的根元素。
    ::selection::selection选择用户已选取的元素部分。
    :target#news:target选择当前活动的 #news 元素。
    :validinput:valid选择带有有效值的所有 input 元素。
    :visiteda:visited选择所有已访问的链接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/302400.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ctfshow web入门 命令执行 web53--web77

web53 日常查看文件 怎么回事不让我看十八 弄了半天发现并不是很对劲&#xff0c;原来我发现他会先回显我输入的命令再进行命令的回显 ?cnl${IFS}flag.php||web54 绕过了很多东西 基本上没有什么命令可以用了但是 grep和?通配符还可以用 ?cgrep${IFS}ctfshow${IFS}???…

BFS宽度优先搜索例题(蓝桥杯)——逃跑的牛

问题描述&#xff1a; 农夫John的一头牛逃跑了&#xff0c;他想要将逃跑的牛找回来。现假设农夫John和牛的位置都在一条直线上&#xff0c;农夫John的初始位置为N&#xff08;0≤N≤100,000&#xff09;&#xff0c;牛的初始位置为K&#xff08;0≤K≤100,000&#xff09;。农夫…

R语言数据操纵:常用函数

目录 处理循环的函数 lapply函数 apply函数 mapply函数 tapply函数 split函数 排序的函数 sort函数与order函数 总结数据信息的函数 head函数与tail函数 summary函数 str函数 table函数 any函数 all函数 xtab函数 object.size函数 这篇文章主要介绍R语言中处理…

APP测试面试题详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、基础篇 1、请介绍一下&#xff0c;APP测试流程&#xff1f…

【算法统治世界】动态规划 个人笔记总结

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《数据结构与算法&#xff1a;初学者入门指南》&#x1f4d8;&am…

分布式主键ID生成策略

业务系统对分布式ID的要求 唯一性&#xff1a;在分布式系统中&#xff0c;每个节点都需要生成唯一的标识符来确保数据的唯一性。传统的单点生成ID方式无法满足分布式环境下的需求&#xff0c;而分布式ID能够在整个系统中保证每个节点生成的ID都是唯一的。 顺序性&#xff1a;某…

CSS设置网页颜色

目录 前言&#xff1a; 1.颜色名字&#xff1a; 2.十六进制码&#xff1a; 3.RGB&#xff1a; 4.RGBA&#xff1a; 5.HSL&#xff1a; 1.hue&#xff1a; 2.saturation&#xff1a; 3.lightness&#xff1a; 6.HSLA&#xff1a; 前言&#xff1a; 我们在电脑显示器&…

Linux 多线程

目录 初识线程 线程的概念 Linux下的线程 线程优缺点 线程控制 线程创建 线程终止 线程等待 线程分离 线程取消 其它 线程互斥 互斥的概念 互斥锁的使用 锁的本质 线程同步 线程同步的概念 条件变量的概念 条件变量的使用 信号量 信号量的概念 信号量接口…

007 CSS的继承和层叠 元素特性

文章目录 CSS属性的继承CSS属性的层叠选择器的权重 HTML元素的类型编写HTML注意事项元素隐藏方法CSS属性-overflowCSS样式不生效可能原因 CSS属性的继承 如果一个属性具备继承性&#xff0c;那么在该元素上设置后&#xff0c;它的后代元素都可以继承这个属性 如果后代元素自己…

如何将平板或手机作为电脑的外接显示器?

先上官网链接&#xff1a;ExtensoDesk 家里有一台华为平板&#xff0c;自从买回来以后除了看视频外&#xff0c;基本没什么作用&#xff0c;于是想着将其作为我电脑的第二个屏幕&#xff0c;提高我学习办公的效率&#xff0c;废物再次利用。最近了解到华为和小米生态有多屏协同…

android11 SystemUI入門之KeyguardPatternView解析

view层级树为&#xff1a; 被包含在 keyguard_host_view.xml中 。 <?xml version"1.0" encoding"utf-8"?> <!-- This is the host view that generally contains two sub views: the widget viewand the security view. --> <com.andro…

关于Emulator和Simulator的探讨

由于写论文需要&#xff0c;仔细的学习和比对一下Emulator和Simulator的概念。原来“Emulator专门指硬件模拟&#xff0c;Simulator专门指软件模拟”的观点是不正确的&#xff0c;于是查看了很多文章的解释。同时也提醒自己&#xff0c;做科研一定要认真细致&#xff0c;无论看…

CLR学习

视频链接&#xff1a;《CLR十分钟》系列之CLR运行模型_哔哩哔哩_bilibili 什么是 CLR 公共语言运行时&#xff08;Common Language Runtime CLR&#xff09; 是一个可有多种编程语言使用的 运行时&#xff0c;CLR 的核心功能&#xff08;比如 内存管理&#xff0c;程序集加载…

Node.JS多线程PromisePool之promise-pool库实现

什么是Promise Pool Map-like, concurrent promise processing for Node.js. Promise-Pool是一个用于管理并发请求的JavaScript库&#xff0c;它可以限制同时进行的请求数量&#xff0c;以避免过多的请求导致服务器压力过大。使用Promise-Pool可以方便地实现对多个异步操作的并…

HarmonyOS 开发-使用SideBarContainer侧边栏淡入淡出动效实现案例

介绍 在2in1或平板上&#xff0c;群聊侧边栏是一种较为常用的功能&#xff0c;虽然HarmonyOS已经具备了基本的动效&#xff0c;但是部分情况下开发者可能有定制侧边栏动效的需求&#xff0c;本例主要介绍了如何基于显式动画实现侧边栏的淡入淡出动效。 效果图预览 使用说明&a…

C#中值类型与引用类型的存储

目录 值对象与引用对象的存储 引用对象的成员存储 值对象与引用对象的存储 数据项的类型定义了存储数据需要的内存大小及组成该类型的数据成员。类型还决定了对象在内存中的存储位置——栈或堆。 C#中类型分为两种&#xff1a;值类型和引用类型&#xff0c;这两种类型的对象…

天机学堂踩坑笔记

相关资源链接&#xff1a; Md笔记&#xff1a;蓝奏云地址 在线笔记&#xff1a;飞书笔记地址 相关视频教程及配套课件&#xff1a; 链接&#xff1a;百度云地址 提取码&#xff1a;hmz1 1. Day01 初识项目 1.1 OpenEuler 22.03LTS yum换源失败 适用于OpenEuler版本为22.03LT…

1.Hexo安装和环境搭建引导

Hexo是一个依赖于一个名为nodejs的程序 因此安装它的方式在Mac和Windows上实际上是一样的 为了在电脑上安装Hexo 需要做两件事 nodejs&#xff0c;基本上是hexo依赖运行的JavaScript框架 Node.js — Run JavaScript Everywheregit&#xff0c;是一个程序&#xff0c;用来管理电…

BurpSuite保姆级教程

Burp Suite下载,破解,代理web,代理模拟器 (一)为Burp Sutie下载运行执行脚本环境(Java) 1.Java官网下载地址&#xff1a;https://www.oracle.com/java/technologies/ 下载Java SE 17.0.8(LTS) 备注&#xff1a;1.2023版Burp Suite 完美的运行脚本的环境是Java17 2.Java8不支持…

数据仓库实践

什么是数据仓库&#xff1f; 数据仓库是一个用于存储大量数据并支持数据分析与报告的系统。它通常用于集成来自不同来源的数据&#xff0c;提供一个统一的视图&#xff0c;以便进行更深入的分析和决策。 数据仓库的主要优势&#xff1f; 决策支持&#xff1a;为企业决策提供可靠…