• 【3】数据筛选3



    #目录 ----     1. 开发前准备     2. 不同解析器对比     3. BeautifulSoup4 初始化和节点对象的认识     4. BS4 案例操作:初始化对象文档     5. 节点查询:子节点     6. 节点查询:父节点     7. 节点查询:兄弟节点     8. 节点查询:解析顺序     9. 高级查询: find/find_all 检索     10. 高级查询: CSS 选择器 ----
    #1.开发前准备 - 官方文档: https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.html 官方文档中文版: https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/ - 命令安装方式 pip install beautifulsoup4 easy_install beautifulsoup4 下载源码包(tar.gz)安装 python setup.py install - 安装解析器: BeautifulSoup4 本身只包含解析器接口规则,支持 python 内置的 HTML 解析器,同时支持第三方的一些解析器[如 lxml] - 如果使用过程中没有指定使用解析器, BeautifulSoup4 会自动从当前的 python 环境中检索最优的解析器加载使用 pip install lxml or pip install html5lib
    #2.不同解析器对比
    解析器 使用 优缺点
    标准库 BeautifulSoup(html, ‘html.parser’) 优点:内置标准库、执行速度适中、容错能力强.
    缺点:对中文解析的容错能力有限
    lxml BeautifulSoup(html, ‘lxml’) 优点:速度快,容错能力强
    缺点:需要安装 c 语言库
    lxml BeautifulSoup(html, [‘lxml’, ‘xml’]) 唯一支持 XML 的解析器
    html5lib BeautifulSoup(html, ‘html5lib’) 优点:容错能力最好, 浏览器方式解析文档, 生成 H5 格式的文档
    缺点:速度慢,不依赖外部扩展
    • 综上所述,优先推荐使用 lxml 解析器

    #3.BeautifulSoup4 初始化和节点对象的认识 - BeautifulSoup4(BS4)可以将一个 html 文档数据流或者 html 文档对象或者 html 字符串,直接加载到 BS4 对象中,得到一个 BS4 的文档对象 --- from bs4 import BeautifulSoup --- soup = BeautifulSoup(open(‘index.html’)) --- soup = BeautifulSoup(‘……’) - BeautifulSoup4 将 HTML 结构化文档, 解析为树形结构化数据,树形文档对象中主要包含四种对象 --- tag: 标签节点对象节点 --- name: 标签名称对象节点 --- attributes: 标签属性对象节点, like dict,如果是多值属性,属性对应的值就是一个 list 数据 --- NavigateString: 标签中文本对象节点,可以直接通过 unicode()函数将文本转换成 unicode 字符串
    #4.BS4 案例操作:初始化对象文档 ```# 目标数据 html_doc = """ The Dormouse's story

    The Dormouse's story

    Once upon a time there were three little sisters; and their names were Elsie, Lacie and Tillie; and they lived at the bottom of a well.

    ...

    """ from bs4 import BeautifulSoup # 构建 bs4 文档对象 soup = BeautifulSoup(html_doc, 'lxml') print(type(soup)) # ```
    #5.节点查询: 子节点 ``` # 节点名称查询 print(soup.title) # The Dormouse's story print(soup.p) #

    The Dormouse's story

    print(soup.a) # Elsie # 子节点查询 chs = soup.contents print(type(chs), len(chs)) # 2 chs2 = soup.children print(type(chs2), len(list(chs2))) # 2 # 包含节点查询 chs3 = soup.descendants print(type(chs3), len(list(chs3))) # 28 # 子节点内容获取 # 获取节点内部文本数据 print(soup.title.string) # The Dormouse's story # 获取文本节点的文本数据 print(soup.title.contents[0].string) # The Dormouse's story # 如果包含子节点并且不是文本节点,返回 None print(soup.body.string) # None # 获取包含的所有文本数据,包括空白字符 print(soup.body.strings) # # 获取包含的所有文本数据,剔除空白字符 print(soup.body.stripped_strings) # ```
    #6.节点查询:父节点 ``` # ##########################父节点查询

    print(soup.a) # Elsie

    查询直接父节点

    print(soup.a.parent.name) # p

    遍历查询所有父节点

    print([tag.name for tag in soup.a.parents]) # ['p', 'body', 'html', '[document]']

    
    <br>
    #7.节点查询: 兄弟节点
    

    ##########################兄弟节点

    获取当前节点

    print(soup.a) # Elsie

    获取前一个兄弟节点:得到文本节点

    print(soup.a.previous_sibling) # Once upon a time there were three little sisters; and their
    names were

    获取后一个兄弟节点:得到文本节点

    print(soup.a.next_sibling) #,

    获取所有的前面的兄弟节点:得到所有紧跟当前节点前面的兄弟节点的生成器对象

    print(soup.a.previous_siblings) # <generator object PageElement.previous_siblings at
    0x000001EF06B57750>

    获取所有的后面的兄弟节点:得到所有紧跟当前节点后面的兄弟节点的生成器对象

    print(soup.a.next_siblings) # <generator object PageElement.next_siblings at 0x0000018A1B41F6D8>

    
    <br>
    #8.节点查询:解析顺序
    BeautifulSoup4 提供了一种比较特殊的操作:按照文档的解析顺序进行节点的查询,解析顺序和浏览器解释 HTML 文档的顺序是一致的
    

    #########################解析顺序节点

    获取当前节点

    print(soup.a) # Elsie

    获取前一个兄弟节点:得到文本节点

    print(soup.a.previous_element) # Once upon a time there were three little sisters; and their
    names were

    获取后一个兄弟节点:得到文本节点

    print(soup.a.next_element) #Elsie

    获取所有的前面的兄弟节点:得到所有紧跟当前节点前面的兄弟节点的生成器对象

    print(soup.a.previous_elements) # <generator object PageElement.previous_elements at
    0x0000013EC8C9F6D8>

    获取所有的后面的兄弟节点:得到所有紧跟当前节点后面的兄弟节点的生成器对象

    print(soup.a.next_elements) # <generator object PageElement.next_elements at 0x0000013EC8C9F6D8>

    获取解析过程节点顺序

    print([tag.name if tag.name else tag for tag in soup.html.next_elements])

    
    ➔ 解析结果:
    

    ['head', 'title', "The Dormouse's story", ' ', 'body', ' ', 'p', 'b', "The Dormouse's story", ' ',
    'p', 'Once upon a time there were three little sisters; and their names were ', 'a', 'Elsie', ', ', 'a',
    'Lacie', ' and ', 'a', 'Tillie', '; and they lived at the bottom of a well.', ' ', 'p', '...', ' ', ' ',
    ' ']

    
    <br>
    #9.高级查询: find/find_all 检索
    -  find(name, attrs, recursive, text, **kwargs)
    ◼ 查询得到一个节点对象数据,如果结果不存在返回 None
    ◼ param name: 要查询的标签的名称
    ◼ param attrs: 要查询的属性字典,如{‘class’: ‘title’}
    ◼ param recursive: 是否查询所有包含的节点,默认 True
    ◼ param text: 查询的节点中包含的指定的内容
    ◼ param kwargs: 如果查询的属性不是内置的指定的属性,可以通过 kwargs 添加自定义属性
    -  find_all(name, attrs, recursive, text, limit, **kwargs)
    ◼ 查询得到一组节点对象数据,如果结果不存在返回[]
    ◼ param limit:查询的结果数量限制
    ◼ 其他参数参考 find(..)
    -  查询过滤操作
    ◼ 条件查询: find_all(‘p’, {‘class’: ‘title’})
    ◼ 并且查询: find_all([‘p’, ‘a’])
    ◼ 属性查询: find_all(id=’link2’)
    ◼ 正则查询: find_all(text=re.compile(‘sisters’))
    ◼ 指定属性查询: find_all(class_=’sister’)
    -  其他查询
    ◼ find_parent()/find_parents()
    ◼ find_previous_sibling()/find_previous_siblings()/find_next_sibling()/find_next_siblings()
    ◼ find_next()/find_all_next()/find_previous()/find_all_previous()
    
    <br>
    #10. 高级查询: CSS 选择器
    -  beautifulsoup.select(css syntax)
    

    ##########################css 查询

    print(soup.select("title")) # 标签选择器
    print(soup.select("#link1")) # id 选择器
    print(soup.select(".sister")) # class 选择器
    print(soup.select("p > a")) # 子类选择器
    print(soup.select("p a")) # 包含选择器
    print(soup.select("p, a, b")) # 群组选择器
    print(soup.select("#link1 ~ .sister")) # 兄弟选择器
    print(soup.select("#link1 + .sister")) # 兄弟选择器
    print(soup.select("p[class='title']")) # 属性选择器
    print(soup.select("a:nth-of-type(2)")) # 伪类选择器

  • 相关阅读:
    LeetCode做题笔记(4)——error: variable-sized object may not be initialized|
    LeetCode做题笔记(3)——if嵌套if时不加花括号{}导致的bug
    LeetCode做题笔记(2)——使用动态内存分配定义一个二维数组
    数组的初始化
    LeetCode做题笔记(1)——二维数组及qsort的compar函数写法详解
    FreeRTOS 在Tricore上的三种任务切换方式
    FreeRTOS 就绪任务列表与延时任务列表(阻塞态到就绪态的转移原理)
    FreeRTOS vTaskDelay(相对延时)和vTaskDelayUntil(绝对延时)的区别及使用方法
    FreeRTOS 互斥信号量(Mutex)与二值信号量(Binary)的区别
    微信小程序函数间传递url的参数丢失问题
  • 原文地址:https://www.cnblogs.com/wqunlong/p/10048832.html
Copyright © 2020-2023  润新知