BeautifulSoup基本使用

作者: 圆圆KK | 来源:发表于2019-03-17 18:45 被阅读5次

    BeautifulSoup官方文档介绍:BeautifulSoup 是一个可以从HTML或XML文件中提取数据的Python库。使用BeautifulSoup更多方便,避免使用正则表达式容易出错,提高效率。

    1.解析器

    BeautifulSoup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,其中一个是 lxml。以下为BeautifulSoup官方文档对支持的解析器优缺点对比。

    解析器 使用方法 优势 劣势
    Python标准库 BeautifulSoup(markup, "html.parser") Python的内置标准库、执行速度适中 、文档容错能力强 Python 2.7.3 or 3.2.2)前的版本中文容错能力差
    LXML HTML 解析器 BeautifulSoup(markup, "lxml") 速度快、文档容错能力强 需要安装C语言库
    LXML XML 解析器 BeautifulSoup(markup, "xml") 速度快、唯一支持XML的解析器 需要安装C语言库
    html5lib BeautifulSoup(markup, "html5lib") 最好的容错性、以浏览器的方式解析文档、生成 HTML5 格式的文档 速度慢、不依赖外部扩展

    推荐使用lxml解释器,效率更高。注意:不同的解析器返回不同的结果

    2.基本使用

    通过解析器,BeautifulSoup可以传入一段字符串或文件。

    from bs4 import BeautifulSoup
    >>> soup = BeautifulSoup("<html>data</html>")
    >>> print(soup.html.string)
    data
    

    Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment。接下来使用以下文档进行说明。

    html_doc = """
    <html><head><title>The Dormouse's story</title></head>
    
    <p class="title"><b>The Dormouse's story</b></p>
    
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1">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>
    """
    soup = BeautifulSoup(html_doc, 'lxml')
    print(soup.prettify())
    
    • tag
      通俗来说tag就是HTML或XML文档的标签,例如上面文档的head、title、p等,如果想获取 <head> 标签,只要用 soup.head。
    >>> soup.head 
    <head><title>The Dormouse's story</title></head>
    >>> soup.body.b
    <b>The Dormouse's story</b>
    >>> soup.a
    <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
    

    可以看到a点只是返回第一个,如果需要历遍全部则需要用find_all('a')。
    tag有多种属性,其中两个最重要的就是name和attributes。name一般返回标签本身(soup返回document),注意,tag属性操作方法和字典一样。

    >>> soup.name 
    '[document]' #soup比较特殊,返回name为[doucument]
    >>> soup.p.name
    p 
    >>> soup.p.attrs
    {'class': ['title']}
    >>> soup.p['class'] #可以直接修改属性soup.p['class'] = 'a'
    ['title']
    
    • NavigableString
      NavigableString就是tag标签内的内容,可以直接使用string获得内容,replace_with()进行替换。
    >>> soup.p.string
    "The Dormouse's story"
    >>> soup.p.string.replace_with("no")
    >>> soup.p.string
    'no'
    
    • BeautifulSoup
      BeautifulSoup表示一个文档的全部内容。
    • comment
      Comment 对象是一个特殊类型的NavigableString对象,针对注释部分,输出不包括注释符号。
    >>> markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
    >>> soup = BeautifulSoup(markup)
    >>> soup.b.string
    'Hey, buddy. Want to buy a used parser?'
    >>> type(soup.b.string)
    bs4.element.Comment
    
    3.节点选择

    上面说到节点选择可以直接利用标签,如<head>标签用soup.head,也可通过name和attrs可以直接获取属性,操作和字典一样。以上是直接获取的方式,当想要获取标签的子节点、父节点、兄弟节点则需要通过另外的方法。

    选择 方法
    直接节点 .contents和.children(生成器)
    子孙节点 .descendants(生成器)
    节点内容 .strings和.stripped_strings(去除空格和空行)
    父节点 .parent和.parents(到根节点)
    兄弟节点 .next_element(s) 和 .previous_element(s)
    • 直接子节点.contents 和 .children,子孙节点.descendants
      .contents输出方式为列表,可以通过列表索引获取某一元素。
    >>> len(soup.head.contents)
    1 
    >>> soup.head.contents
    [<title>The Dormouse's story</title>]
    >>> soup.head.contents[0]
    <title>The Dormouse's story</title>
    

    .children是一个llist生成器,可以对子节点进行历遍循环

    >>> soup.body.children
    <list_iterator at 0x19e8183a860>
    >>> for child in soup.body.children:
    >>>    print(child)
    

    .descendants是返回所有子孙节点,比较children和descendants的输出区别

    >>> len(list(soup.body.descendants))
    19
    >>> len(list(soup.body.children))
    6
    >>> for child in soup.body.descendants:
    >>>    print(child)
    
    • 节点内容.strings 和 stripped_strings
      上面基本使用说到可以使用string获得节点内容,当含有多个字符串时可以用到.string循环;当字符串含有很多空格和空行,可以用到stripped_strings去除。
    >>> for string in soup.stripped_strings:
    >>>    print(string)
    
    • 父节点.parent和.parents
      .parent是返回父节点,.parents是返回到根标签的所有节点,注意根节点<html>的父节点是BeautifulSoup 对象,BeautifulSoup 对象的父节点是None。
    >>> soup.a.parent.name
    'p'
    >>> for parent in soup.a.parents:
    >>>    if parent is None:
    >>>        print(parent)
    >>>    else:
    >>>        print(parent.name)
    p
    body
    html
    [document]
    
    • 兄弟节点.next_element和 .previous_element / .next_elements和 .previous_elements
      .next_element 指向当前被解析的对象的下一个解析对象, .previous_elements当前被解析的对象的前一个解析对象。
    4.搜索文档树
    • find_all

    find_all( name , attrs , recursive , text , **kwargs )

    • 解释
      • name参数可以传入标签名称、正则表达式、列表。
      • text 参数接受 字符串 , 正则表达式 , 列表, True。
    >>> soup.find_all('a', id="link2")
    >>> soup.find_all(['a','b'])
    

    相关文章

      网友评论

        本文标题:BeautifulSoup基本使用

        本文链接:https://www.haomeiwen.com/subject/twktmqtx.html