zoukankan      html  css  js  c++  java
  • 遍历文档树

    子节点

    • 一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点.Beautiful Soup提供了许多操作和遍历子节点的属性.

    • 注意: Beautiful Soup中字符串节点不支持这些属性,因为字符串没有子节点

    1. tag的名字

    • 操作文档树最简单的方法就是告诉它你想获取的tag的name.如果想获取 <head>标签,只要用 soup.head :

    • 这是个获取tag的小窍门,可以在文档树的tag中多次调用这个方法.下面的代码可以获取<body>标签中的第一个<b>标签:

    • 通过点取属性的方式只能获得当前名字的第一个tag:

    • 如果想要得到所有的<a>标签,或是通过名字得到比一个tag更多的内容的时候,就需要用到搜索文档树中描述的方法,比如: find_all()

    2. .contents 和 .children

    • tag的.contents属性可以将tag的子节点以列表的方式输出:

    • BeautifulSoup 对象本身一定会包含子节点,也就是说<html>标签也是 BeautifulSoup 对象的子节点:

    • 字符串没有 .contents 属性,因为字符串没有子节点:

    • 通过tag的 .children 生成器,可以对tag的子节点进行循环:

    3. .descendants

    • .contents .children 属性仅包含tag的直接子节点.例如,<head>标签只有一个直接子节点<title>
    
    head_tag.contents
    
    # [<title>The Dormouse's story</title>]
    
    
    • 但是标签也包含一个子节点:字符串 “The Dormouse’s story”,这种情况下字符串 “The Dormouse’s story”也属于<code><head></code>标签的子孙节点. <code>.descendants</code> 属性可以对所有tag的子孙节点进行递归循环(先序遍历):</li> </ul> <pre><code class="language-python"> for child in head_tag.descendants: print(child) # <title>The Dormouse's story</title> # The Dormouse's story </code></pre> <p>上面的例子中, <code><head></code>标签只有一个子节点,但是有2个子孙节点:<code><head></code>节点和<code><head></code>的子节点, BeautifulSoup 有一个直接子节点(<code><html></code>节点),却有很多子孙节点:</p> <pre><code> len(list(soup.children)) # 1 len(list(soup.descendants)) # 25 </code></pre> <h3 id="4-string">4. .string</h3> <ul> <li>如果tag只有一个 NavigableString 类型子节点,那么这个tag可以使用 <code>.string </code>得到子节点:</li> </ul> <pre><code class="language-python"> title_tag.string # u'The Dormouse's story' </code></pre> <p>如果一个tag仅有一个子节点,那么这个tag也可以使用 <code>.string</code> 方法,输出结果与当前唯一子节点的 <code>.string</code> 结果相同:</p> <pre><code class="language-python"> head_tag.contents # [<title>The Dormouse's story</title>] </code></pre> <pre><code class="language-python"> head_tag.string # u'The Dormouse's story' </code></pre> <p>如果tag包含了多个子节点,tag就无法确定 <code>.string</code> 方法应该调用哪个子节点的内容, <code>.string</code> 的输出结果是 None :</p> <pre><code class="language-python"> print(soup.html.string) # None </code></pre> <h3 id="5-strings-和-stripped_strings">5. .strings 和 stripped_strings</h3> <h2 id="父节点">父节点</h2> <ul> <li>每个tag或字符串都有父节点:被包含在某个tag中</li> </ul> <h3 id="1-parent">1. .parent</h3> <ul> <li> <p>通过<code>.parent</code>属性来获取某个元素的父节点.在例子文档中,<code><head></code>标签是<code><title></code>标签的父节点:</p> </li> <li> <p>文档title的字符串也有父节点:<title>标签</p> </li> <li> <p>文档的顶层节点比如<code><html></code>的父节点是 BeautifulSoup 对象:</p> </li> <li> <p>BeautifulSoup 对象的 <code>.parent</code> 是None:</p> </li> </ul> <h3 id="2-parents">2. .parents</h3> <ul> <li>通过元素的 .parents 属性可以递归得到元素的所有父辈节点,下面的例子使用了 .parents 方法遍历了<code><a></code>标签到根节点的所有节点</li> </ul> <h2 id="兄弟节点">兄弟节点</h2> <pre><code class="language-python"> sibling_soup = BeautifulSoup("<a><b>text1</b><c>text2</c></b></a>") print(sibling_soup.prettify()) # <html> # <body> # <a> # <b> # text1 # </b> # <c> # text2 # </c> # </a> # </body> # </html> </code></pre> <blockquote> <p>因为<b>标签和<c>标签是同一层:他们是同一个元素的子节点,所以<b>和<c>可以被称为兄弟节点.一段文档以标准格式输出时,兄弟节点有相同的缩进级别.在代码中也可以使用这种关系.</p> </blockquote> <h3 id="1-next_sibling-和-previous_sibling">1. .next_sibling 和 .previous_sibling</h3> <ul> <li> <p>在文档树中,使用 <code>.next_sibling</code> 和 <code>.previous_sibling</code> 属性来查询兄弟节点:</p> </li> <li> <p>例子中的字符串“text1”和“text2”不是兄弟节点,因为它们的父节点不同:</p> </li> <li> <p>实际文档中的tag的<code> .next_sibling</code> 和 <code>.previous_sibling</code> 属性通常是字符串或空白.</p> </li> </ul> <pre><code> <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a> <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a> </code></pre> <blockquote> <p>如果以为第一个<code><a></code>标签的<code> .next_sibling</code> 结果是第二个<code><a></code>标签,那就错了,真实结果是第一个<code><a></code>标签和第二个<code><a></code>标签之间的顿号和换行符:</p> </blockquote> <p>第二个<code><a></code>标签是顿号的 <code>.next_sibling</code> 属性:</p> <h3 id="2-next_siblings-和-previous_siblings">2. .next_siblings 和 .previous_siblings</h3> <ul> <li>通过 .next_siblings 和 .previous_siblings 属性可以对当前节点的兄弟节点迭代输出:</li> </ul> <h2 id="回退和前进">回退和前进</h2> <pre><code> <html><head><title>The Dormouse's story</title></head> <p class="title"><b>The Dormouse's story</b></p> </code></pre> <blockquote> <p>HTML解析器把这段字符串转换成一连串的事件: “打开<html>标签”,”打开一个<head>标签”,”打开一个<title>标签”,”添加一段字符串”,”关闭<title>标签”,”打开<p>标签”,等等.Beautiful Soup提供了重现解析器初始化过程的方法.</p> </blockquote> <h3 id="1-next_element-和-previous_element">1. .next_element 和 .previous_element</h3> <blockquote> <p><code>.next_element</code> 属性指向解析过程中下一个被解析的对象(字符串或tag),结果可能与<code>.next_sibling</code>相同,但通常是不一样的.</p> </blockquote> <blockquote> <p>这是文档中最后一个<code><a></code>标签,它的 <code>.next_sibling</code> 结果是一个字符串,因为当前的解析过程 [2] 因为当前的解析过程因为遇到了<code><a></code>标签而中断了:</p> </blockquote> <pre><code class="language-python"> 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.' </code></pre> <blockquote> <p>但这个<code><a></code>标签的<code>.next_element</code>属性结果是在<code><a></code>标签被解析之后的解析内容,不是<code><a></code>标签后的句子部分,应该是字符串”Tillie”:</p> </blockquote> <pre><code class="language-python"> last_a_tag.next_element # u'Tillie' </code></pre> <blockquote> <p>这是因为在原始文档中,字符串“Tillie” 在分号前出现,解析器先进入<code><a></code>标签,然后是字符串“Tillie”,然后关闭<code></a></code>标签,然后是分号和剩余部分.分号与<code><a></code>标签在同一层级,但是字符串“Tillie”会被先解析.</p> </blockquote> <blockquote> <p><code>.previous_element</code> 属性刚好与 <code>.next_element </code>相反,它指向当前被解析的对象的前一个解析对象:</p> </blockquote> <h3 id="2-next_elements-和-previous_elements">2. .next_elements 和 .previous_elements</h3> <ul> <li>通过 .next_elements 和 .previous_elements 的迭代器就可以向前或向后访问文档的解析内容,就好像文档正在被解析一样:</li> </ul>
    秋来凉风起,无限思远人
  • 相关阅读:
    Requests库常用方法及其详解
    MacOS下搭建python环境
    Requests库与HTTP协议
    MacOS下安装Requests库及使用
    Swing State: Consistent Updates for Stateful and Programmable Data Planes
    Transparent Flow Migration for NFV
    2018软工团队选题报告
    Traffic Steering for Service Function Chaining
    2018年软工第二次结对作业
    【数字图像处理】Tencent视频团队讲座记录
  • 原文地址:https://www.cnblogs.com/lalavender/p/10744880.html
Copyright © 2011-2022 走看看