bs4的操作

下面的一段HTML代码将作为例子

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<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>
"""
  1. prettify() 将一个bs对象按照标准格式进行格式化输出
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc)
print(soup.prettify())
  1. 几个简单的浏览结构化的方法

    • soup.标签:找出第一个该类标签

      print(soup.title)
      
      # <title>The Dormouse's story</title>
      
    • soup.标签.name:获取tag的name属性值

          print(soup.title.name)
          # title
    • soup.title.text 和 soup.title.string 的区别:

      print(soup.title.text)
      print(type(soup.title.text))
      print(soup.title.string)
      print(type(soup.title.string))
      
      # The Dormouse's story
      
      
      # <class 'str'>
      
      
      # The Dormouse's story
      
      
      # <class 'bs4.element.NavigableString'>
      
    • find_all() 和 find():前者返回符合条件的标签列表,后者返回一个bs4的tag对象

    • soup.get_text() 获取文档中的所有的文字内容
  2. tag标签属性值的操作

    • 获取属性值:获取文档中第一个p标签的所有class属性,返回list,转换的文档是XML格式,那么tag中不包含多值属性

      print(soup.p.get('class'))
      print(soup.p.attrs['class'])
      print(soup.p['class'])
      
      # ['title']
      
      
      # ['title']
      
      
      # ['title']
      
    • 添加、修改属性、删除属性:

      soup.b['class'] = 'content'
      print(soup.b)
      
      #<b class="content">The Dormouse's story</b>
      
      soup.b['class'] = 'text'
      print(soup.b)
      
      #<b class="text">The Dormouse's story</b>
      
      del soup.b['class']
      print(soup.b)
      
      #<b>The Dormouse's story</b>
      
  3. 子节点

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

      print(soup.head.contents)
      
      # [<title>The Dormouse's story</title>]
      
    • .children 生成器,可以对tag的直接子节点进行循环

      for j in soup.head.children:
          print(j)
      
      #<title>The Dormouse's story</title>
      
      for i in soup.title.children:
          print(i)
      
      #The Dormouse's story
      
    • .descendants 属性可以对所有tag的子孙节点进行递归循环

      for k in soup.head.descendants:
          print(k)
      
      # <title>The Dormouse's story</title>
      
      
      # The Dormouse's story
      
    • .string 和 .strings \ stripped_strings:tag只有一个 NavigableString 类型子节点,那么这个tag可以使用 .string 得到子节点;tag中包含多个字符串 [2] ,可以使用 .strings 来循环获取;输出的字符串中可能包含了很多空格或空行,使用 .stripped_strings 可以去除多余空白内容;

  4. 父节点

    • .parent:

      <head>标签是<title>标签的父节点;
      文档title的字符串也有父节点:<title>标签;
      文档的顶层节点比如<html>的父节点是 BeautifulSoup 对象;
      BeautifulSoup 对象的 .parent 是None;
    • .parents:通过元素的 .parents 属性可以递归得到元素的所有父辈节点,下面的例子使用了 .parents 方法遍历了\<\a>标签到根节点的所有节点.

      for parent in soup.a.parents:
          print(parent.name)
      
      #p
      
      
      #body
      
      
      #html
      
      
      #[document]
      
  5. 兄弟节点

    • .next_sibling 和 .previous_sibling:\<\b>标签有 .next_sibling 属性,但是没有 .previous_sibling 属性,因为\<\b>标签在同级节点中是第一个.同理,\<\c>标签有 .previous_sibling 属性,却没有 .next_sibling 属性:

      sibling_soup = BeautifulSoup('<a><b>text1</b><c>text2</c></b></a>')
    • 在html_doc文档中,第一个\<\a>标签的.next_sibling结果不是第二个标签,而是’,’

    • 通过 .next_siblings 和 .previous_siblings 属性可以对当前节点的兄弟节点迭代输出;
  6. 搜索文档树

    • 过滤器
      – 字符串
      soup.find_all('b') 找出所有的<b>标签

    – 正则表达式

    soup.find_all(re.compile("^b")) 找出所有以b开头的标签,例子中<body>和<b>都能被找到
    soup.find_all(re.comile("t")) 找出所有标签中包含't'的标签

    – 列表

    soup.find_all(["a", "b"]) 找到文档中所有<a>标签和<b>标签

    – True

    soup.find_all(True) True:可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点

    – 方法
    以下方法找出包含 class 属性却不包含 id 属性的标签:

    def has_class_but_no_id(tag):
        return tag.has_attr('class') and not tag.has_attr('id')
    print(soup.find_all(has_class_but_no_id))
    
    # [<p class="title content"><b>The Dormouse's story</b></p>, <p class="story">Once upon a # time there were three little sisters; and their names were
    
    
    # <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    
    
    # <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
    
    
    # <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
    
    
    # and they lived at the bottom of a well.</p>, <p class="story">...</p>]
    
    • find_all
      -- find_all( name , attrs , recursive , text , **kwargs )
      soup.find_all("p", "title")
      
      # [<p class="title"><b>The Dormouse's story</b></p>]
      
      soup.find_all(href=re.compile("elsie"), id='link1')
      
      # [<a class="sister" href="http://example.com/elsie" id="link1">three</a>]
      

    – 特殊属性的搜索

    data_soup = BeautifulSoup('<div data-foo="value">foo!</div>')
    data_soup.find_all(data-foo="value")
    
    # SyntaxError: keyword can't be an expression
    
    data_soup.find_all(attrs={"data-foo": "value"})
    
    # [<div data-foo="value">foo!</div>]
    

    – 按CSS搜索
    class 在Python中是保留字,使用 class 做参数会导致语法错误.从Beautiful Soup的4.1.1版本开始,可以通过 class_ 参数搜索有指定CSS类名的tag:

    print(soup.find_all("a", class_="sister"))
    
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    
    
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
    
    
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    

    – text参数
    class 在Python中是保留字,使用 class 做参数会导致语法错误.从Beautiful Soup的4.1.1版本开始,可以通过 class_ 参数搜索有指定CSS类名的tag:

    print(soup.find_all(text="Elsie"))
    
    # ['Elsie']
    

    – limit参数

    soup.find_all("a", limit=2)
    
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    
    
    #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    

    – recursive 参数
    调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False :

    soup.html.find_all("title")
    
    # [<title>The Dormouse's story</title>]
    
    soup.html.find_all("title", recursive=False)
    
    # []
    
    • Beautiful Soup中还有10个用于搜索的API.它们中的五个用的是与 find_all() 相同的搜索参数,另外5个与 find() 方法的搜索参数类似.区别仅是它们搜索文档的不同部分.记住: find_all() 和 find() 只搜索当前节点的所有子节点,孙子节点等. find_parents() 和 find_parent() 用来搜索当前节点的父辈节点,搜索方法与普通tag的搜索方法相同,搜索文档搜索文档包含的内容. 我们从一个文档中的一个叶子节点开始.

    • CSS选择器
      Beautiful Soup支持大部分的CSS选择器,在 Tag 或 BeautifulSoup 对象的 .select() 方法中传入字符串参数,即可使用CSS选择器的语法找到tag:
      – 通过tag标签逐层查找:

      soup.select("html head title")
      
      # [<title>The Dormouse's story</title>]
      

    – 找到某个tag标签下的直接子标签:

    soup.select("head > title")
    
    # [<title>The Dormouse's story</title>]
    
    soup.select("p > a")
    
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
    
    
    #  <a class="sister" href="http://example.com/lacie"  id="link2">Lacie</a>,
    
    
    #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    
    soup.select("p > a:nth-of-type(2)")
    
    # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]
    
    soup.select("p > #link1")
    
    # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
    
    soup.select("body > a")
    
    # []
    

    – 找到兄弟节点标签:(所有兄弟和直系兄弟)

    soup.select("#link1 ~ .sister")
        # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
        #  <a class="sister" href="http://example.com/tillie"  id="link3">Tillie</a>]
    soup.select("#link1 + .sister")
        # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

    – 通过CSS的类名查找:

    soup.select(".sister")
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
        #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
        #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    soup.select("[class~=sister]")
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
        #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
        #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

    – 通过tag的id查找:

    soup.select("#link1")
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
    soup.select("a#link2")
        # [<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>]

    – 通过是否存在某个属性来查找:

    soup.select('a[href]')
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
        #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
        #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

    – 通过属性的值来查找:

    soup.select('a[href="http://example.com/elsie"]')
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
    soup.select('a[href^="http://example.com/"]')
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>,
        #  <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>,
        #  <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    soup.select('a[href$="tillie"]')
        # [<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
    soup.select('a[href*=".com/el"]')
        # [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值