一、 引言

在《第14.8节 Python中使用BeautifulSoup加载HTML报文》中介绍使用BeautifulSoup的安装、导入和创建对象的过程,本节介绍导入后利用BeautifulSoup对象访问相关标签数据。

本节案例中介绍处理的c:\temp\s1.html文件内容如下:

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <style type="text/css"> .textline{color:blue;}</style>
  5. <link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>
  6. <title>BeautifulSoups使用方法 - 老猿Python - CSDN博客 </title></head>
  7. <body>
  8. <h1>老猿Python</h1>
  9. <div><p class="textline" name="line1"> 老猿Python首行</p></div>
  10. <div>
  11. <h2>老猿Python第二行<a href="https://blog.csdn.net/LaoYuanPython" /> </h2>
  12. <h3><b>老猿Python第三行</b><a href="https://blog.csdn.net/LaoYuanPython" /> </h3>
  13. </div>
  14. </body></html>

创建soup对象的代码如下:

  1. >>> from bs4 import BeautifulSoup
  2. >>> def getsoup():
  3. fp = open(r'c:\temp\s1.html',encoding='utf-8')
  4. soup = BeautifulSoup(fp, 'lxml')
  5. fp.close()
  6. print(soup)
  7. return soup
  8. >>> soup=getsoup()

二、 访问标签及其属性数据

通过BeautifulSoup对象可以访问标签对应的html元素、并进一步访问标签的名字、属性、html元素标签对中的内容。

  1. 通过Tag标签获取HTML元素内容

    Tag就是 HTML 中的一个个标签,用 BeautifulSoup 可以很方便地获取 T标签,通过标签名可以获取HTML报文中对应标签的第一个记录。注意标签识别时对大小写敏感(标签应该都是小写)。

    如上面读取文件解析报文构建soap对象后,访问相关的标签的结果:
  1. >>> soup.title
  2. <title>BeautifulSoups使用方法 - 老猿Python - CSDN博客 </title>
  3. >>> soup.p
  4. <p class="textline" name="line1"> 老猿Python首行</p>
  5. >>> soup.link
  6. <link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>
  1. 通过标签获取标签属性

    通过BeautifulSoup对象的标签名的attrs属性可以访问标签的所有属性,返回的属性为一个字典,如果通过标签名加属性名的方法可以访问属性的值。如:
  1. >>> soup.link.attrs
  2. {'href': 'https://blog.csdn.net/LaoYuanPython/article/details/95360624', 'rel': ['canonical']}
  3. >>> soup.link['rel']
  4. ['canonical']
  5. >>> soup.link.name
  6. 'link'
  7. >>>

除了读取相关数据外,还可以通过赋值进行内存数据的修改,如:

  1. >>> soup.title = '老猿Python'

注意:

 上述通过“BeautifulSoup对象.标签”去访问的数据都是html报文中第一个匹配的标签的内容;

 可以通过“BeautifulSoup对象.标签.attrs”访问标签的所有属性数据,如soup.link.attrs,通过“soup.标签[“属性名”]”访问具体属性的值,如soup.link[‘rel’]。

  1. 无嵌套情况下通过标签获取标签内的文字内容

    当通过标签获取到标签内容后,可以通过标签内容的string属性获取标签内的文字。由于string属性返回内容的类型为bs4.element.NavigableString,所以称获取的文本为NavigableString,如:
  1. >>> soup.title.string
  2. 'BeautifulSoups使用方法 - 老猿Python - CSDN博客 '
  3. >>> soup.link
  4. <link href="https://blog.csdn.net/LaoYuanPython/article/details/95360624" rel="canonical"/>
  5. >>> soup.link.string
  6. >>> soup.h1.string
  7. '老猿Python'
  8. >>>

上面soup.link.string没有数据,是因为link只有标签数据而标签外无内容。我们来看看数据类型:

  1. >>> type( soup.title.string)
  2. <class 'bs4.element.NavigableString'>
  3. >>> soup.title.string[0:10]
  4. 'BeautifulS'
  5. >>>
  1. 标签嵌套情况下通过父标签获取标签内的文字内容,这又分为三种情况:

    1)如果标签里面只有唯一的一个标签无其他内容,那么string会返回最里面嵌套标签对应的内容。如:
  1. >>> soup.div
  2. <div><p class="textline" name="line1"> 老猿Python首行</p></div>
  3. >>> soup.div.string
  4. ' 老猿Python首行'
  5. >>> soup.div.p.string
  6. ' 老猿Python首行'
  7. >>>

2)如果tag包含了1个子节点且本身标签内还有文本内容,无法确认该返回哪个文本内容,因此模块给string 的值为 None。如:

  1. >>> soup.h2
  2. <h2>老猿Python第二行<a href="https://blog.csdn.net/LaoYuanPython"></a> </h2>
  3. >>> soup.h2.string
  4. >>> soup.h2.a
  5. <a href="https://blog.csdn.net/LaoYuanPython"></a>
  6. >>>

3)如果tag包含了多个子节点,string 的输出结果也是 None。

  1. >>> soup.h3
  2. <h3><b>老猿Python第三行</b><a href="https://blog.csdn.net/LaoYuanPython"></a> </h3>
  3. >>> soup.h3.string
  4. >>> soup.h3.b
  5. <b>老猿Python第三行</b>
  6. >>> soup.h3.b.string
  7. '老猿Python第三行'
  8. >>>

三、 嵌套标签节点访问

  1. 通过标签的contents属性,可以访问其下嵌套的所有下级HTML元素,这些该标签下的子标签对应的HTML元素放到一个content 指向的列表中。如:
  1. >>> print(soup.body.contents)
  2. ['\n', <h1>老猿Python</h1>, '\n', <div><p class="textline" name="line1"> 老猿Python首行</p></div>, '\n', <div>
  3. <h2>老猿Python第二行<a href="https://blog.csdn.net/LaoYuanPython"></a> </h2>
  4. <h3><b>老猿Python第三行</b><a href="https://blog.csdn.net/LaoYuanPython"></a> </h3>
  5. </div>, '\n']
  6. >>>

注意换行符和空行都会作为一个列表元素返回。

2. 通过标签的children属性也可以访问标签下嵌套的所有HTML元素,只是其类型不是列表,而是一个迭代器。如:

  1. >>> for i in soup.body.children:print(i,end=', ')
  2. , <h1>老猿Python</h1>,
  3. , <div><p class="textline" name="line1"> 老猿Python首行</p></div>,
  4. , <div>
  5. <h2>老猿Python第二行<a href="https://blog.csdn.net/LaoYuanPython"></a> </h2>
  6. <h3><b>老猿Python第三行</b><a href="https://blog.csdn.net/LaoYuanPython"></a> </h3>
  7. </div>,
  8. ,
  9. >>>
  10. >>> type(soup.body.children)
  11. <class 'list_iterator'>
  12. >>>

从上述输出可以看到children与contents还是有换行符和空行。

  1. 访问嵌套标签的所有子孙节点

    escendants 属性可以对标签其下所有层次的节点进行访问,而 children只能访问直接子节点,注意descendants返回的是一个生成器。
  1. >>> type(soup.body.descendants)
  2. <class 'generator'>
  3. >>> for i in soup.body.descendants:print(i,end=', ')
  4. , <h1>老猿Python</h1>, 老猿Python,
  5. , <div><p class="textline" name="line1"> 老猿Python首行</p></div>, <p class="textline" name="line1"> 老猿Python首行</p>, 老猿Python首行,
  6. , <div>
  7. <h2>老猿Python第二行<a href="https://blog.csdn.net/LaoYuanPython"></a> </h2>
  8. <h3><b>老猿Python第三行</b><a href="https://blog.csdn.net/LaoYuanPython"></a> </h3>
  9. </div>,
  10. , <h2>老猿Python第二行<a href="https://blog.csdn.net/LaoYuanPython"></a> </h2>, 老猿Python第二行, <a href="https://blog.csdn.net/LaoYuanPython"></a>, ,
  11. , <h3><b>老猿Python第三行</b><a href="https://blog.csdn.net/LaoYuanPython"></a> </h3>, <b>老猿Python第三行</b>, 老猿Python第三行, <a href="https://blog.csdn.net/LaoYuanPython"></a>, ,
  12. ,
  13. ,
  14. >>>
  1. 访问标签的父节点

    可以通过标签的parent属性访问其直接父节点,如:
  1. >>> soup.b.parent
  2. <h3><b>老猿Python第三行</b><a href="https://blog.csdn.net/LaoYuanPython"></a> </h3>
  3. >>>
  1. 访问标签的所有祖先节点

    通过标签的parents属性可以访问其所有父节点及祖先节点,该值为一个生成器,如:
  1. >>> type(soup.b.parents)
  2. <class 'generator'>
  3. >>> for i in soup.b.parents:print(i.name,i.string)
  4. h3 None
  5. div None
  6. body None
  7. html None
  8. [document] None
  9. >>>
  1. 访问标签的同父节点下的同级兄弟节点

    next_sibling 属性为节点的下一个兄弟节点,previous_sibling 属性为节点的上一个兄弟节点,如果节点不存在,则返回 None,由于空白或者换行也可以被视作一个节点,所以得到的结果可能是空白或者换行。
  1. >>> soup.b.next_sibling
  2. <a href="https://blog.csdn.net/LaoYuanPython"></a>
  3. >>> soup.b.pre_sibling
  4. >>>
  1. 访问标签的同父节点下的所有同级兄弟节点

    通过next_siblings 和 previous_siblings 属性可以对当前节点的所有兄弟节点迭代访问,如:
  1. >>> for i in soup.h2.next_siblings:print(i)
  2. <h3><b>老猿Python第三行</b><a href="https://blog.csdn.net/LaoYuanPython"></a> </h3>
  3. >>> for i in soup.h3.previous_siblings:print(i)
  4. <h2>老猿Python第二行<a href="https://blog.csdn.net/LaoYuanPython"></a> </h2>
  5. >>>
  1. 访问标签的前后节点

    通过next_element和previous_element可以访问标签的前后元素,这里的前后是指html文档中当前标签的前一个元素和后一个元素,不论标签层级,只是字符串的位置前后。并且不一定是标签,只要是独立含义的部分。如:
  1. >>> soup.b.next_element
  2. '老猿Python第三行'
  3. >>> soup.b.previous_element
  4. <h3><b>老猿Python第三行</b><a href="https://blog.csdn.net/LaoYuanPython"></a> </h3>
  5. >>>
  1. 访问标签的所有前后节点

    通过 next_elements 和 previous_elements 的生成器就可以访问当前标签所有前面和后面的html文档解析元素。如:
  1. >>> for n in soup.a.next_elements:
  2. if n!=None and n.name!=None:print(n.name)
  3. h3
  4. b
  5. a
  6. >>> for n in soup.head.previous_elements:print(n.name)
  7. None
  8. html
  9. None
  10. >>>

注意部分元素可能是空行或换行符。

  1. 访问标签的所有内容

    使用标签的contents属性可以访问该标签下的所有元素,如:
  1. >>> soup.div.contents
  2. ['\n', <h1 class="t1" id="l1" name="line1">老猿Python1行</h1>, '\n', <h2 class="t2" id="l2" name="line2">老猿Python第2行</h2>, '\n', <h3 class="t3" id="l3" name="line3">老猿Python3行</h3>, '\n', <div>
  3. <h1 class="t1" id="l4" name="line4">LaoYuanPython1行</h1>
  4. <h2 class="t2" id="l5" name="line5">LaoYuanPython2行</h2>
  5. <h3 class="t3" id="l6" name="line6">LaoYuanPython3行</h3>
  6. </div>, '\n']
  7. >>> soup.h1.contents
  8. ['老猿Python第1行']
  9. >>>

四、 访问对象的所有内容

  1. 通过对象的strings属性迭代访问除标签外的所有内容,包括空行、空白行,如:
  1. >>> for i in soup.head.strings:print(i)
  2. .textline{color:blue;}
  3. BeautifulSoups使用方法 - 老猿Python - CSDN博客
  4. >>>
  1. 通过对象的stripped_strings属性迭代访问所有内容,去除空行、空白行,如:
  1. >>> for i in soup.head.stripped_strings:print(i)
  2. .textline{color:blue;}
  3. BeautifulSoups使用方法 - 老猿Python - CSDN博客
  4. >>>

本节介绍了BeautifulSoup对象的主要属性,通过这些属性可以访问特定标签和内容。

老猿Python,跟老猿学Python!

博客地址:https://blog.csdn.net/LaoYuanPython


老猿Python博客文章目录:https://blog.csdn.net/LaoYuanPython/article/details/98245036

请大家多多支持,点赞、评论和加关注!谢谢!

第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问的更多相关文章

  1. 第14.12节 Python中使用BeautifulSoup解析http报文:使用select方法快速定位内容

    一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>和<第14.11节 Python中使用BeautifulSo ...

  2. 第14.11节 Python中使用BeautifulSoup解析http报文:使用查找方法快速定位内容

    一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>介绍了BeautifulSoup对象的主要属性,通过这些属性可以访 ...

  3. 第14.8节 Python中使用BeautifulSoup加载HTML报文

    一. 引言 BeautifulSoup是一个三方模块bs4中提供的进行HTML解析的类,可以认为是一个HTML解析工具箱,对HTML报文中的标签具有比较好的容错识别功能.阅读本节需要了解html相关的 ...

  4. 第14.9节 Python中使用urllib.request+BeautifulSoup获取url访问的基本信息

    利用urllib.request读取url文档的内容并使用BeautifulSoup解析后,可以通过一些基本的BeautifulSoup对象输出html文档的基本信息.以博文<第14.6节 使用 ...

  5. 第9.10节 Python中IO模块其他文件操作属性和方法简介

    本文中所有案例中的fp都是使用open函数打开文件返回的一个文件对象,为了节省篇幅,大部分没有提供文件打开的代码. 一. 文件是否关闭的属性 属性名:closed 功用:判断文件是否关闭 示例: &g ...

  6. 第7.22节 Python中使用super调用父类的方法

    第7.22节 Python中使用super调用父类的方法 前面章节很多地方都引入了super方法,这个方法就是访问超类这个类对象的.由于super方法的特殊性,本节单独谈一谈super方法. 一.su ...

  7. 第8.20节 Python中限制动态定义实例属性的白名单:__slots__

    一. 引言 按照<第7.10节 Python类中的实例变量定义与使用>.<第7.14节Python类中的实例方法解析>中的介绍,当定义了一个类,并且创建了该类的实例后,可以给该 ...

  8. 第8.23节 Python中使用sort/sorted排序与“富比较”方法的关系分析

    一. 引言 <第8.21节 Python中__lt__.gt__等 "富比较"("rich comparison")方法用途探究>和<第8.2 ...

  9. 第8.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析

    一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...

随机推荐

  1. 主题包含一张index.html

    有半年之久没有更新新作品了,但这个小小领地我并没有忘记,我会坚持下去,一直在这等你,等你的每次回眸,感恩你的每次驻足,这已经足够成为我坚守的动力和理由,尽管现在有很多不足和不尽人意,也没很多的时间管理 ...

  2. 关于“Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.”

    Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the c ...

  3. 面试都要问的Spring MVC

    MVC总结 1. 概述 还是之前的三个套路 1.1 是什么? Spring提供一套视图层的处理框架,他基于Servlet实现,可以通过XML或者注解进行我们需要的配置. 他提供了拦截器,文件上传,CO ...

  4. IP 层收发报文简要剖析6--ip报文输出3 ip_push_pending_frames

    L4层的协议会把数据通过ip_append_data或ip_append_page把数据线放在缓冲区,然后再显示调用ip_push_pending_frames传送数据. 把数据放在缓冲区有两个优点, ...

  5. Markdown语法+Typora快捷键

    1. Markdown语法 1.1 代码块生成 // 对于代码块,使用"```+编程语言"即可生成书写对应代码块的区域 // JS代码块 ​```javascript // Jav ...

  6. 02 Filter过滤器

    Filter 一.Filter过滤器 Filter过滤器它是JavaWeb的三大组件之一.三大组件分别是:Servlet程序.Listener监听器.Filter过滤器 Filter过滤器是JavaE ...

  7. 测试_QTP使用

    1.Qtp是什么? QTP是Quick Test Professional的简称,是一种自动测试工具.使用QTP的目的是想用它来执行重复的自动化测试,主要是用于回归测试和测试同一软件的新版本.(百度百 ...

  8. HDU100题简要题解(2050~2059)

    HDU2050 折线分割平面 题目链接 Problem Description 我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目.比如,一条折线可以 ...

  9. Spark SQL | 目前Spark社区最活跃的组件之一

    Spark SQL是一个用来处理结构化数据的Spark组件,前身是shark,但是shark过多的依赖于hive如采用hive的语法解析器.查询优化器等,制约了Spark各个组件之间的相互集成,因此S ...

  10. .Net orm 开源项目 FreeSql 2.0.0(满意的答卷)

    写在开头 2018年11月头脑发热到今天,一晃已经两年,当初从舒服区走向一个巨大的坑,回头一看后背一凉. 两年时间从无到有,经历数不清的日夜奋斗(有人问花了多长时间投入,答案:全职x2 + 两年无休息 ...