zoukankan      html  css  js  c++  java
  • 读BeautifulSoup官方文档之与bs有关的对象和属性(2)

    上一节说到tag, 这里接着讲, tag有个属性叫做string, tag.string其实就是我们要掌握的四个对象中的第二个 ---- NavigableString,  它代表的是该tag内的text(甚至包括空白字符, 该tag内如果有别的tag, 必须前后紧挨不带空格, 否则返回None, 这一点的原因在下面提到了.), 其实这个NavigableString就是对于普通的Unicode的字符串的封装, 除了他提供一些对方便html结构树进行搜索的方法, 同时我们可以用.replace_with()来替换tag的内容, 我们可以用 unicode() 来将它转化为普通string. 

     1 tag.string
     2 # u'Extremely bold'
     3 type(tag.string)
     4 # <class 'bs4.element.NavigableString'>
     5 
     6 unicode_string = unicode(tag.string)
     7 unicode_string
     8 # u'Extremely bold'
     9 type(unicode_string)
    10 # <type 'unicode'>
    11 
    12 tag.string.replace_with("No longer bold")
    13 tag
    14 # <blockquote>No longer bold</blockquote>

    最后一个要说的对象叫做Comment, Comment 其实就是特殊的NavigableString对象. 经过实现发现只有紧挨这父tag写, 才有效果, 否则会返回None.(原因也在下面提到了)

    1 markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
    2 #<b> <!--前面有一个空格--></b> --> 这样会直接返回None
    3 soup = BeautifulSoup(markup)
    4 comment = soup.b.string
    5 type(comment)
    6 # <class 'bs4.element.Comment'>

    了解了这四类对象, 接下来我们就可以探究如何找到所需要的内容...

    下面是最简单的方式 :

    soup.head
    # <head><title>The Dormouse's story</title></head> 如果有多个返回第一个
    
    soup.body.b
    # <b>The Dormouse's story</b> 先找到第一个body, 再找body中的第一个b
    
    soup.b
    #如果上例中b是最先出现的, 那么也可以直接索引得到.

    .contents 和 .children:

    这两者的区别在于.contents返回的是列表, .children返回的是generator(但是其实内容都是一样的)...

    比如对于

    1 <body>
    2 <b>
    3     aabbccdd
    4 </b>
    5 </body>
    1 soup = BeautifulSoup(open('test.html'), 'lxml')
    2 print(soup.body.contents)

    结果是:

    ['
    ', <b>
      aabbccdd
    </b>, '
    ']

    值得一提的是BeautifulSoup也有自己的contents.

    .descendants :

    这个和.children唯一的区别在于前者返回所有子孙后者只返回直系孩子, 就不多说了.

    .string :

    如果一个tag只有一个children并且那个children还是NavigableString(这种情况就是tag的内容是纯文字), 那么我们可以用.string来获得它.

    1 <b>
    2     aabbccdd
    3 </b>

    上述html的b.contents是这样的 :

    ['
        aabbccdd
    ']

    对于这种, 就是符合上面所说的情况的, 就可以用b.string来获得它...

    同时如果一个tag只有一个children并且它的children是另外一个tag, 且另外一个tag有一个.string, 那么这个tag的.string就等于它的孩子的.string.

    对于这个例子是不行的 :

    1 <body>
    2 <b>
    3     aabbccdd
    4 </b>
    5 </body>

    对这个例子来说, 调用.contents的结果是这样的:

    ['
    ', <b>
        aabbccdd
    </b>, '
    ']

    除非把上面的例子写成这样 :

    <body><b> aabbccdd </b></body>

    这就是为什么我上面说要想得到.string必须tag前后紧挨不能有空格的原因.

  • 相关阅读:
    CentOS 7 搭建 LAMP
    CentOS 7 安装 nginx
    ms-sql关联表操作
    在CentOS下自动备份mysql
    Redhat 7 或者 CentOS 7 密码破解
    java环境变量的设置
    CentOS6.6安装及配置vsftpd文件服务器
    Virtualbox虚拟机配置CentOS7.0静态网络
    CentOS6.6安装vmware workstation报错
    CentOS6.6安装virtualbox4.1.44
  • 原文地址:https://www.cnblogs.com/nzhl/p/5590843.html
Copyright © 2011-2022 走看看