前言
只会一种正则表达式,是无法解决这些复杂多变的网页结构,那么今天继续来学习网页解析的另一种方式BeautifulSoup4后面简称bs4。
HTML 文档本身是结构化的文本,有一定的规则,通过它的结构可以简化信息提取。于是,就有了lxml、pyquery、BeautifulSoup等网页信息提取库。一般我们会用这些库来提取网页信息。其中,lxml 有很高的解析效率,支持 xPath 语法(一种可以在 HTML 中查找信息的规则语法);pyquery 得名于 jQuery(知名的前端 js 库),可以用类似 jQuery 的语法解析网页。但我们今天要说的,是剩下的这个:BeautifulSoup。
BeautifulSoup(简称 bs)翻译成中文就是“美丽的汤”,这个奇特的名字来源于《爱丽丝梦游仙境》(这也是为何在其官网会配上奇怪的插图,以及用《爱丽丝》的片段作为测试文本)。4 是BeautifulSoup的第四个版本
bs 最大的特点我觉得是简单易用,不像正则和 xPath 需要刻意去记住很多特定语法,尽管那样会效率更高更直接。对大多数 python 使用者来说,好用会比高效更重要
BeautifulSoup4
基本概念
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的网页信息提取库
安装
由于bs4是需要依赖lxml的所以在安装bs4的时候需要先按照lxml
pip install bs4
pip install lxml
使用
bs对象的种类
- tag : 标签
- NavigableString : 可导航的字符串
- BeautifulSoup : soup对象
- Comment : 注释
在bs4里面对象种类可以分为4种 第一个是tag标签也是我们用的最多的 。第二个是一个可导航的字符串 第三个是一个bs对象 第四个是一个注释 用的不多。接下来我们来演示一下
from bs4 import BeautifulSoup
from bs4.element import NavigableString
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<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")
# tag : 标签
print(soup.title)
print(type(soup.title))
# NavigableString : 可导航的字符串
print(type(soup.p.string))
# BeautifulSoup : soup对象
print(type(soup))
Comment : 注释
html = '<a><!--生日快乐!!--></a>'
s = BeautifulSoup(html,'lxml')
print(type(s.a.string)
find()和find_all()方法
搜索文档树,一般用的比较多的两个方法就是fand()和find_all()这2个方法。find()方法是找到第一个满足条件的标签后立即返回,只返回第一个元素。find_all()方法是把所有满足条件的标签都找到,然后以列表的方式进行返回
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<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.find_all('a'))
结果:
[<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
print(soup.find('a'))
结果:
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
select()方法
我们也可以通过css选择器的方式来提取数据。但是需要注意的是这里面需要我们掌握css语法
这里大家可以参考w3c www.w3school.com.cn/cssref/css_…
下面列举一下常用的select方法
- 通过标签名来查找 soup.select('a') / soup.select_one('a') 这个用法和find()和find_all()的使用是一样的
- 通过类名查找 soup.select('.title')
- 通过id查找 soup.select('#link1')
修改文档树
bs4不仅可以进行查询,也可以对页面结构进行修改,但是与查询和解析网页相比修改几乎很少用到。所以我们列举几种常用的修改方式
- 修改tag的名称和属性
- 修改string 属性赋值,就相当于用当前的内容替代了原来的内容
- append() 像tag中添加内容,就好像Python的列表的 .append() 方法
- decompose() 修改删除段落,对于一些没有必要的文章段落我们可以给他删除掉
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<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,features="lxml")
# 修改tag的名称和属性
tag_p = soup.p
print(tag_p)
tag_p.name = 'w' # 修改标签的名称
tag_p['class'] = 'age' # 修改属性
print(tag_p)
# 修改string值
print(tag_p.string)
tag_p.string = 'you need python'
print(tag_p.string)
# append添加值
tag_p.append('abc')
print(tag_p)
# 删除
r = soup.find(class_ = 'title')
# print(r)
r.decompose()
print(soup)
ok,学会以上的内容基本bs4就算是入门了。现在我们已经学习了2种网页解析方式,那么今后大家可以根据不同的页面结构采用最合理的技术来完成需求。最后祝愿大家新年快乐!