zoukankan      html  css  js  c++  java
  • 【Python爬虫学习笔记5】Beautiful Soup库

    Beautiful Soup 和 lxml 一样,是Python的一个HTML/XML的解析库,它可以借助网页的结构和属性等特性来解析网页。它和lxml有相当的功能,也有着不同之处:lxml只会局部遍历,而Beautiful Soup 是基于HTML DOM(Document Object Model)的,会载入整个文档来解析DOM树,因此时间和内存开销都会大很多,性能要低于lxml。

    如下为一个解析器对比(包含正则):

    解析工具 解析速度 使用难度
    Beautiful Soup 最慢 最简单
    lxml 简单
    正则 最快 最难

    即便如此,Beautiful Soup 的解析使用相对简单,其API非常人性化,支持CSS选择器、Python标准库HTML解析器,同时也支持 lxml 的 XML解析器,甚至容错性最好的html5lib解析器。所以说,利用好Beautiful Soup可以省去很多工作,提高解析效率。

    安装方法

    使用pip进行安装:pip install bs4

    基本使用

    1.使用基础

    使用前需要先导入BeautifulSoup模块(属于bs4库),然后使用Beautiful(html,parse)实例化对象,传入的参数分别为待解析的html源码文本和解析器种类(如lxml,html.parse,xml或html5lib)。当实例化对象soup后,接下来就可以调用其各个方法和属性解析HTML代码了。

    html = """
    <table class="tablelist" cellpadding="0" cellspacing="0"><tbody>
                    <tr class="even">
                        <td class="l square"><a target="_blank" href="position_detail.php?id=44279&amp;keywords=python&amp;tid=0&amp;lid=0">28607-113 微信支付大数据平台开发工程师(深圳)</a></td>
                        <td>技术类</td>
                        <td>1</td>
                        <td>深圳</td>
                        <td>2018-09-18</td>
                    </tr>
                    <tr class="odd">
                        <td class="l square"><a target="_blank" href="position_detail.php?id=44274&amp;keywords=python&amp;tid=0&amp;lid=0">OMG097-自然语言处理工程师(北京)</a></td>
                        <td>技术类</td>
                        <td>3</td>
                        <td>北京</td>
                        <td>2018-09-18</td>
                    </tr>
                    <tr class="even">
                        <td class="l square"><a target="_blank" href="position_detail.php?id=44263&amp;keywords=python&amp;tid=0&amp;lid=0">18428-银行业务测试工程师(深圳)</a><span class="hot">&nbsp;</span></td>
                        <td>技术类</td>
                        <td>1</td>
                        <td>深圳</td>
                        <td>2018-09-18</td>
                    </tr>
    </tbody></table>
    """
    ##前期准备
    from bs4 import BeautifulSoup
    
    # 实例化对象
    soup = BeautifulSoup(html, 'lxml')
    # 美观地输出HTML源代码文本print
    (bs.prettify())

    2.find()与find_all()方法

    这两个都是Soup解析方法中较为常用的用于检索获取特定节点的方法,其中find()方法用于获取一个节点,返回值为单个的Tag标签(如果存在,否则为None,当有多个满足时只返回第一个),而find_all()则是在find()的基础上返回所有符合条件的节点列表(没有满足的情况下返回空列表[])。

    通常情况下,find_all()用得更为频繁,基本语法为:object = soup.find_all(Tag),下面以一系列示例来说明其用法。

    ##使用find_all()检索获取节点标签
    from bs4 import BeautifulSoup
    html="""如上示例"""
    soup = BeautifulSoup(html, 'lxml')
    
    # 示例1——获取所有tr标签
    trs = soup.find_all('tr')
    for tr in trs:
        print(type(tr))    #<class 'bs4.element.Tag'>
        print(tr)
    
    # 示例2——获取第2个tr标签
    tr = soup.find_all('tr',limit=2)[1]        #参数limit用于限制返回个数为2个,由于是列表结构,第二个下标为1
    print(tr)
    
    # 示例3——获取所有class为even的tr标签
    trs = soup.find_all('tr',attrs={'class':'even'})    #参数attrs用于属性过滤
    
    # 示例4——将所有id等于test,class也等于test的a标签提取出来
    aList = soup.find_all('a',attrs={'class':'test','id':'test'})
    
    # 示例5——获取所有a标签的href属性
    aList = soup.find_all('a')
    for a in aList:
        href = a['href']    # 或href = a.attrs['href'],attrs为其属性字典
        print(href)

    3.select()方法

    此方法为CSS选择器方法,即通过元素CSS选择表达式来筛选符合条件的节点,其返回的也是为一个列表。使用此方法前需要对CSS有一定的了解,在爬虫中我们只需要掌握以下几类基本的用法即可,其他具体的可以查阅相关网络资料(比如,http://www.w3school.com.cn/cssref/css_selectors.ASP)

    选择器 构成法 使用说明 示例 描述
    通过标签名选择 tag 直接输入待选择的标签名 div 选择所有的div标签
    通过类名选择 .class 在类名前面加一个. p.text 选择所有类为text的p标签
    通过id选择 #id 在id名前加一个#号 #username 选择id为username的标签
    组合选择1(全局选择)   将多个选择器方法叠加一起,同时用空格分开 p #poster 选择id为poster的p标签
    组合选择2(特定选择)   当需要使用组合来选择直接子节点时,需要用’>’连接 div > input 选择div下的直接input标签
    通过属性选择 [attrs=value] 通过在[]中指定属性表达式来选择,但不适用多属性 a[id=”link”] 选择id为link的a标签

    在熟悉CSS选择器基本语法规则后,我们便可以通过soup的select(选择表达式)方法来获取相应的节点标签了。以上的 select 方法返回的结果都是列表形式,可以遍历或通过下标获取节点元素,然后用使用 get_text()(返回子孙非标签字符串) 方法来获取其文本内容。

    下面仍以上述html代码为例,介绍select()的使用方法。

    ##使用select()方法检索获取节点
    from bs4 import BeautifulSoup
    html="""如上示例"""
    soup = BeautifulSoup(html, 'lxml')
    
    # 示例1——获取所有tr标签
    trs = soup.select('tr')
    for tr in trs:
        print(tr)
    
    # 示例2——获取第2个tr标签
    tr = soup.select('tr')[1]
    print(tr)
    
    # 示例3——获取所有class为even的tr标签
    trs = soup.select('tr[class="even"]')
    for tr in trs:
        print(tr)
    
    # 示例4——将所有id等于test,class也等于test的a标签提取出来
    #由于CSS选择器无法直接选取同时满足两种条件的标签,故此目标无法完成,但可以通过二次选择来获取
    
    # 示例5——获取所有a标签的href属性
    aList= soup.select('a')
    for a in aList:
        href = a['href']
        print(href)

    4.获取文本内容

    在soup获取后的节点对象中,如要获取其文本内容,除了上文中提到的get_text()方法外,还可以使用如下的属性:

    (1)string:获取某个标签下的非标签字符串,返回的为字符串。

    (2)strings:获取某个标签下的子孙非标签字符串,返回的为生成器。

    (3)stripped_string:获取某个标签下的子孙非标签字符串,会去掉空白字符,返回的为生成器。

    仍以上述为例,使用示例如下:

    ##获取文本内容
    tr2 = soup.select('tr')[1]
    
    # 获取非标签字符串
    print(tr2.string)    #None
    
    # 获取子孙非标签字符串
    print(list(tr2.strings))    #['
    ', 'OMG097-自然语言处理工程师(北京)', '
    ', '技术类', '
    ', '3', '
    ', '北京', '
    ', '2018-09-18', '
    ']
    
    # 获取除去空白的子孙非标签字符串
    print(list(tr2.stripped_strings))    #['OMG097-自然语言处理工程师(北京)', '技术类', '3', '北京', '2018-09-18']
    
    # 获取子孙非标签字符串,以普通字符串形式返回
    print(tr2.get_text())
    """
    Output:
    
    OMG097-自然语言处理工程师(北京)
    技术类
    3
    北京
    2018-09-18
    
    """

    补充内容

    1.Beautiful Soup中四个常用对象:

    (1)Tag

    即HTML中的一个个节点标签,如head、body、title、div、p和input等等。

    (2)NavigatableString

    获取标签后,我们利用其属性(如string属性)从标签得到它的内容所返回的这个对象就时NavigatableString。

    (3)BeautifulSoup

    BeautifulSoup 对象表示的是一个文档的全部内容,大部分时候可以把它当作 Tag 对象,其支持遍历文档树和搜索文档树中描述的大部分的方法,比如我们之前使用soup就是这种对象。

    (4)Comment

    Tag , NavigableString , BeautifulSoup 几乎覆盖了html和xml中的所有内容,但是有一类特殊对象——注释,而Comment就是用于获取这些内容的对象。实际上,Comment 对象是一个特殊的 NavigableString 对象。

    html = "<p><!--Hello World--></p>"
    soup = BeautifulSoup(html)
    comment = soup.b.string
    print(comment)    # ‘Hello World’

    2.contents和children属性遍历文档树

    在我们获取标签节点后,还可以通过contents和children两个属性来获取其下的子节点,二者的区别在于contents返回所有子节点列表,而children返回的是一个迭代器。

    tr2 = soup.find_all('tr')[1]
    
    # 返回所有子节点的列表
    print(tr2.contents)
    """
    Output:
    ['
    ', <td class="l square"><a href="position_detail.php?id=44274&amp;keywords=python&amp;tid=0&amp;lid=0" target="_blank">OMG097-自然语言处理工程师(北京)</a></td>, '
    ', <td>技术类</td>, '
    ', <td>3</td>, '
    ', <td>北京</td>, '
    ', <td>2018-09-18</td>, '
    ']
    """
    
    # 返回所有子节点的迭代器
    print(tr2.children)
    """
    Output:
    <list_iterator object at 0x00000224FFF01518>
    """

  • 相关阅读:
    Django models中的null和blank的区别
    微服务
    幂等性
    restful规范
    related_name
    数据库 引擎,数据类型,约束
    数据库 基本操作
    python 常见算法
    python if,循环的练习
    python数据类型、if判断语句
  • 原文地址:https://www.cnblogs.com/Unikfox/p/9676177.html
Copyright © 2011-2022 走看看