beautifulsoup解析库

上一篇记叙了xpath解析库的基本使用,这一篇整理一下Beautifulsoup这个解析库。依旧是菜,若有错误的地方,欢迎大家随时指正。。。。。。。(conme on.......)

首先,还是先来当以那个html字符串

html = '''
<div id="container">
    <ul class="list">
         <li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
     <ul class="list">
         <li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
 </div>
'''
View Code

Beautiful Soup:简单来说,Beautiful Soup就是Python的一个HTML或XML的解析库,可以用它来方便地从网页中提取数据。Beautiful Soup在解析时实际上依赖解析器,它除了支持Python标准库中的HTML解析器外,还支持一些第三方解析器(比如lxml)。下面是一些常见的解析器

然后,再来看一下beautiful soup的四种对象,因为下面的方法,只要是这四种对象里面的,都可以使用。

tag:HTML 中的一个个标签,两个重要的属性,name 和 attrs :
NavigableString:得到了标签的内容用 .string 即可获取标签内部的文字,会输出注释
BeautifulSoup:BeautifulSoup 对象表示的是一个文档的全部内容,是一个特殊的 Tag
Comment:Comment 对象是一个特殊类型的 NavigableString 对象,不会输出注释

(1):建立文档树:首先,需要导入Beautifulsoup库,然后把获取到的html和喜欢用的解析器传进去就可以了。

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')

 

(2) 节点选择器:直接调用节点的名称就可以选择节点元素,再调用string属性就可以得到节点内的文本了。像这样

 

1 soup = BeautifulSoup(html, 'lxml')
2 li = soup.li
3 print(li.string)

输出结果如下:
first ite

 

节点选择器,只能找到第一个节点,然后就不再继续向下寻找了,使用string方法获取第一个li节点的文本内容。

(3)方法选择器:这是重点,方法选择器可以帮助我们快速获取到需要的那部分信息,并且可以根据属性进行过滤。这里主要说一下find和find_all方法,下面方法适用于find和find_all,find_all表示找到所有符合条件的标签,find则表示找到第一个符合条件的标签,同样返回一个列表。

1 soup = BeautifulSoup(html, 'lxml')
2 ul_list = soup.find_all(name='ul', attrs={'class': 'list'})
3 print(ul_list)

输出如内容如下:
[<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>, <ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>]

 

上面第二行代码,表示找到所有标签名是ul,并且class属性为list的标签,如果不需要根据标签属性进行过滤,把后面的attrs={'class': 'list'}去掉即可,可以看到,它的返回结果是一个列表,里面每个元素的内容就是ul标签的内容,这点相对xpath来说更加直观,如果只要找到第一个符合条件的标签,那么只需要把find_all换成find就行了,当然,也可以对这个返回的列表进行遍历,然后依次对列表里的每个元素进行二次操作。

(4)根据标签文本进行选择:find_all方法中有一个text的参数,可以根据标签的文本内容进行选择,传入的形式可以是字符串,可以是正则表达式对象,

 

1 soup = BeautifulSoup(html, 'lxml')
2 result = soup.find_all(text='first item')
3 print(result)

输出结果如下:
['first item', 'first item'

 

 

 

这里我们直接传入的是字符串,返回结果直接是标签的文本内容,这样,我们就可以找到有多少个文本内容与之相同的标签了。如果我们传入的是一个正则表达式,则返回的就是所有符合这个表达式的标签内容。

(5)找到所有子标签:再对列表里的每个元素进行遍历时,我们可以对当前元素(这里是一个ul标签)再次利用此方法。获取标签里面的内容

 

1 soup = BeautifulSoup(html, 'lxml')
2 ul_list = soup.find_all(name='ul', attrs={'class': 'list'})
3 for ul in ul_list:
4     li_list = ul.find_all(name='li')
5     print(li_list)

输出结果如下:
[<li class="item-0">first item</li>, <li class="item-1"><a href="link2.html">second item</a></li>, <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>, <li class="item-1 active"><a href="link4.html">fourth item</a></li>, <li class="item-0"><a href="link5.html">fifth item</a></li>]
[<li class="item-0">first item</li>, <li class="item-1"><a href="link2.html">second item</a></li>, <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>, <li class="item-1 active"><a href="link4.html">fourth item</a></li>, <li class="item-0"><a href="link5.html">fifth item</a></li>]

 

 

 

使用循环对每一个ul标签进行遍历,然后找到ul标签里面的所有li标签,以列表的形式返回,另外,beautiful soup也提供了一些其他的方法,不过与这两个相比用的较少,有兴趣的小伙伴可以动手试一下:

  • find_parents()find_parent():前者返回所有祖先节点,后者返回直接父节点。
  • find_next_siblings()find_next_sibling():前者返回后面所有的兄弟节点,后者返回后面第一个兄弟节点。
  • find_previous_siblings()find_previous_sibling():前者返回前面所有的兄弟节点,后者返回前面第一个兄弟节点。
  • find_all_next()find_next():前者返回节点后所有符合条件的节点,后者返回第一个符合条件的节点。
  • find_all_previous()find_previous():前者返回节点后所有符合条件的节点,后者返回第一个符合条件的节点。

(6)css选择器:Beautiful Soup还提供了另外一种选择器,那就是CSS选择器。使用CSS选择器时,只需要调用select()方法,传入相应的CSS选择器即可

1 soup = BeautifulSoup(html, 'lxml')
2 ul_list = soup.select('.list')
3 for ul in ul_list:
4     li_list = ul.select('.item-0')
5     for li in li_list:
6         print('标签:',li, '标签文本:',li.string, '标签属性:',li.attrs.get('class'))

输出结果如下:
标签: <li class="item-0">first item</li> 标签文本: first item 标签属性: ['item-0']
标签: <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li> 标签文本: third item 标签属性: ['item-0', 'active']
标签: <li class="item-0"><a href="link5.html">fifth item</a></li> 标签文本: fifth item 标签属性: ['item-0']
标签: <li class="item-0">first item</li> 标签文本: first item 标签属性: ['item-0']
标签: <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li> 标签文本: third item 标签属性: ['item-0', 'active']
标签: <li class="item-0"><a href="link5.html">fifth item</a></li> 标签文本: fifth item 标签属性: ['item-0']

 

可以看出,这里获取标签文本和标签属性的方法和前面是一样的,就是再选择的时候稍微有点不一样。

第二行,选择出所有具有class属性,并且属性值为list的标签,返回一个列表,css中,. 表示class属性,#表示id属性,第三行,遍历列表,选取每个元素中具有class属性,并且属性值为item-0的标签,同样返回一个列表,第五行遍历这个列表,第六行获取每个元素内容。再css中,允许一个class属性同时具有多个属性值,属性值之间以空格隔开,所以第二和第四行的结果列表里有两个元素。

文章参考:https://cuiqingcai.com/5548.html

**************************不积跬步,无以至千里。**************************

转载于:https://www.cnblogs.com/liangxiyang/p/11302525.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值