• 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')
    
  • 相关阅读:
    使用springboot遇到的问题
    npm使用出现的问题
    ORACLE遇到的新知识
    使用linux
    解释ArrayList的源码
    git的基础知识(并不是直接照着抄写的,用到的写过来)
    使用github遇到的问题
    java将数据库中菜单表中内容转化成一个导航树
    使用python自动发放员工工资条到个人邮箱
    zabbix图形中文乱码
  • 原文地址:https://www.cnblogs.com/hsinfo/p/13775545.html
Copyright © 2020-2023  润新知