zoukankan      html  css  js  c++  java
  • BeautifulSoup的高级应用 之.parent .parents .next_sibling.previous_sibling.next_siblings.previous_siblings

    继上一篇BeautifulSoup的高级应用,主要解说的是contents children descendants string strings stripped_strings。本篇主要解说.parent .parents .next_sibling .previous_sibling .next_siblings .previous_siblings

    本篇博客继续使用上篇的html页面内容:

    html_doc = """ 
    <html>
    <head><title>The Dormouse's story</title></head> 
    <p class="title"><b>The Dormouse's story</b></p> 
    <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="link1">Elsie</a>, 
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> 
    <p class="story">...</p> 
    </html>"""

    继续分析文档树 ,每一个 tag或字符串都有父节点 :被包括在某个 tag中
    .parent:
    通过 .parent 属性来获取某个元素的父节点.在样例html文档中,标签是标签的父节点:

    title_tag = soup.title 
    title_tag
    # <title>The Dormouse's story</title> 
    title_tag.parent 
    # <head><title>The Dormouse's story</title></head>

    文档title的字符串也有父节点:标签

    title_tag.string.parent 
    # <title>The Dormouse's story</title>

    文档的顶层节点比方的父节点是 BeautifulSoup 对象:

    html_tag = soup.html 
    type(html_tag.parent) 
    # <class 'bs4.BeautifulSoup'>

    BeautifulSoup 对象的 .parent 是None。

    .parents
    通过元素的.parents属性能够递归得到元素的全部父辈节点 , 以下的样例使用了 .parents方 法遍历了 标签到根节点 的全部节点:

    link = soup.a 
    link 
    # <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a> 
    for parent in link.parents: 
        if parent is None: 
            print(parent) 
        else: 
            print(parent.name) 
    # p 
    # body 
    # html 
    # [document] 
    # None

    兄弟节点
    举例说明:

    <a>
        <b>text1</b>
        <c>text2</c>
    </a>

    这里的b和c节点为兄弟节点
    .next_sibling 和 .previous_sibling .:
    在文档树中 ,使用 .next_sibling 和 .previous_sibling 属性来查询兄弟节点:

    sibling_soup = BeautifulSoup("<a><b>text1</b><c>text2</c></b></a>")
    sibling_soup.b.next_sibling   
    # <c>text2</c> 
    sibling_soup.c.previous_sibling 
    # <b>text1</b>

    b 标签有.next_sibling 属性 ,可是没有 .previous_sibling 属性 ,由于 b标签在同级节点中是第一个 .同理 ,c标签有 .previous_sibling 属性 ,却没有 .next_sibling 属性 。

    link = soup.a link 
    # <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a> 
    link.next_sibling 
    # u',
    '

    注意:第一个a标签的next_sibling 属性值为 。

    link.next_sibling.next_sibling 
    # <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>

    第一个a标签的next_sibling的next_sibling 属性值为Lacie

    .next_siblings.previous_siblings.
    通过 .next_siblings 和 .previous_siblings 属性对当前节点的兄弟节点迭代输出:

    for sibling in soup.a.next_siblings: 
        print(repr(sibling)) # u',
    ' 
    # <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> 
    # u' and
    ' 
    # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a> 
    # u'; and they lived at the bottom of a well.' 
    # None 
    for sibling in soup.find(id="link3").previous_siblings:                                 print(repr(sibling)) 
    # ' and
    ' 
    # <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> 
    # u',
    '
    # <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a> 
    # u'Once upon a time there were three little sisters; and their names were
    ' 
    # None

    回退和前进:
    举例html例如以下:

    <html><head><title>The Dormouse's story</title></head> <p class="title"><b>The Dormouse's story</b></p>

    HTML 解析器把这段字符串转换成一连的事件 : “ 打开标签 ”加入一段字符串 ”,关闭 标签 ”,”打开

    标签 ”, 等.Beautiful Soup提供了重现解析器初始化过程的方法

    .next_element 和 .previous_element .
    .next_element 属性指向解析过程中下一个被的对象 (字符串或 tag),结果可能 与 .next_sibling 同样 ,但一般是不一样的 .

    last_a_tag = soup.find("a", id="link3") 
    last_a_tag 
    # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a> 
    last_a_tag.next_sibling 
    # '; and they lived at the bottom of a well.'

    但这个 标签的 .next_element 属性结果是在标签被解析之后的内容 ,不是 标 签后的句子部分 ,应该是字符串 ”Tillie”:

    last_a_tag.next_element 
    # u'Tillie'

    .previous_element 属性刚好与.next_element 相反 ,它指向当前被解 析的对象的前一个解析对象 :

    last_a_tag.previous_element 
    # u' and
    ' 
    last_a_tag.previous_element.next_element
    # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>

    .next_elements 和 .previous_elements
    通过 .next_elements 和 .previous_elements 的迭代器就能够向前或后訪问文档解析内容 ,就好像文档正在被解析一样 :

    for element in last_a_tag.next_elements:                  print(repr(element)) 
    # u'Tillie' 
    # u';
    and they lived at the bottom of a well.' 
    # u'
    
    ' 
    # <p class="story">...</p> 
    # u'...' 
    # u'
    ' 
    # None

    下一篇 将解说一下BeautifulSoup的搜索文档树的高级方法。

  • 相关阅读:
    hdu5628 Clarke and math
    LOJ#2452. 「POI2010」反对称 Antisymmetry
    LOJ#2444. 「NOI2011」阿狸的打字机
    BZOJ2795: [Poi2012]A Horrible Poem
    LOJ#2427. 「POI2010」珍珠项链 Beads
    云主机文件系统readonly处理案例
    兼容性测试中如何切换和管理多个JDK版本
    Promise之你看得懂的Promise
    一次MySQL线上慢查询分析及索引使用
    考拉消息中心消息盒子处理重构(策略模式)
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/7053776.html
Copyright © 2011-2022 走看看