zoukankan      html  css  js  c++  java
  • 爬虫 >>> BeautifulSoup 模块

    Beautiful Soup 解析库

      简称BS4;是一个可以从 HTML 或 XML 文件中提取数据的 python 库。

    中文文档

      https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

    安装

      pip3 install beautifulsoup4

    安装解析器

    # 官网推荐使用。因为效率更高(速度快, 文档容错能力强)
    # 容错处理,文档的容错能力指的是在 html 代码不完整的情况下,使用该模块可以识别该错误
    # 并能按照标准的缩进格式的结构输出
    pip3 install lxml  

     基本使用

      遍历文档树

        直接通过标签名字选择:速度快,存在多个相同的标签则只返回第一个

    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup('要解析的内容', '解析器(一般使用"lxml")')
    
    # 1:美化作用(帮助我们处理好缩进,结构化显示)
    soup = soup.prettufy()  
    
    # 2:获取标签
    soup.p  # ---> soup 内的 p 标签;存在多个相同的标签则只返回第一个
    soup.a  # ---> soup 内的 a 标签;存在多个相同的标签则只返回第一个
    
    # 2:获取标签名称
    soup.p.name  # ---> 结果为 p 
    
    # 3:获取标签内的属性
    soup.p.attrs  # ---> p 标签内有多少属性都会以字典的形式返回(包括自定义属性)
    
    # 4:获取标签内容
    soup.p.string   # ---> p 标签下面文本只有一个时候可以取到,否则为 None
    soup.p.strings  # ---> 拿到一个生成器对象 generater, 取到 p 下的而所有文本内容
    soup.p.text  # ---> 取到 p 下所有的文本内容
    for line in soup.stripped_strings:  # 去掉空白
        print(line)
        
    # 5:嵌套选择
    soup.head.title.string  # ---> head 标签下 title 标签内的内容
    
    # 6:子节点、子孙节点
    soup.p.contents  # ---> p 下所有子节点
    soup.p.children  # ---> 得到一个迭代器,包含 p 下面所有的子节点
    soup.p.descendants  # ---> 获取子孙节点,p 下所有的标签都会被选择出来
    
    # 7:父节点、祖父节点
    soup.a.parent  # 获取 a 标签的父节点
    soup.a.parents  # 找到 a 标签所有的祖父节点,父亲的父亲...
    
    # 8:兄弟节点
    soup.a.next_sibling  # 下一个兄弟
    soup.a.next_siblings  # 下面的兄弟们(生成器对象)
    soup.a.previous_sibling  # 上一个兄弟
    soup.a.previous_siblings  # 上面的兄弟们(生成器对象)

       搜索文档树

    # find 与 find_all
    '''
    区别是 find_all() 方法的返回结果是值包含一个元素的列表
    而 find() 方法直接返回结果
    
    find_all() 方法没有找到目标是返回空列表
    find() 方法找不到目标时,返回 None 
    '''
    
    
    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup('文档内容', 'lxml')
    
    # 1:五中过滤器 ---> 字符串、正则表达式、列表、布尔值、方法
    # 1.1:字符串(字符串代表标签名)
    soup.find_all('b')  # 搜索所有的 b 标签
    
    # 1.2:正则表达式
    import re
    soup.find_all(re.compile('^b'))  # 找出所有 b 开头的标签;如 body, b 标签
    
    # 1.3:列表
    soup.find_all(['a', 'b'])  # 与列表中任一元素匹配的内容返回
    
    # 1.4:布尔值
    soup.find_all(True)  # 可以匹配任何值,查找到所有的tag, 但是不会返回字符串节点
    
    # 1.5:方法
        # 先定义一个方法:方法只接受一个元素参数。
        # 如果这个方法返回 True 表示当前元素匹配并且被找到,如果不是则反回 False
    def has_class_but_no_id(tag):  
        return tag.has_attr('class') and not tag.has_attr('id')
    
    soup.find_all(has_class_but_no_id)  # 传入方法名
    
    
    
    
    # 2、find_all( name , attrs , recursive , text , **kwargs )
    # 2.1、name: 搜索name参数的值可以使任一类型的 过滤器 ,字符窜,正则表达式,列表,方法或是 True .
    print(soup.find_all(name=re.compile('^t')))
    
    # 2.2、keyword: key=value的形式,value可以是过滤器:字符串 , 正则表达式 , 列表, True .
    print(soup.find_all(id=re.compile('my')))
    print(soup.find_all(href=re.compile('lacie'), id=re.compile('d')))  # 注意类要用class_
    print(soup.find_all(id=True))  # 查找有id属性的标签
    
    # 有些tag属性在搜索不能使用,比如HTML5中的 data-* 属性:
    data_soup = BeautifulSoup('<div data-foo="value">foo!</div>', 'lxml')
    # data_soup.find_all(data-foo="value") 
    #报错:SyntaxError: keyword can't be an expression
    # 但是可以通过 find_all() 方法的 attrs 参数定义一个字典参数来搜索包含特殊属性的tag:
    print(data_soup.find_all(attrs={"data-foo": "value"}))
    # [<div data-foo="value">foo!</div>]
    
    # 2.3、按照类名查找,注意关键字是class_,class_=value,value可以是五种选择器之一
    print(soup.find_all('a', class_='sister'))  # 查找类为sister的a标签
    print(soup.find_all('a', class_='sister ssss'))  # 查找类为sister和sss的a标签,顺序错误也匹配不成功
    print(soup.find_all(class_=re.compile('^sis')))  # 查找类为sister的所有标签
    
    # 2.4、attrs
    print(soup.find_all('p', attrs={'class': 'story'}))
    
    # 2.5、text: 值可以是:字符,列表,True,正则
    print(soup.find_all(text='Elsie'))
    print(soup.find_all('a', text='Elsie'))
    
    # 2.6、limit参数:如果文档树很大那么搜索会很慢.如果我们不需要全部结果,可以使用 limit 参数限制返回结果的数量.
    # 效果与SQL中的limit关键字类似,当搜索到的结果数量达到 limit 的限制时,就停止搜索返回结果
    print(soup.find_all('a', limit=2)) # 2.7、recursive:调用tag的 find_all() 方法时,Beautiful Soup会检索当前tag的所有子孙节点
    # 如果 只想搜索tag的直接子节点,可以使用参数 recursive=False .
    print(soup.html.find_all('a')) print(soup.html.find_all('a', recursive=False)) ''' 像调用 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)
    ''' # 3:CSS选择器 from bs4 import BeautifulSoup soup = BeautifulSoup('dfjeisdf,'lxml') # 3.1、选择标签 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就可以了 # 3.2、获取属性 print(soup.select('#list-2 h1')[0].attrs) # 3.3、获取内容 print(soup.select('#list-2 h1')[0].get_text())

       总结

    # 1、推荐使用lxml解析库
    
    # 2、三种选择器:标签选择器,find与find_all,css选择器
    '''
        1、标签选择器筛选功能弱,但是速度快
        2、建议使用 find, find_all 查询匹配单个结果或者多个结果
        3、如果对 css 选择器非常熟悉建议使用 select
    '''
       
    # 3、记住常用的 获取属性 attrs文本值 get_text() 的方法
  • 相关阅读:
    记 · 佛系青年 · 嗯我百度了下
    【CSS】452- 浏览器解析 CSS 样式的过程
    记 · 平安夜 · 平安平安平安
    【Vuejs】451- Vue CLI 首屏优化技巧
    【网站发布】前端自习课
    【CSS】450- 温故而知我不懂的CSS
    【CSS】449- CSS第四级选择器
    RabbitDemo —— Topic
    RabbitDemo —— Fanout
    RabbitDemo —— Direct
  • 原文地址:https://www.cnblogs.com/pupy/p/11989674.html
Copyright © 2011-2022 走看看