• BeautifulSoup


    Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。
    它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。

    一、安装

    pip install beautifulsoup4
    pip install lxml

    二、使用

    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(html_doc,'lxml')
    res = soup.prettify()   # 结构化显示,并补全标签

    三、遍历文档树

    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 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>
     </body>
    </html>
    """
    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(html_doc,'lxml')
    print(soup.p)             # 找到第一个P标签
    print(soup.p.name)        # 获取标签的名称 p
    print(soup.p.attrs)       # 获取标签的属性 {'class': ['title']}

    获取标签的文本

    print(soup.p.text)        # 获取p标签下的所有内容
    print(soup.p.get_text())  # 获取p标签下的所有内容
    print(soup.p.string)      # p标签的文本只有一个时,否则返回None
    print(soup.p.strings)     # 获取生成器对象,取到P标签下的所有内容
    
    for line in soup.p.strings:
        print(line)

    tag对象

    tag_p = soup.p
    print(tag_p.attrs)              # {'class': ['title'], 'id': 'p1'}
    print(tag_p['class'])           # ['title']
    print(tag_p.get('class'))       # ['title']
    print(tag_p['id'])              # p1
    print(tag_p.get('id'))          # p1
    #1、嵌套选择
    print(soup.head.title.string)
    print(soup.body.a.string)
    
    
    #2、子节点、子孙节点
    print(soup.p.contents) #p下所有子节点
    print(soup.p.children) #得到一个迭代器,包含p下所有子节点
    
    for i,child in enumerate(soup.p.children):
        print(i,child)
    
    print(soup.p.descendants) #获取子孙节点,p下所有的标签都会选择出来
    for i,child in enumerate(soup.p.descendants):
        print(i,child)
    
    #3、父节点、祖先节点
    print(soup.a.parent) #获取a标签的父节点
    print(soup.a.parents) #找到a标签所有的祖先节点,父亲的父亲,父亲的父亲的父亲...
    
    
    #4、兄弟节点
    print(soup.a.next_sibling) #下一个兄弟
    print(soup.a.previous_sibling) #上一个兄弟
    
    print(list(soup.a.next_siblings)) #下面的兄弟们=>生成器对象
    print(soup.a.previous_siblings) #上面的兄弟们=>生成器对象

    四、五种过滤器

    html_doc = '''<html><head><title>The Dormouse's story</title></head>
    <body>
    <p class="title"><b>The Dormouse's story</b></p>
    <p class="title"><b>$75</b></p>
    <p id="meiyuan">啦啦啦啦啦啦</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>'''
    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(html_doc,'lxml')
    
    # find_all(self, name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs)
    
    # 1.字符串,即标签名,特点时完全匹配
    print(soup.find_all('b'))      # 找到所有的p标签,返回列表
    print(soup.find_all(attrs={'class':"sister"}))  # 找到class属性是sister的标签
    
    # 2.正则表达式
    import re
    print(soup.find_all(re.compile('^h')))  # 找到所有h开头的标签,head和html标签
    print(soup.find_all(attrs={"id":re.compile("link")}))       # 找到id有link的标签
    
    # 3.列表
    print(soup.find_all(['a','b']))           # 找到所有的a标签和b标签
    
    
    # 4.True:可以匹配任何值,下面代码查找到所有的tag,但是不会返回字符串节点
    print(soup.find_all(attrs={"id":True}))     # 查找所有含有id的标签
    print(soup.find_all(name=True))               # 找到所有标签的标签名
    
    # 5.方法:如果没有合适过滤器,那么还可以定义一个方法,方法只接受一个元素参数 ,如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False
    
    def has_class_not_id(tag):
        # 有class属性没id的标签
        return tag.has_attr("class") and not tag.has_attr("id")
    
    print(soup.find_all(has_class_not_id))
    
    print(soup.find_all(name="a",limit=2))#找所有的a标签,只找前两个
    print(soup.body.find_all(attrs={"class":"sister"},recursive=False))#找属性为sister的
    print(soup.html.find_all('a'))
    print(soup.html.find_all('a',recursive=False))
    # recursive = True  #从子子孙孙都找到了
    # recursive = False #如果只想搜索tag的直接子节点(就不往里面找了),可以使用参数 recursive=False .
    
    # **kwargs
    print(soup.find_all(attrs={"class":"sister"}))
    print(soup.find_all(class_="sister"))  #这两个是一样的
    
    print(soup.find_all(attrs={"id":"link3"})) #这两个是一样的,只是表示方式不一样
    print(soup.find_all(id="link3"))

    find_all() 和 find() 的区别

    唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回结果.
    find_all() 方法没有找到目标是返回空列表, find() 方法找不到目标时,返回 None .

    find_all( name , attrs , recursive , text , **kwargs )
    find( name , attrs , recursive , text , **kwargs )

    像调用 find_all() 一样调用tag
    find_all() 几乎是Beautiful Soup中最常用的搜索方法,所以我们定义了它的简写方法. BeautifulSoup 对象和 tag 对象可以被当作一个方法来使用,
    这个方法的执行结果与调用这个对象的 find_all() 方法相同,下面两行代码是等价的:
    
    soup.find_all("a")
    soup("a")
    
    这两行代码也是等价的:
    
    soup.title.find_all(text=True)
    soup.title(text=True)

    CSS选择器

    html_doc = """
     <html><head><title>The Dormouse's story</title></head>
     <body>
     <p class="title">
         <b>The Dormouse's story</b>
         Once upon a time there were three little sisters; and their names were
         <a href="http://example.com/elsie" class="sister" id="link1">
             <span>Elsie</span>
         </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>;
         <div class='panel-1'>
             <ul class='list' id='list-1'>
                 <li class='element'>Foo</li>
                 <li class='element'>Bar</li>
                 <li class='element'>Jay</li>
             </ul>
             <ul class='list list-small' id='list-2'>
                 <li class='element'><h1 class='yyyy'>Foo</h1></li>
                 <li class='element xxx'>Bar</li>
                 <li class='element'>Jay</li>
             </ul>
         </div>
         and they lived at the bottom of a well.
    </p>
    <p class="story">...</p>
    """
    
    from bs4 import BeautifulSoup
    
    soup=BeautifulSoup(html_doc,'lxml')
    
    # 1.通过标签名查找
    print(soup.select("title"))     # 返回title标签的列表
    
    # 2.通过类名查找
    print(soup.select(".sister"))
    
    # 3.通过ID查找
    print(soup.select("#link1"))
    
    # 获取属性
    print(soup.select("#list-2")[0].attrs)  # {'class': ['list', 'list-small'], 'id': 'list-2'}
    
    # 获取内容
    print(soup.select("#list-2")[0].text)
  • 相关阅读:
    编程爱好者论坛第六次编程比赛题目
    google china code jam round2 div1 1000分题
    ogl2dlibsdl cvs repository @ cosoft
    偶尔也提一个游戏点子:宇宙碰撞
    今天看到一些笑话...
    google china code jam入围赛的一个题
    用Regular expression寻找源代码中的汉字字符串
    生成函数理论初步
    Komodo 的中文支持
    “豪华版”的USB延长线
  • 原文地址:https://www.cnblogs.com/st-st/p/10313089.html
Copyright © 2020-2023  润新知