Python网络爬虫与信息提取(二)—— BeautifulSoup
BeautifulSoup官方介绍:
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.
官方网站:https://www.crummy.com/software/BeautifulSoup/
BeautifulSoup安装
在"C:\Windows\System32"中找到"cmd.exe",使用管理员身份运行,在命令行中输入:“pip install beautifulsoup4”运行。
C:\Windows\system32>pip install beautifulsoup4
Requirement already satisfied (use --upgrade to upgrade): beautifulsoup4 in c:\users\lei\appdata\local\programs\python\p
ython35\lib\site-packages\beautifulsoup4-4.5.-py3..egg
You are using pip version 8.1., however version 9.0. is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
提示pip版本过低,使用 python -m pip install --upgrade pip 进行升级。
Beautiful Soup库的安装测试:
from bs4 import BeautifulSoup
soup = BeautifulSoup('<p>data</p>','html.parser')
演示HTML页面地址:http://www.cnblogs.com/yan-lei
>>> import requests
>>> from bs4 import BeautifulSoup
>>> r = requests.get("http://www.cnblogs.com/yan-lei/")
>>> demo = r.text
>>> soup = BeautifulSoup(demo,"html.parser")
>>> soup
Beautiful Soup库的使用
以HTML为例,任何HTML文件都是有一组"<>"组织起来的,其实就是标签,标签之间形成了上下游关系,形成了标签树。BeautifulSoup库是解析、遍历、维护“标签树”的功能库
<p>..</p>:标签Tag
- 标签Name一般成对出现
- 属性Attributes 0个或多个
Beautiful Soup库的引用
Beautiful Soup库,也叫beautfulsoup4 或bs4。约定引用方式如下,即主要是用BeautifulSoup类。
from bs4 import BeautifulSoup
import bs4
Beautiful Soup类
将标签树转换为BeautifulSoup类,此时我们将HTML、标签树、BeautifulSoup类等价
from bs4 import BeautifulSoup
soup1 = BeautifulSoup("<html>data</html>","html.parser")
soup2 = BeautifulSoup(open("D://demo.html",'rb'),"html.parser")
使用 soup2 = BeautifulSoup(open("D://demo.html"),"html.parser") 报错:
Traceback (most recent call last):
File "<stdin>", line , in <module>
File "C:\Users\lei\AppData\Local\Programs\Python\Python35\lib\site-packages\beautifulsoup4-4.5.0-py3.5.egg\bs4\__init_
_.py", line 191, in __init__
UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence
BeautifulSoup对应一个HTML/XML文档的全部内容。
Beautiful Soup库解析器
| 解析器 | 使用方法 | 条件 |
|---|---|---|
| bs4的HTML解析器 | BeautifulSoup(mk,'html.parser') | 安装bs4库 |
| lxml的HTML解析器 | BeautifulSoup(mk,'lxml') | pip install lxml |
| lxml的XML解析器 | BeautifulSoup(mk,'xml') | pip install lxml |
| html5lib的解析器 | BeautifulSoup(mk,'html5lib') | pip install html5lib |
Beautiful Soup类的基本元素
| 基本元素 | 说明 |
|---|---|
| Tag | 标签,最基本的信息组织单元,分别用<>和</>标明开头和结尾 |
| Name | 标签的名字,<p>...</p>的名字是'p',格式:<tag>.name |
| Attributes | 标签的属性,字典形式的组织,格式:<tag>.attrs |
| NavigleString | 标签内非属性字符串,<>...</>中字符串,格式<tag>.string |
| Comment | 标签内字符串的注释部分,一种特殊的Comment类型 |
- Tag标签:任何存在于HTML语法中的标签都可以用soup.<tag>访问获得;当HTML文档中存在多个相同<tag>对应内容时,soup.<tag>返回第一个。
- Tag的名字(name):每个<tag>都有自己的名字,通过<tag>.name获取,字符串类型。
- Tag的attrs(属性):一个<tag>可以有0个或多个属性,字典类型。
- Tag的NavigableString:NavigableString可以跨越多个层次
- Tag的Comment:Comment是一种特殊类型。
>>> import requests
>>> from bs4 import BeautifulSoup
>>> r = requests.get('http://www.cnblogs.com/yan-lei/')
>>> html = r.text
>>> soup = BeautifulSoup(html,'html.parser')
>>> soup.title
<title>Python学习者 - 博客园</title>
>>> soup.a
<a name="top"></a>
>>> soup.a.name
'a'
>>> soup.a.parent.name
'body'
>>> soup.a.attrs
{'name': 'top'}
>>> type(soup.a)
<class 'bs4.element.Tag'>
>>> type(soup.a.attrs)
<class 'dict'>
>>> soup.h1.string
'Python学习者'
>>> type(soup.h1.string)
<class 'bs4.element.NavigableString'>
基于bs4库的HTML内容遍历方法
HTML中 <...>构成了所属关系,形成了标签的树形结构,有三种遍历方式。
使用以下的HTML进行测试:E:\BeautifulSoupTest.html
<html>
<head>
<meta charset="utf-8">
<title>BeautifulSoup</title>
</head>
<body>
<div id="header">
<h1 style="font-size:16px;text-align:center">这里是标题</h1>
</div>
<div id="nav">
<h1>左导航</h1>
</div>
<div id="main">
<p>第一段</p>
<p>第二段</p>
<img src="test.jpg"/>
<p><a href="http://www.cnblogs.com/yan-lei/">博客园</a></p> </div>
<div id="footer">
<h1>底边</h1>
</div> </body>
</html>
标签树的下行遍历
| 属性 | 说明 |
|---|---|
| .contents | 子节点的列表,将<tag>所有儿子节点存入列表 |
| .contents | 子节点的列表,将<tag>所有儿子节点存入列表 |
| .children | 子节点的迭代类型,与.contents类似,用于循环遍历儿子节点 |
| .descendants | 子孙节点的迭代类型,包含所有子孙节点,用于循环遍历 |
BeautifulSoup类是标签树的根节点
>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup(open('E:\\BeautifulSoupTest.html','rb'),'html.parser')
>>> soup.head.contents #返回的是列表
['\n', <meta charset="utf-8">
<title>BeautifulSoup</title>
</meta>]
>>> len(soup.body.contents)
9
>>> for child in soup.body.children: # 遍历儿子节点
... print(child)
... <div id="header">
<h1 style="font-size:16px;text-align:center">这里是标题</h1>
</div> <div id="nav">
<h1>左导航</h1>
</div> <div id="main">
<p>第一段</p>
<p>第二段</p>
<img src="test.jpg">
<p><a href="http://www.cnblogs.com/yan-lei/">博客园</a></p>
</img></div> <div id="footer">
<h1>底边</h1>
</div> >>> for child in soup.body.descendants: # 遍历子孙节点
... print(child)
... <div id="header">
<h1 style="font-size:16px;text-align:center">这里是标题</h1>
</div> <h1 style="font-size:16px;text-align:center">这里是标题</h1>
这里是标题 <div id="nav">
<h1>左导航</h1>
</div> <h1>左导航</h1>
左导航 <div id="main">
<p>第一段</p>
<p>第二段</p>
<img src="test.jpg">
<p><a href="http://www.cnblogs.com/yan-lei/">博客园</a></p>
</img></div> <p>第一段</p>
第一段 <p>第二段</p>
第二段 <img src="test.jpg">
<p><a href="http://www.cnblogs.com/yan-lei/">博客园</a></p>
</img> <p><a href="http://www.cnblogs.com/yan-lei/">博客园</a></p>
<a href="http://www.cnblogs.com/yan-lei/">博客园</a>
博客园 <div id="footer">
<h1>底边</h1>
</div> <h1>底边</h1>
底边
for child in soup.body.children: # 遍历儿子节点
print(child) for child in soup.body.descendants: # 遍历子孙节点
print(child)
标签树的上行遍历
| 属性 | 说明 |
|---|---|
| .parent | 节点的父亲标签 |
| .parents | 节点先辈标签的迭代类型,用于循环遍历先辈节点 |
>>> for parent in soup.a.parents:
... if parent is None:
... print(parent)
... else:
... print(parent.name)
...
p
img
div
body
html
[document]
# 判断所有先辈节点,包括soup本身,所以要区别判断
for parent in soup.a.parents:
if parent is None:
print(parent)
else:
print(parent.name)
标签树的平行遍历
| 属性 | 说明 |
|---|---|
| .next_sibling | 返回按照HTML文本顺序的下一个平行节点标签 |
| .previous_sibling | 返回按照HTML文本顺序的上一个平行节点标签 |
| .next_siblings | 迭代类型,返回按照HTML文本顺序的后续所有平行节点标签 |
| .previous_siblings | 迭代类型,返回按照HTML文本顺序的前续所有平行节点标签 |
*所有的平行遍历发生在同一个父节点下的各节点间。
# div标签下一个平行节点标签
soup.div.next_sibling # div标签上一个平行节点标签
soup.div.previous_sibling # 遍历后续节点
for sibling in soup.div.next_sibling:
print(sibling) # 遍历前续节点
for sibling in soup.div.previous_sibling:
print(sibling)
基于bs4库的HTML格式输出
bs4库的prettify()方法
.prettify()为HTML文本<>及其内容增加'\n'
.prettify()可用于标签,方法:<tag>.prettify()
print(soup.prettify())
bs4库将任何HTML输入都变成utf-8编码,Python 3.x默认支持编码是utf-8,解析无障碍。
信息标记的三种形式
信息的标记:
- 标记后的信息可形成信息组织结构,增加了信息维度
- 标记后的信息可用于通信、存储或展示
- 标记的结构与信息一样具有重要价值
- 标记后的信息更利于程序的理解和运用
HTML的信息标记:
HTML是WWW(World Wide Web)的信息组织方式。
HTML通过预定义的<>...</>标签形式组织不同类型的信息。
XML eXtensible Markup Language
XML格式是基于HTML格式发展以来的一种通用的信息格式。
- XML基本格式:<name> ... </name>
- 空元素缩写形式:<name />
- 注释书写形式:<!-- -->
JSON JavaScript Object Notation
有类型的键值对 key:value
使用 "" 表达是字符串类型,没有字符串则是数字类型。
YAML YAML Ain't Markup Language
无类型键值对 key:value
通过缩进表达所属关系
- - 表达并列关系
- | 表达整块数据
- # 表示注释
key : value
key : #Comment
-value1
-value2
key :
subkey : subvalue
三种信息标记形式的比较:
XML 最早的通用信息标记语言,可扩展性好,但繁琐。Internet上的信息交互与传递。
JSON 信息有类型,适合程序处理(js),较XML简洁。移动应用云端和节点的信息通信,无注释。
YAML 信息无类型,文本信息比例最高,可读性好。各类系统的配置文件,有注释易读。
信息提取的一般方法
方法一:完整解析信息的标记形式,再提取关键信息。
XML JSON YAML
需要标记解析器 例如bs4库的标签树遍历
优点:信息解析准确
缺点:提取过程繁琐,速度慢。
方法二:无视标记形式,直接搜索关键信息。
搜索
对信息的文本查找函数即可。
优点:提取过程简介,速度较快。
缺点:提取结果准确性与信息内容相关。
方法三:融合方法
融合方法:结合形式解析与搜索方法,提取关键信息。
基于bs4库的HTML内容查找方法
<>.find_all(name,attrs,recursive,string,**kwargs)
返回一个列表类型,存储查找结果。
- name:对标签名称的检索字符串。
- attrs:对标签属性值的检索字符串,可标注属性检索。
- recursive:是否对子孙全部检索,默认True。
- string:<>...</>中字符串区域的检索字符串。
<tag>(..) 等价于 <tag>.find_all(..)
soup(..) 等价于 soup.find_all(..)
>>> soup.div()
[<h1 style="font-size:16px;text-align:center">这里是标题</h1>]
>>> for tag in soup.find_all(True): # 返回所有的标签
... print(tag.name)
...
html
head
meta
title
body
div
h1
div
h1
div
p
p
img
p
a
div
h1
扩展方法
| 方法 | 说明 |
|---|---|
| <>.find() | 搜索且只返回一个结果,自负串类型,同.find_all()参数 |
| <>.find_parents() | 在先辈节点中搜索,返回列表类型,同find_all()参数 |
| <>.find_parent() | 在先辈节点中返回一个结果,字符串类型,同.find()参数 |
| <>.find_next_siblings() | 在后续平行节点中搜索,返回列表类型,同.find_all()参数 |
| <>.find_next_sibling() | 在后续平行节点中返回一个结果,字符串类型,同.find()参数 |
| <>.find_previous_siblings() | 在前序节点中搜索,返回列表类型,同.find_all()参数 |
| <>.find_previous_sibling() | 在前序节点中返回一个结果,字符串类型,同.find()参数 |

Python网络爬虫与信息提取(二)—— BeautifulSoup的更多相关文章
- Python网络爬虫与信息提取
1.Requests库入门 Requests安装 用管理员身份打开命令提示符: pip install requests 测试:打开IDLE: >>> import requests ...
- 第三次作业-Python网络爬虫与信息提取
1.注册中国大学MOOC 2.选择北京理工大学嵩天老师的<Python网络爬虫与信息提取>MOOC课程 3.学习完成第0周至第4周的课程内容,并完成各周作业 过程. 5.写一篇不少于100 ...
- 第三次作业-MOOC学习笔记:Python网络爬虫与信息提取
1.注册中国大学MOOC 2.选择北京理工大学嵩天老师的<Python网络爬虫与信息提取>MOOC课程 3.学习完成第0周至第4周的课程内容,并完成各周作业 第一周 Requests库的爬 ...
- 第3次作业-MOOC学习笔记:Python网络爬虫与信息提取
1.注册中国大学MOOC 2.选择北京理工大学嵩天老师的<Python网络爬虫与信息提取>MOOC课程 3.学习完成第0周至第4周的课程内容,并完成各周作业 4.提供图片或网站显示的学习进 ...
- Python网络爬虫与信息提取笔记
直接复制粘贴笔记发现有问题 文档下载地址//download.csdn.net/download/hide_on_rush/12266493 掌握定向网络数据爬取和网页解析的基本能力常用的 Pytho ...
- 【学习笔记】PYTHON网络爬虫与信息提取(北理工 嵩天)
学习目的:掌握定向网络数据爬取和网页解析的基本能力the Website is the API- 1 python ide 文本ide:IDLE,Sublime Text集成ide:Pychar ...
- Python网络爬虫与信息提取(一)
学习 北京理工大学 嵩天 课程笔记 课程体系结构: 1.Requests框架:自动爬取HTML页面与自动网络请求提交 2.robots.txt:网络爬虫排除标准 3.BeautifulSoup框架:解 ...
- python网络爬虫-入门(二)
为什么要学网络爬虫 可以替代人工从网页中找到数据并复制粘贴到excel中,这种重复性的工作不仅浪费时间还一不留神还会出错----解决无法自动化和无法实时获取数据 对于这些公开数据的应用价值,我 ...
- PYTHON网络爬虫与信息提取[BeautifulSoup](单元四)
1 简介 from bs4 import BeautifulSoup soup=BeautifulSoup(<p>data</p>,'html.parser') 2 基本元素 ...
随机推荐
- web离线应用--applicationCache
applicationCache是html5新增的一个离线应用功能 离线浏览: 用户可以在离线状态下浏览网站内容. 更快的速度: 因为数据被存储在本地,所以速度会更快. 减轻服务器的负载: 浏览器只会 ...
- 晓莲说-何不原创:如何通过jad把class批量反编译成java文件
背景:前几天在项目开发的时候遇到一个问题,那就是利用myeclipse编写好的一个项目打包成jar包后上传部署到服务器里,之后本地的项目被自己改来改去出现了一些问题,想着把上传到服务器里面的war包下 ...
- 利用python web框架django实现py-faster-rcnn demo实例
操作系统.编程环境及其他: window7 cpu python2.7 pycharm5.0 django1.8x 说明:本blog是上一篇blog(http://www.cnblogs.co ...
- 15. 使用Apache Curator管理ZooKeeper
Apache ZooKeeper是为了帮助解决复杂问题的软件工具,它可以帮助用户从复杂的实现中解救出来. 然而,ZooKeeper只暴露了原语,这取决于用户如何使用这些原语来解决应用程序中的协调问题. ...
- 实践作业2:黑盒测试实践——安装配置测试工具 Day 3
安装配置Katalon Studio工具 1.找下载Katalon链接,需要有效电子邮件才能激活Katalon账户,在我的Gmail里注册. 2.选择下载版本 3.下载完成后 ,转到计算机上的文件夹, ...
- linux 下配置静态IP
设置静态网络如下[root@bogon network-scripts]# pwd 进入这个路径下 /etc/sysconfig/network-scripts [root@bogon network ...
- 一些内存模型、并发、netty知识点的记录
happens-before:描述内存可见性as-if-serial:无论怎么重排序,程序的运行结果不会改变 ReentrantLock依赖了队列同步器AQS,其实现方式是volatile变量的读写操 ...
- 表单的自动到json与urlstr
将表单序列化成json,将json转换成字符串 //将表单序列化成json 字符串 $.fn.serializeObject = function(){ var obj = {}; var count ...
- C#复习资料
C#期末考试复习题 一.单项选择题(每小题2分,共20分) 1.在类作用域中能够通过直接使用该类的( )成员名进行访问. A. 私有 B. 公用 C. 保护 D. 任 ...
- FPGA编程基础(一)--參数传递与寄存器使用
一.參数映射 參数映射的功能就是实现參数化元件.所谓的"參数化元件"就是指元件的某些參数是可调的,通过调整这些參数从而可实现一类结构类似而功能不同的电路.在应用中.非常多电路都可採 ...