Python网络爬虫与信息提取学习记录(二)

『第二周』BeautifulSoup库

Beautiful Soup库

帮助文档:https://beautifulsoup.readthedocs.io/zh_CN/latest/

Beautiful Soup 是一个可以从HTML或XML文件中提取数据的第三方库,需要安装。

pip install beautifulsoup4

Beautiful Soup库,简称bs4,是解析、遍历、维护“标签树”的功能库。


解析器及其区别

解析器使用方法优势劣势
python标准库BeautifulSoup(markup, "html.parser")* python的内置标准库
* 执行速度适中
* 文档容错能力强
* python 2.7.3 or 3.2.2)前 的版本中文档容错能力差
lxml HTML 解析器BeautifulSoup(markup, "lxml")* 速度快
* 文档容错能力强
* 需要安装C语言库
lxml XML 解析器BeautifulSoup(markup, ["lxml-xml"])<br>
BeautifulSoup(markup, "xml")
* 速度快
* 唯一支持XML的解析器
* 需要安装C语言库
html5libBeautifulSoup(markup, "html5lib")* 最好的容错性
* 以浏览器的方式解析文档
* 生成HTML5格式的文档
* 速度慢
* 不依赖外部扩展

推荐使用lxml作为解析器,因为效率更高。

几种解析器的区别

如果一个格式完美(perfectly-formed)的html,使用不同的解析器没什么区别。

但如果不是格式完美,则不同的解析器会给出不同的结果。

>>> BeautifulSoup("<a></p>", "lxml")
<html><body><a></a></body></html>

>>> BeautifulSoup("<a></p>", "html5lib")
<html><head></head><body><a><p></p></a></body></html>

>>> BeautifulSoup("<a></p>", "html.parser")
<a></a>

BeautifulSoup基本元素

基本元素说明
Tag标签,最基本的信息组织单元,分别用<>和</>标明开头和结尾
Name标签的名字,<p>...</p>的名字是’p’,格式:<tag>.name
Attributes标签的属性,字典形式组织,格式: <tag>.attrs
Navigablestring标签内非属性字符串,<>...</>中字符串,格式:<tag>.string
Comment标签内字符串的注释部分,一种特殊的Comment类型

BeautifulSoup基本元素

解析树型结构

解析树型结构

下行遍历:

属性说明
.contents子节点的列表,将所有儿子节点存入列表
.children子节点的迭代类型,与.contents类似,用于循环遍历
.descendants子孙节点的迭代类型,包含所有子孙节点,用于循环遍历
>>> soup.head.contents
[<title>This is a python demo page</title>]

for child in soup.body.children:
    print(child)    ##遍历儿子节点
    
for child in soup.body.descendants:
    print(child)    ##遍历子孙节点

上行遍历:

属性说明
.parent节点的父亲标签
.parents节点先辈标签的迭代类型,用于循环遍历先辈节点
>>>soup.title.parent
<head><title>This is a python demo page</title></head>

>>> for parent in soup.a.parents:
        if parent is None:
            print(parent)
        else:
            print(parent.name)
P
body
html
[document]
## 遍历所有先辈节点,包括soup本身,所以要区别判断

平行遍历:

属性说明
.next_sibling返回按照HTML文本顺序的下一个平行节点标签
.previous_sibling返回按照HTML文本顺序的上一个平行节点标签
.next_siblings迭代类型,返回按照HTML文本顺序的后续所有平行节点标签
previous_siblings迭代类型,返回按照HTML文本顺序的前续所有平行节点标签

标签树的平行遍历

>>> soup.a.next_sibling 
'and'

for sibling in soup.a.next_siblings:
    print(sibling)    ## 遍历后续节点


for sibling in soup.a.previous_siblings:
    print(sibling)    ## 遍历前续节点


如何更优雅的显示HTML页面?

.prettify()为HTML文本及其内容增加’\n’,可用于标签,方法:<tag>.prettify()

bs4库将任何HTML输入都变成utf-8编码,而python 3.x默认支持编码是utf-8,解析无障碍。

>>> soup.p
<p class="title"><b>The demo python introduces several python courses.</b></p>

>>> soup.p.prettify()
'<p class="title">\n <b>\n  The demo python introduces several python courses.\n </b>\n</p>\n'

>>> print(soup.p.prettify())
<p class="title">
 <b>
  The demo python introduces several python courses.
 </b>
</p>

信息标记

XML eXtensible Markup Language

XML

<name>...</name>
<name />
<!---->

JSON JavaScript Object Notation
有类型的键值对 key : value

JSON

"key": "value"
"key": ["value1", "value2"]
"key": {"subkey": "subvalue"}

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库的标签树遍历信息解析准确提取过程繁琐,速度慢
无视标记形式,直接搜索关键信息搜索对信息的文本查找函数即可提取过程简洁,速度较快提取结果准确性与信息内容相关
结合形式解析与搜索方法,提取关键信息XML JSON YAML +搜索需要标记解析器及文本查找函数

<>.find_all(name, attrs, reccursive, string, **kwargs)

返回一个列表,存储查找的结果

  • name: 对标签名称的检索字符串

  • attrs: 对标签属性值的检索字符串,可标注属性检索

  • recursive: 是否对子孙全部检索,默认True

  • string: <>…</>中字符串区域的检索字符串

<tag>(..) 等价于 <tag>.find_all(..)

扩展方法

方法说明
<>.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()参数

.string和.text

.string方法在tag包含多个子节点时,tag无法确定.string方法应该调用哪个子节点的内容,所以输出None

.text可以返回当前节点所包含的所有文本内容,包括当前节点的子孙节点


.format中文对齐

问题
大学排名1
原理

因为单个西文字符的长度要比单个中文字符的长度要小,所以当所需的中文字符串长度大于所提供的长度时,便会自动占用后面的空间,导致后面数据的排版不符合我们的规定。

解决

将空格转化为中文空格

print("{:^5}\t{:{}^20}\t{:^5}".format("排名", "大学", chr(12288), "总分"))

结果大学排名2


扩展

[1]   陌上行走.python3中eval函数用法简介.https://blog.csdn.net/qq_29883591/article/details/53443062

[2]   牧歌_.深入解析Python中的__builtins__内建对象.https://www.jb51.net/article/87076.htm

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值