zoukankan      html  css  js  c++  java
  • 强大的BeautifulSoup

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库·它能够通过你喜欢的转换器实现惯用的文档导航

    安装BeautifulSoup

    • 推荐使用Beautiful Soup 4,已经移植到BS4中,Beautiful Soup 3已经停止开发了,下面是安装步骤:
      • 如果使用新版的Debain或Ubuntu,可以通过系统软件包管理来安装:apt-get install Python-bs4
      • Beautiful Soup 4通过Pipy发布,可以通过pip安装:pip install beautiful
      • 下载源码安装:https://pypi.org/project/beautifulsoup4/,进入文件夹,运行 python setup.py install

    BeautifulSoup 的使用

    1 快速开始

    • 导入bs4库:from bs4 import BeautifulSoup 的使用

    • 创建BeautifulSoup对象,创建BeautifulSoup对象有种方式,

      • 通过字符串创建:
        soup = BeautifulSoup(html_str,'lxml',from_encoding='utf-8')
    
    
    - 通过文件来创建:
    
        soup = BeautifulSoup(open('index.html'))
    

    文档被转化成Unicode,并且HTML的实例都被转化成Unicode编码。打印soup对象内容,格式化输出

    print soup.prettify()
    
    • Beautiful Soup 会选择合适的解析器来解析这段文档,如果手动解析就要指定解析器解析。

    • BeautifulSoup支持Python标准库的HTML解析器,还支持一些第三方的解析器:lxml、html5lib

      • lxml(需要安装c语言库,分为lxml HTML解析器和lxml XML 解析器)解析速度要比标准库中的HTML解析速度快,安装:pip install lxml或者apt install Python-lxml
      • 纯python实现的html5lib(速度慢),安装:pip install html5lib或者apt install Python-html5lib

    推荐使用lxml作为解释器

    2 对象种类

    • BeautifulSoup将复杂HTML文档转换换成一个复杂的树形结构,每个节点都是Python对象,对象可以分为4种:

      • Tag
      • NavigablString
      • BeautifulSoup
      • Comment
    • Tag对象就相当于HTML原生文档中的Tag,通俗就是标记。下面就是怎么在HTML抽取Tag:

      • 抽取title:print soup.title
      • 抽取a:print soup.a
      • 抽取p:print soup.p

    soup对象本身比较特殊,他的name为[document],对于其他内部标记,输出的值变为标机本身的名称。Tag不仅可以可以获取name,还可以修改name,改变之后将影响所有通过当前BeautifulSoup对象生成HTML文档。

    soup.title.name = 'mytitle'
    print soup.title
    print soup.mytitle
    
    运行结果:
    None
    <mytitle>.......</mytitle>
    

    3 NavigableString

    • 我们已经得到标记的内容,想要获取标记文字怎么办,需要用到.string
    print soup.p.string
    print type(soup.p.string)
    

    BeautifulSoup 用NavigableString类包装Tag中的字符串,一个NavigableString字符串与python中Unicode字符串相同,通过Unicode()方法可以直接将NavigableString对象转换成Unicode字符串

    unicode_string = unicode(soup.p.string)
    
    • BeautifulSoup对象表示一个文档的全部内容。大部分可以把他当做Tag对象,是一个T特殊的Tag,因为BeautifulSoup对象并不是真正的HTML或者XML的标记。所以它没有name和attribute属性:
    print type(soup.name)
    print soup.name
    print soup.attrs
    
    运行结果:
    <type 'unicode'>
    [document]
    {}
    
    • Coment一些特殊对象。比如是文档注释部分:
      print soup.a.string
      print type(soup.a.string)

    a标记里的内容实际是注释,如果用.string输出内容的话,会发现已经把注释符号去掉了。如果我们不清楚这个标记.string的情况下,可能造成数据混乱。因此提取字符串时:

    if type(soup.a.string)==bs4.element.Comment:
        print soup.a.string
    

    4 遍历文档树

    • BeautifulSoup会将HTML转化为文档进行搜索,树形结构,

      • 子节点
      • 父节点
      • 兄弟节点
      • 前后节点

    详细:[https://wizardforcel.gitbooks.io/bs4-doc/content/6.html]https://wizardforcel.gitbooks.io/bs4-doc/content/6.html

    5 搜索文档树

    • BeautifulSoup定义了很多搜索方法,着重介绍find_all()方法

    • find_all( name , attrs , recursive , string , **kwargs )

    • find_all() 方法搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件

    • name 参数:

      • 可以查找所有名字为name的标记,字符串会自动忽略。name参数取值可以字符串、正则表达式、列表、True和方法
      • 比如查找文档中文档所的标记,返回值为列表:'print soup.find_all('b')'
      • 如果传入的是列表参数,那会返回列表中任一元素匹配的内容返回:'print soup.find_all('b',‘b’)'
      • 传入True,True可以匹配任何值,下面代码查看到所有的tag,但是不会返回字符串节点:
      • for tag in soup.find_all(True):
            print tag.name
        
    • kwargs 参数在python中表示为keyword参数,如果指定一个名字参数不是搜索内置的参数名,搜索时把该参数当做指定名字Tag的属性来搜索。搜索指定名字的属性可以使用的参数值包括字符串、正则表达式、列表、True。

      • 比如包含id参数,要搜索每个tag的“id”属性:print soup.fina_all(id='link2')
    • 可以指定多个名字的参数也可以同时过滤tag多个属性:

    print soup.find_all(href=re.compile("elsie"),id="link1")
    
    • attrs ,如果搜索包含特殊属性的tag,用到attrs:
    data_soup = BeautifulSoup('<div data-foo="value">fool</div>')
    data_soup.find_all(attrs={"data-foo":"value"})
    
    
    • text 参数:通过text参数搜索文档中的字符串内容,与name参数可选值一样,text参数接收字符串、正则表达式、列表、True:
    print soup.find_all(text="Elsie")
    print soup.find_all(text={"Tillie","Elsie","Lacie"})
    print soup.find_all(text=re.compile("Dormouse"))
    
    
    • limit参数
      • find_all返回 全部的搜索结果,如果文档很大,搜索很慢,我们不需要那么多,就可以用他限制返回数量。当搜索结果达到limit值,就停止搜索:
        print soup.find_all("a",limit=2)
    
    • recursive参数
      • 调用tag的find_all()方法时,Beautiful soup会检索当前tag所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数recursive=False
        print soup.find_all("title")
        print soup.find_all("title",recursive=False)
    

    CSS选择器

    • web前端通过类名前加.,id名前加#,就可以定位元素的位置。同样,可以用类似的方法筛选元素,用到的方法是soup.select(),返回的类型是list

    • 1通过标记名称可以直接查找,逐层查找,也可以找到某个标记下的直接子标记和兄弟节点标记:

    
    #直接查找title标签
    print soup.select("title")
    #逐层查找title标签
    print soup.select("html head title")
    #查找直接子节点
    #查找head下的title标签
    print soup.select("head > title")
    #查找p下的id="link1"的标签
    print soup.select("p > #link1")
    #查找兄弟节点
    #查找id="link1"之后class=sisiter的所有兄弟标签
    print soup.select("#link1 ~ .sister")
    #查找紧跟着id="link1"之后class=sisiter的子标签
    print soup.select("#link1 + .sister")
    
    • 2 通过css的类名查找
    print soup.select(".sister")
    print soup.select("[class~=sister]")
    
    
    • 3 通过tag的id查找
    
    print soup.select("#link1")
    print soup.select("a#link2")
    
    
    • 4 通过是否存在某个属性来查找
    print soup.select('a[href]')
    
    
    • 5 通过属性值来查找
    print soup.select('a[href="http://example.com/elsie"]')
    print soup.select('a[href^="http://example.com/"]')
    print soup.select('a[href$="tillie"]')
    print soup.select('a[href*=".com/el"]')
    
  • 相关阅读:
    Python入门教程 超详细1小时学会Python
    K最近邻(KNN,k-Nearest Neighbor)准确理解
    K最近邻(KNN,k-Nearest Neighbor)准确理解
    如何区分数据科学家,数据工程师与数据分析师
    如何区分数据科学家,数据工程师与数据分析师
    【BZOJ】1003 Cards
    TinySpring分析二
    Tomcat 系统架构与设计模式,第 1 部分: 工作原理
    MySQL中使用INNER JOIN来实现Intersect并集操作
    jqPaginator-master | kkpager-master 这两个分页插件的使用方法
  • 原文地址:https://www.cnblogs.com/guguobao/p/9426469.html
Copyright © 2011-2022 走看看