BeautifulSoup是一个可以从HTML或XML文件中提取数据的Python扩展库,是一个分析HTML或XML文件的解析器。它通过合适的转换器实现文档导航、查找、修改文档等功能;可以很好地处理不规范标记并生成剖析树(ParseTree);提供的导航功能(Navigating)可以简单、快速地搜索剖析树以及修改剖析树。Beau-tifulSoup技术通常用于分析网页结构,爬取相应的Web文档,对于不规则的HTML文档提供定的补全功能,从而节省开发者的时间和精力。
我们上次学的正则表达式对于爬取网页数据有很大的局限性,如:
(1)正则表达式被HTML源码所约束,而不是取决于更抽象的结构;网页结构中很小的改动可能会导致程序的中断。
(2)程序需要根据实际HTML源码分析内容,可能会遇到字符实体如&之类的HTML特性,需要指定处理如<span></span>
、图标超链接、下标等不同内容。
(3)正则表达式并不是完全可读的,更复杂的HTML代码和查询表达式会变得很乱
建议安装BeautifulSoup 4,因为BeautifulSoup 3已经停止更新了,安装成功后,在程序中导入BeautifulSoup库,如下:
from BeautifulSoup import BeautifulSoup #处理HTML
from BeautifulSoup import BeautifulStoneSoup #处理XML
import Beautiful #导入完整的BeautifulSoup
如果安装的是BeautifulSoup 4,则导入代码如下:
from bs4 import BeautifulSoup
先预设一段代码,进行下面的学习
<!DOCTYPE html>
<html lang="en">
<head>
<title>BeautifulSoup技术学习</title>
</head>
<body>
<h1>斩梦</h1>
<p class="author"> <b>作者:</b> 杨友</p>
<p class="content">
笔启云霄志,天涯梦何处?<br>
引笔书倾诉,伴影两孤独。<br>
三春花事好,空趣亦空无。<br>
秀发软香系,重起行前鼓。<br>
披风鉴星月,舟踏浪平渡。<br>
漫思阑珊意,金榜路殊途。<br>
勿时以为念,寒窗铭刻骨。<br>
</p>
<p class="introduction" >
作者,<a href="http://www.gufe.edu.cn/www/">贵州财经大学</a> 学生,信息管理与信息系统专业。
本诗歌作于 <a href="https://gzszfzx.30edu.com.cn/">贞丰中学</a> 高三时,那年正是高考,
心中的感情观和学业观放在一起抉择,做出了自己的决定。作为一个乐观且斗志昂扬的高考人,
时间正是最关键的青春年华,道出了自己理想、学习、爱情、选择、过程、目标、结局、纪念......
</p>
</body>
</html>
1、BeautifulSoup解析HTML
创建一个BeautifulSoup对象,然后调用BeautifulSoup库的prettify()函数格式化输出网页
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
HTML = '''
<!DOCTYPE html>
<html lang="en">
<head>
<title>BeautifulSoup技术学习</title>
</head>
<body>
<h1>斩梦</h1>
<p class="author"> <b>作者:</b> 杨友</p>
<p class="content">
笔启云霄志,天涯梦何处?<br>
引笔书倾诉,伴影两孤独。<br>
三春花事好,空趣亦空无。<br>
秀发软香系,重起行前鼓。<br>
披风鉴星月,舟踏浪平渡。<br>
漫思阑珊意,金榜路殊途。<br>
勿时以为念,寒窗铭刻骨。<br>
</p>
<p class="introduction" >
作者,<a href="http://www.gufe.edu.cn/www/">贵州财经大学</a> 学生,信息管理与信息系统专业。
本诗歌作于 <a href="https://gzszfzx.30edu.com.cn/">贞丰中学</a> 高三时,那年正是高考,
心中的感情观和学业观放在一起抉择,做出了自己的决定。作为一个乐观且斗志昂扬的高考人,
时间正是最关键的青春年华,道出了自己理想、学习、爱情、选择、过程、目标、结局、纪念......
</p>
'''
#按照标准的缩进格式结构输出
soup = BeautifulSoup(HTML)
print soup.prettify()
输出结果如下:
<!DOCTYPE html>
<html lang="en">
<head>
<title>
BeautifulSoup技术学习
</title>
</head>
<body>
<h1>
斩梦
</h1>
<p class="author">
<b>
作者:
</b>
杨友
</p>
<p class="content">
笔启云霄志,天涯梦何处?
<br/>
引笔书倾诉,伴影两孤独。
<br/>
三春花事好,空趣亦空无。
<br/>
秀发软香系,重起行前鼓。
<br/>
披风鉴星月,舟踏浪平渡。
<br/>
漫思阑珊意,金榜路殊途。
<br/>
勿时以为念,寒窗铭刻骨。
<br/>
</p>
<p class="introduction">
作者,
<a href="http://www.gufe.edu.cn/www/">
贵州财经大学
</a>
学生,信息管理与信息系统专业。
本诗歌作于
<a href="https://gzszfzx.30edu.com.cn/">
贞丰中学
</a>
高三时,那年正是高考,
心中的感情观和学业观放在一起抉择,做出了自己的决定。作为一个乐观且斗志昂扬的高考人,
时间正是最关键的青春年华,道出了自己理想、学习、爱情、选择、过程、目标、结局、纪念......
</p>
</body>
</html>
注意: 代码中的HTML缺少结束标签</body>和</html>
,但是使用的prettify()函数输出的结果已经自动补齐,这是BeautifulSoup的一个优点,即使是损坏的标签,也会尽可能转化为DOM树,并尽可能与原文档的内容一致。
另外,还可以用本地HTML文件来创建BeautifulSoup对象,代码如下:
soup = BeautifulSoup(open('G:/MyPoem.html'))
2、获取网页标签信息
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
#创建本地文件soup对象
soup = BeautifulSoup(open('G:/MyPoem.html'),"html.parser")
#获取标题
tit = soup.title
print u'标题:',tit
#获取头部信息
print u'头部:',soup.head
运行结果:
======================== RESTART: G:\20190709_BS2.py ========================
标题: <title>BeautifulSoup技术学习</title>
头部: <head>
<title>BeautifulSoup技术学习</title>
</head>
>>>
通过上面的运行结果得出,soup.title,soup.head输出的结果包括它的标签,我们可以用这种方法输出 a 标签和 p 标签的全部内容,MHTL文本中有两个 a 标签链接和两个 p 标签,输出时都需要使用unicode()函数转码,否则输出的内容为乱码。
(1)输出超链接 a 标签链接代码如下:
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
#创建本地文件soup对象
soup = BeautifulSoup(open('G:/MyPoem.html'),"html.parser")
#获取<a>标签全部信息
k = unicode(soup.a)
print u'超链接:',k
运行结果:
(2)输出段落 p 标签代码如下:
#获取<p></p>的内容
t = unicode(soup.p)
print u'段落:',t
运行结果:
注意: 我们只输出了一个 a 标签的内容和一个 p 标签的内容
源码汇总如下:
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
#创建本地文件soup对象
soup = BeautifulSoup(open('G:/MyPoem.html'),"html.parser")
#获取标题
tit = unicode(soup.title)
print u'标题:',tit
#获取头部信息
head = unicode(soup.head)
print u'头部:',head
#获取<a>标签全部信息
k= unicode(soup.a)
print u'超链接:',k
#获取<p></p>的内容
txt = unicode(soup.p)
print u'段落:',txt
运行结果:
3、定位标签及获取内容
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
#创建本地文件soup对象
soup = BeautifulSoup(open('G:/MyPoem.html'),"html.parser")
for a in soup.find_all('a'):
#获取到所有<a>标签链接
print u'标签链接:',unicode(a)
#获取到所有链接
print u'链 接:',(a.get('href'))
#获取<a></a>间的内容
print u'链接名称:',unicode(a.get_text())
print "\n" #输出换行符,方便查看循环次数,使数据美观
运行结果:
步骤:
(1)用find_all(‘a’)函数查找所有的<a>
标签,并通过for循环输出结果;
(2)unicode(a),获取完整的标签链接,unicode防止中文乱码
(3)a.get(‘href’),获取超链接,超链接前面有href=,用它定位
(4)a.get_text(),获取超链接的名称,<a>被截取的部分</a>