beautifulsoup解析库
上一篇记叙了xpath解析库的基本使用,这一篇整理一下Beautifulsoup这个解析库。依旧是菜,若有错误的地方,欢迎大家随时指正。。。。。。。(come on.......)
首先,还是先来当以那个html字符串
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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> '''
Beautiful Soup:简单来说,Beautiful Soup就是Python的一个HTML的解析库
然后,再来看一下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 // 获取到第一个li节点 3 print(li.string) // 使用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'}) // 表示找到所有标签名是ul,并且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>]
另外,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()
:前者返回节点后所有符合条件的节点,后者返回第一个符合条件的节点。
文章参考:https://cuiqingcai.com/5548.html
**************************不积跬步,无以至千里。**************************