006 Python网络爬虫与信息提取 信息组织与提取方法
[A] 信息标记的三种形式
信息标记:通过网络爬虫,我们可以获取各式各样的信息,比如地址信息,姓名信息,日期信息,年代信息等,这些信息会很冗杂
通过对信息的标记,可以帮助我们更好的组织和管理这些信息
信息标记的好处:
1. 标记后的信息可形成信息组织结构,增加了信息维度
2. 标记后的信息可用于通信,存储和展示
3. 标记的结构和信息一样具有重要价值
4. 标记后的信息更利于程序的理解和运用
国际公认的信息表达种类有三种:
1. JSON JavaScript Object Notation,即 JavaScript对象标记
键和值均必须为字符串类型
基本格式:通过有类型的键值对构建的对象
{"name": "汕头大学"}
一个键对应多个值时:采用数组格式
{"name": ["汕头大学", "深圳大学"]}
可以进行嵌套
2. XML eXtensible Markup Language,即可拓展的标记性语言
基本格式:类似于html语言格式
<img arc = "china.jpg" size = 10>这是一张图片</img>
无标签内容时:
<img arc = "china.jpg" size = 10 />
注释信息:
<!-- 注释内容 -->
3. YAML YAML Ain't Markup Language
键和值都没有双引号,即键和值都是无类型的
基本格式:无类型的键值对
name: "汕头大学"
嵌套关系组成:通过缩进表示
name:
newName: "汕头大学"
oldName: "汕头市扶贫委员会"
表达并列关系: 对应于JSON中的数组
name:
-"汕头大学"
-“汕头市扶贫委员会”
数据块信息表达:
当一个键的值为一大段话的时候,需要换行
用|表示整块数据,用 # 添加注释信息
text: | # 学校介绍
汕头大学(Shantou University),位于广东省汕头市,是教育部、广东省、李嘉诚基金会三方共建的省部共建大学,
也是全球唯一一所由私人基金会——李嘉诚基金会持续资助的公立大学;入选广东省“211工程”建设高校、广东省高水
平大学重点学科建设高校、教育部卓越工程师教育培养计划、教育部卓越医生教育培养计划、国家级大学生创新创业
。。。。。。
三种信息标记形式的比较:
XML 最早的通用信息标记语言,可拓展性好,但是比较繁琐 适用于Internet上的信息交互和传递
JSON 信息有类型,适合程序处理(js),较XML简洁 适用于云端和节点的信息通信,无注释
YAML 信息无类型,文本信息比列最高,可读性好 适用于各类系统的配置文件,有注释易读
[B] 信息提取的方法
信息提取指的是从标记后的信息中心提取所关注的内容
信息提取的一般方法:
1. 完整的解析信息的标记形式,再提取关键信息
XML JSON YAML
使用到的标记解释器,如bs4库的标签树遍历
优点:信息表达准确
缺点:提取过程繁琐,速度慢,需要程序员对所分析信息的结构和内容有清晰的认识和理解
2. 无视标记形式,直接搜索关键信息
通过查找函数直接查找文本信息即可
优点:提取过程简洁,速度快
缺点:提取结果与提取内容相关
3. 融合方法: 结合形式解析和搜索方法,提取关键信息
实例:提取HTML中所有的URL链接
思路:
1. 搜搜所有的<a>标签
2. 解析<a>标签格式,提取href后的链接内容
示例代码:
import requests from bs4 import BeautifulSoup # 1. 爬取相关内容 r = requests.get('http://python123.io/ws/demo.html') demo = r.text # 2. 煲汤 soup = BeautifulSoup(demo, 'html.parser') # print(soup) # 3. 提取HTML中所有的URL链接 for link in soup.find_all('a'): print(link.get('href')) print('打印完了')
[C] 基于bs4库的HTML内容查找方法
BeautifulSoup类返回的soup对象存在一些方法:
1. soup.find_all(name, attr, recursive, string, **kwargs)
返回值:列表类型,存储查找的结果
参数:
name: 对标签类型的检索字符串,如'a', 'p'
若要检索多个标签的name为数组 ['a', 'p']
若要查找文档下的所有标签,则name为True
若要检索更复杂的,name也可以为正则表达式
attrs:对标签属性值的检索字符串,可标注属性检索
为字符串时,直接写入标签属性值即可
为键值对时,写全即可,如id='link1'
recursive: 是否对子孙节点进行搜索,默认为True
如果为False,表示只在子节点这一层查找
string: <>..</>标签之间的检索字符串
如:string='Advanced Python'
注:该方法只有当标签中的内容完整的写在string中时才会搜索成功,若要部分匹配可使用正则表达式
find_all()方法由于太过于常用,因此存在简写方式:
1. <tag>.find_all() 可简写为 <tag>()
2. soup.find_all() 可简写为 soup()
拓展方法:
方法 | 说明 |
.find | 搜索且只返回一个结果,字符串类型,同.find_all()参数 |
.find_parent() | 在先辈节点中返回一个结果,字符串类型,同.find()参数 |
.find_parents() | 在先辈节点中搜索,返回列表类型,字符串类型,同.find_all()参数 |
.find_next_sibling() | 在后续平行节点中返回一个结果,字符串类型,同.find_all()参数 |
.find_next_siblings() | 在后续平行节点中搜索,返回列表类型,同.find_all()参数 |
.find_previous_sibling() | 在前续平行节点中返回一个结果,字符串类型,同.find_all()参数 |
.find_previous_siblings() | 在前续平行节点中搜索,返回列表类型,同.find_all()参数 |