信息的标记
- 标记后的信息可形成信息组织结构,增加了信息维度
- 标记的结构与信息一样具有重要价值
- 标记后的信息可用于通信、存储或展示
- 标记后的信息更利于程序理解和运用
HTML的信息标记
HTML通过预定义的<>…</>标签形式组织不同类型的信息
<html>
<head>
<title>
This is a python demo page
</title>
</head>
<body>
<p class="title">
<b>
The demo python introduces several python courses.
...
</p>
</body>
</html>
信息标记有哪些种类呢?
信息标记的三种形式
XML、JSON、YAML
XML
eXtensible Markup Language
空元素的缩写形式
<img src=“china.jpg” size=“10” />
注释书写形式
<!‐‐ This is a comment, very useful ‐‐>
XML
eXtensible Markup Language
<name> … </name>
<name />
<!‐‐ ‐‐>
JSON
JavaScript Object Notation
多值用[,]组织
“name” : [ “北京理工大学”, “延安自然科学院” ]
键值对嵌套用{,}
“name” : {
“newName” : “北京理工大学”,
“oldName” : “延安自然科学院” }
JSON
JavaScript Object Notation
“key” : “value”
“key” : [“value1”, “value2”]
“key” : {“subkey” : “subvalue”}
YAML
YAML Ain’t Markup Language
缩进表达所属关系(与python一样)
name:
newName:北京理工大学
oldName:延安自然科学院
-表达并列关系
name:
-北京理工大学
-延安自然科学院
| 表达整块数据 # 表示注释
text: | #学校介绍
北京理工大学创立于1940年,学校是新中国成立以来国家历批次重点建设的高校,首批进入国家“211工程”和“985工程”建设行列......
YAML
YAML Ain’t Markup Language
key : value
key : #Comment
‐value1
‐value2
key :
subkey : subvalue
三种信息标记形式的比较
标记形式 | 比较 |
---|---|
XML | 最早的通用信息标记语言,可扩展性好,但繁琐 Internet上的信息交互与传递 |
JSON | 信息有类型,适合程序处理(js),较XML简洁 移动应用云端和节点的信息通信,无注释 |
YAML | 信息无类型,文本信息比例最高,可读性好 各类系统的配置文件,有注释易读 |
XML实例
<person>
<firstName>Tian</firstName>
<lastName>Song</lastName>
<address>
<streetAddr>中关村南大街5号</streetAddr>
<city>北京市</city>
<zipcode>100081</zipcode>
</address>
<prof>Computer System</prof><prof>Security</prof>
</person>
JSON实例
{
“firstName” : “Tian” ,
“lastName” : “Song” ,
“address” : {
“streetAddr” : “中关村南大街5号” ,
“city” : “北京市” ,
“zipcode” : “100081”
} ,
“prof” : [ “Computer System” , “Security” ] }
YAML实例
firstName : Tian
lastName : Song
address :
streetAddr : 中关村南大街5号
city : 北京市
zipcode : 100081
prof : ‐Computer System
‐Security
信息提取的一般方法
从标记后的信息中提取所关注的内容
XML JSON YAML
方法一:完整解析信息的标记形式,再提取关键信息
优点:信息解析准确
缺点:提取过程繁琐,速度慢
方法二:无视标记形式,直接搜索关键信息 (对信息的文本查找函数即可)
优点:提取过程简洁,速度较快
缺点:提取结果准确性与信息内容相关
融合方法:
结合形式解析与搜索方法,提取关键信息(需要标记解析器及文本查找函数)
实例:
提取HTML中所有的URL链接
思路:
(1)搜索到所有的<a>标签
(2)解析<a>标签格式,提取href后的内容链接
>>> import requests
>>> r = requests.get("http://python123.io/ws/demo.html")
>>> demo = r.text
>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup(demo,"html.parser")
>>> for link in soup.find_all('a'):
print(link.get('href'))
http://www.icourse163.org/course/BIT-268001
http://www.icourse163.org/course/BIT-1001870001
基于bs4库的HTML内容查找方法
<>.find_all(name, attrs, recursive, string, **kwargs)
返回一个列表类型,存储查找的结果
- name : 对标签名称的检索字符串
>>> soup.find_all('a')
[<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>, <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>]
>>> soup.find_all(['a','b'])
[<b>The demo python introduces several python courses.</b>, <a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>, <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>]
>>> for tag in soup.find_all(True):
print(tag.name)
html
head
title
body
p
b
p
a
a
>>> import re
>>> for tag in soup.find_all(re.compile('b')):
print(tag.name)
body
b
>>>
<>.find_all(name, attrs, recursive, string, **kwargs)
返回一个列表类型,存储查找的结果
- name : 对标签名称的检索字符串
- attrs: 对标签属性值的检索字符串,可标注属性检索
>>> soup.find_all(id='link')
[]
>>> import re
>>> soup.find_all(id=re.compile('link'))
[<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>, <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>]
<>.find_all(name, attrs, recursive, string, **kwargs)
返回一个列表类型,存储查找的结果
- name : 对标签名称的检索字符串
- attrs: 对标签属性值的检索字符串,可标注属性检索
- recursive: 是否对子孙全部检索,默认True
>>> soup.find_all('a')
[<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>, <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>]
>>> soup.find_all('a',recursive=False)
[]
>>>
<>.find_all(name, attrs, recursive, string, **kwargs)
返回一个列表类型,存储查找的结果
- name : 对标签名称的检索字符串
- attrs: 对标签属性值的检索字符串,可标注属性检索
- recursive: 是否对子孙全部检索,默认True
- string: <>…</>中字符串区域的检索字符串
>>> soup
<html><head><title>This is a python demo page</title></head>
<body>
<p class="title"><b>The demo python introduces several python courses.</b></p>
<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:
<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a> and <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>.</p>
</body></html>
>>> soup.find_all(string='Basic Python')
['Basic Python']
>>> import re
>>> soup.find_all(string=re.compile('python'))
['This is a python demo page', 'The demo python introduces several python courses.']
>>>
- <tag>(…)等价于.find_all(…)
- soup(…) 等价于soup.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()参数 |