爬虫 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.mzph.cn/news/815239.shtml

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

相关文章

华大基因获证:氧化三甲胺检测试剂助力心血管疾病早期干预

近日&#xff0c;深圳华大基因股份有限公司旗下的全资子公司华大生物科技&#xff08;武汉&#xff09;有限公司获得两项医疗器械注册证&#xff08;注册号&#xff1a;鄂械注准20232404470和鄂械注准20232404469&#xff09;。该试剂是国内首个获批二类注册的&#xff0c;基于…

2024第十五届蓝桥杯 Java B组 填空题

声明&#xff1a;博主比较菜&#xff0c;以下均为个人想法。解决方法仅供参考。欢迎大家一起讨论交流&#xff01; 第一题&#xff1a; 题目&#xff1a; &#xff08;简洁版&#xff09;从小到大排列是20或24倍数的正整数&#xff0c;前10个数依次是&#xff1a;”20 24 40 …

Linux进阶篇:文件传输工具curl命令详解

文件传输工具Linux curl命令详解 一 curl命令介绍 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具&#xff0c;可以说是一款很强大的http命令行工具。它支持文件的上传和下载&#xff0c;是综合传输工具&#xff0c;但按传统&#xff0c;习惯称url为下载工具。…

package.java文件的作用

你查看springboot的源码&#xff0c;有很多类都有这个文件&#xff0c;在idea不能创建&#xff0c;因为不支持这种命名&#xff0c;只能用记事本创建后复制都项目中。 主要应用是给类添加正常&#xff0c;或者把公用的注解都放到这里&#xff0c;常量不合适&#xff0c;作用范…

竞赛 基于CNN实现谣言检测 - python 深度学习 机器学习

文章目录 1 前言1.1 背景 2 数据集3 实现过程4 CNN网络实现5 模型训练部分6 模型评估7 预测结果8 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于CNN实现谣言检测 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&am…

欧姆龙61F系列液位开关使用教程(补水和排水)

欧姆龙61F系列液位开关使用教程(补水和排水) 本文以61F-LS-CP11-NRA型号的液位开关为例进行说明: 具体的选型文档可参考以下链接中的内容: OMRON欧姆龙-无浮标开关(紧凑插入型)61F-LS液位开关-选型样本说明 补水功能(供水) 如下图所示, 电机电源为3相AC220V; 控制电…

SSRF+Redis未授权getshell

SSRFRedis未授权getshell 1.前言 当一个网站具有ssrf漏洞&#xff0c;如果没有一些过滤措施&#xff0c;比如没过滤file协议&#xff0c;gophere协议&#xff0c;dict等协议&#xff0c;就会导致无法访问的内网服务器信息泄露&#xff0c;甚至可以让攻击者拿下内网服务器权限 …

Git分布式版本控制系统——Git常用命令(二)

五、Git常用命令————分支操作 同一个仓库可以有多个分支&#xff0c;各个分支相互独立&#xff0c;互不干扰 分支的相关命令&#xff0c;具体如下&#xff1a; git branch 查看分支 git branch [name] 创建分支&#x…

5. Mysql的binlog介绍

参考&#xff1a;InnoDB学习&#xff08;三&#xff09;之BinLog 1. BinLog介绍 BinLog又称为二进制日志&#xff0c;是MySQL服务层的数据日志&#xff0c;MySQL所有的存储引擎都支持BinLog。 BinLog记录了MySQL中的数据更新和可能导致数据更新的事件&#xff0c;可以用于主从…

轻量带屏解决方案之恒玄芯片移植案例

本文章基于恒玄科技BES2600W芯片的欧智通 Multi-modal V200Z-R开发板 &#xff0c;进行轻量带屏开发板的标准移植&#xff0c;开发了智能开关面板样例&#xff0c;同时实现了ace_engine_lite、arkui_ui_lite、aafwk_lite、appexecfwk_lite、HDF等部件基于OpenHarmony LiteOS-M内…

【联机不卡顿】幻兽帕鲁教你如何低成本0延迟畅玩 云服务器性价比选择方案 16G低至26/月

更新日期&#xff1a;4月14日&#xff08;腾讯云16G价格回调了&#xff01;京东云采购季持续进行&#xff09; 本文纯原创&#xff0c;侵权必究 《最新对比表》已更新在文章头部—腾讯云文档&#xff0c;文章具有时效性&#xff0c;请以腾讯文档为准&#xff01; 【腾讯文档实…

算法:位运算

算法&#xff1a;位运算 常见位运算操作基本题型模拟加法数字查找总结 常见位运算操作 在C/C中&#xff0c;有比较丰富的位运算操作符&#xff0c;常见的有&#xff1a; &&#xff1a;按位与 |&#xff1a;按位或 ~&#xff1a;按位取反 ^&#xff1a;按位异或 <<&a…

MySQ数据库: MySQL数据库的安装配置 ,图文步骤详细,一篇即可完成安装完成! MySQL数据库如何与客户端连接

LiuJinTao&#xff1a; 2024年4月14日 文章目录 MySQL的安装配置1. 下载2. 安装 三、 MySQL 启动与停止1. 第一种 方式&#xff1a;2. 第二种方式&#xff1a; 四、MySQL 客户端连接2. 方式二&#xff1a; MySQL的安装配置 1. 下载 官方下载网址&#xff1a;https://www.mysq…

代码随想录刷题随记21-回溯1

代码随想录刷题随记21-回溯1 回溯法解决的问题 回溯法&#xff0c;一般可以解决如下几种问题&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合 切割问题&#xff1a;一个字符串按一定规则有几种切割方式 子集问题&#xff1a;一个N个数的集合里有多少符…

可视化大屏C位图:​地理信息—地球焦点图

Hello&#xff0c;我是大千UI工场&#xff0c;本期可视化大屏的焦点图&#xff08;C位&#xff09;分享将地球作为焦点图的情形&#xff0c;欢迎友友们关注、评论&#xff0c;如果有订单可私信。 将地球作为可视化大屏焦点图可以有以下几个作用&#xff1a; 全球数据展示&…

蓝桥杯嵌入式(G431)备赛笔记——DMA+ADC(单通道+多通道)

单通道&#xff1a; 开启循环模式&#xff0c;两个参数设为word u32 adc_tick0; u32 r37_value0; u32 r38_value0; float r37_volt0; float r38_volt0;//DMAADCvoid DMA_ADC() {if(uwTick-adc_tick<100) return;adc_tick uwTick;HAL_ADC_Start_DMA(&hadc2, &r37_v…

Python学习笔记19 - 类与对象

类的创建 对象的创建 类属性、类方法、静态方法 动态绑定属性和方法 面向对象的三大特征 封装&#xff1a;提高程序的安全性 继承&#xff1a;提高代码的复用性 多态&#xff1a;提高程序的可扩展性和可维护性 类的常用的特殊属性 类的常用的特殊方法 –add–() –len–() –…

Java中创建多线程的方法

继承Thread类&#xff0c;对该类进行new一个实例&#xff0c;对实例调用start方法&#xff0c;重写run方法。 缺点&#xff1a;单继承&#xff0c;无法继承 public class myThread extends Thread {public static void main(String[] args) {myThread myThread new myThread()…

Netty学习——实战篇1 BIO、NIO入门demo 备注

1 BIO 实战代码 Slf4j public class BIOServer {public static void main(String[] args) throws IOException {//1 创建线程池ExecutorService threadPool Executors.newCachedThreadPool();//2 创建ServerSocketServerSocket serverSocket new ServerSocket(8000);log.in…

【嵌入式基础知识学习】AD/DA—数模/模数转换

AD/DA—数模/模数转换概念 数字电路只能处理二进制数字信号&#xff0c;而声音、温度、速度和光线等都是模拟量&#xff0c;利用相应的传感器&#xff08;如声音用话筒&#xff09;可以将它们转换成模拟信号&#xff0c;然后由A/D转换器将它们转换成二进制数字信号&#xff0c…