zoukankan      html  css  js  c++  java
  • 1.4Beautiful Soup

    Beautiful Soup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库

    Beautiful Soup简介

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

    安装

    pip install beautifulsoup4
    #安装Beautifulsoup4
    pip install lxml
    #安装解析器
    

    基本用法

    <--示例代码-->
    html_doc = """
    <html><head><title>The Dormouse's story</title></head>
    <body>
    <p class="sister"><b>$37</b></p>
    <p class="story" id="p">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" >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>
    """
    
    from bs4 import BeautifulSoup
    # 第一个参数是解析文本
    # 第二个参数是解析器
    soup = BeautifulSoup(html_doc, 'lxml')
    
    # 具备自动补全html标签功能
    print(soup)
    
    # 美化html便签
    html_doc = soup.prettify()
    print(html_doc)
    

    遍历文档树

    主要看标黑的

    1、直接使用 '.' 来查找,只能找到第一个,返回的是一个对象

    # 直接选择标签(返回的是一个对象)
    print(soup.a)  # 获取第一个a标签
    print(soup.p)  # 获取第一个p标签
    print(type(soup.a))  # <class 'bs4.element.Tag'>
    

    2、获取标签的名称(没什么用)

    print(soup.a.name)  # 获取a标签的名字
    

    3、获取标签的属性(也没什么用)

    方式一

    soup = BeautifulSoup(html_doc, 'lxml')
    res = soup.p
    print(res['class'])  # class 可以有多个,所以是列表
    # ['sister']
    

    方式二

    print(soup.a.arrts)  # 获取a标签内所有的属性
    # {'href': 'http://example.com/elsie', 'class': ['sister']}
    print(res.a.attrs['class'])
    # ['sister']
    

    4、获取标签的内容

    print(soup.p.text)  # 所有层级都拿出来拼到一起
    print(soup.string)  # 只有 1 层,才能取出
    pring(list(soup.strings))  # 把每次取出来都做成一个生成器
    print(soup.a.arrts['href'])  # 获取a标签内的href属性
    #http://example.com/elsie
    

    5、嵌套选择

    print(soup.p.b)   #获取第一个p标签内的b标签		#<b>$37</b>
    print(soup.p.b.text)  # 打印b标签内的文本		  #$37
    

    6、子节点、子孙节点(不经常用)

    print(soup.p.children)	 # 获取第一个p标签所有的子节点,返回的是一个迭代器
    print(list(soup.p.children))  # list转成列表
    

    7、父节点、祖先节点(不经常用)

    print(soup.a.parent)  # 获取第一个a标签内的父节点
    # 获取祖先节点(爸爸,爸爸的爸爸,爸爸的爸爸的爸爸...以此类推)
    print(list(soup.a.parents))  # 获取第一个a标签的祖先节点,返回的是一个生成器
    

    8、兄弟节点(不经常用)

    # (sibling: 兄弟姐妹)
    # 获取下一个兄弟节点   
    print(soup.a.next_sibling)
    # 获取下一个的所有兄弟节点,返回的是一个生成器
    print(soup.a.next_siblings)
    print(list(soup.a.next_siblings)) 
    # 获取上一个兄弟节点
    print(soup.a.previous_sibling)
    # 获取上一个的所有兄弟节点,返回的是一个生成器
    print(list(soup.a.previous_siblings))
    

    搜索文档树

    BeautifulSoup定义了很多搜索方法,这里着重介绍2个:find() find_all(),两个配合使用

    1、字符串查找 引号内是字符串

    print(soup.find('p'))	#获取第一个p标签
    print(soup.find_all('p'))	#获取所有的p标签
    print(soup.find_all(class_='title'))  # 获取所有 class 为 title 的标签
    print(soup.find_all(id='id_p'))  # 获取所有 id 为 id_p 的标签
    
    print(soup.find(text='$37'))  # 查找标签内为$37的文本,推荐配合其他匹配规则使用,否则毫无意义
    print(soup.find_all(name='p',text='$37'))  # 查找所有文本为$37的p标签
    print(soup.find_all(href='http://example.com/elsie'))  # href属性为http://example.com/elsie的标签
    
    # 组合使用
    print(soup.find_all(name='a',attrs={'id':'link3'},text='Tillie'))  # 查找所有id为link3,文本为Tillie的a标签
    
    

    2、正则表达式

    import re
    res = re.compile('^b')
    res = soup.find_all(name=res)  # 查找以 b 开头的所有标签
    res = re.compile('#con')
    res = soup.find_all(id='res')  # 查找 id 为 con 开头的 id 的所有标签
    

    3、列表

    # 列表内可以匹配多个
    ret=soup.find_all(name=['body','b'])
    ret=soup.find_all(id=['id_p','link1'])
    ret=soup.find_all(class_=['id_p','link1'])
    
    and 关系
    ret=soup.find_all(class_='title',name='p')
    

    4、True

    ret=soup.find_all(name=True)  # 所有有名字的标签
    ret=soup.find_all(id=True)   # 所有有id的标签
    ret=soup.find_all(href=True)  # 所有有herf属性的
    

    5、方法(了解)

    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))
    

    6、其他使用(了解)

    ret=soup.find_all(attrs={'class':"title"})
    ret=soup.find_all(attrs={'id':"id_p1",'class':'title'})
    

    7、拿到标签,取属性,取 text

    ret=soup.find_all(attrs={'id':"id_p",'class':'title'})
    print(ret[0].text)
    

    8、limit(限制条数)

    # soup.find()  就是find_all limit=1
    ret=soup.find_all(name=True,limit=2)  # 只要 2 条数据
    

    9、recursive(了解)

    # recursive=False (只找儿子)不递归查找,只找第一层
    ret=soup.body.find_all(name='p',recursive=False)
    

    CSS 选择器

    1 css 选择器

    Tag 对象.select("css 选择器")

    print(soup.p.select('.sister'))
    print(soup.select('.sister span'))
    
    print(soup.select('#link1'))
    print(soup.select('#link1 span'))
    
    print(soup.select('#list-2 .element.xxx'))
    
    print(soup.select('#list-2')[0].select('.element')) #可以一直select,但其实没必要,一条select就可以了
    

    2 获取属性

    print(soup.select('#list-2 h1')[0].attrs)
    

    3 获取内容

    print(soup.select('#list-2 h1')[0].get_text())
    

    XPath 选择

    / 从根节点选取
    // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
    . 选取当前节点
    .. 选取当前节点的父节点
    @ 选取属性

    示例文档
    doc='''
    <html>
     <head>
      <base href='http://example.com/' />
      <title>Example website</title>
     </head>
     <body>
      <div id='images'>
       <a href='image1.html' id="xxx">Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>
       <h5>test</h5>
       <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
       <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
       <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
       <a href='image5.html' class='li li-item' name='items'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
       <a href='image6.html' name='items'><span><h5>test</h5></span>Name: My image 6 <br /><img src='image6_thumb.jpg' /></a>
      </div>
     </body>
    </html>
    '''
    

    1 所有节点

    a=html.xpath('//*')
    

    2 指定节点(结果为列表)

    a=html.xpath('//head')
    

    3 子节点,子孙节点

    a=html.xpath('//div/a')
    

    4 父节点

    a=html.xpath('//body//a[@href="image1.html"]/..')
    a=html.xpath('//body//a[@href="image1.html"]')
    a=html.xpath('//body//a[1]/..')
    也可以这样
    a=html.xpath('//body//a[1]/parent::*')
    

    5 属性匹配

    a=html.xpath('//body//a[@href="image1.html"]')
    

    6 文本获取 标签后加:/text()

    a=html.xpath('//body//a[@href="image1.html"]/text()')
    a=html.xpath('//body//a/text()')
    

    7 属性获取 标签后:/@href

    a=html.xpath('//body//a/@href')
    # 注意从1 开始取(不是从0)
    a=html.xpath('//body//a[3]/@href')
    

    8 属性多值匹配

    a=html.xpath('//body//a[@class="li"]')
    a=html.xpath('//body//a[@href="image1.html"]')
    a=html.xpath('//body//a[contains(@class,"li")]')
    a=html.xpath('//body//a[contains(@class,"li")]/text()')
    a=html.xpath('//body//a[contains(@class,"li")]/@name')
    

    9 多属性匹配 or 和 and (了解)

    a=html.xpath('//body//a[contains(@class,"li") or @name="items"]')
    a=html.xpath('//body//a[contains(@class,"li") and @name="items"]/text()')
    a=html.xpath('//body//a[contains(@class,"li")]/text()')
    

    10 按序选择

    a=html.xpath('//a[2]/text()')
    a=html.xpath('//a[2]/@href')
    # 取最后一个(了解)
    a=html.xpath('//a[last()]/@href')
    a=html.xpath('//a[last()]/text()')
    # 位置小于3的
    a=html.xpath('//a[position()<3]/@href')
    a=html.xpath('//a[position()<3]/text()')
    # 倒数第二个
    a=html.xpath('//a[last()-2]/@href')
    

    11 节点轴选择

    # ancestor:祖先节点
    # 使用了* 获取所有祖先节点
    a=html.xpath('//a/ancestor::*')
    # # 获取祖先节点中的div
    # a=html.xpath('//a/ancestor::div')
    # a=html.xpath('//a/ancestor::div/a[2]/text()')
    # attribute:属性值
    # a=html.xpath('//a[1]/attribute::*')
    # a=html.xpath('//a[1]/@href')
    # child:直接子节点
    # a=html.xpath('//a[1]/child::*')
    # a=html.xpath('//a[1]/img/@src')
    # descendant:所有子孙节点
    # a=html.xpath('//a[6]/descendant::*')
    # following:当前节点之后所有节点(递归)
    # a=html.xpath('//a[1]/following::*')
    # a=html.xpath('//a[1]/following::*[1]/@href')
    # following-sibling:当前节点之后同级节点(同级)
    # a=html.xpath('//a[1]/following-sibling::*')
    # a=html.xpath('//a[1]/following-sibling::a')
    # a=html.xpath('//a[1]/following-sibling::*[2]')
    # a=html.xpath('//a[1]/following-sibling::*[2]/@href')
    
  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/hsinfo/p/13775545.html
Copyright © 2011-2022 走看看