Python网络爬虫与信息提取-Day9-信息标记与提取方法

一、信息标记的三种形式

我们需要对信息进行表记,使得我们能够理解信息所反馈的真实含义。

标记后的信息可形成信息组织结构,增加了信息维度

标记的结构与信息一样具有重要价值

标记后的信息可用于通信、存储或展示

标记后的信息更利于程序理解和运用,也利于人对信息的深入理解与运用


HTML的信息标记

HTMLWWW(World Wide Web)的信息组织方式

它能够将声音、图像、视频等超文本信息嵌入到文本中

HTML通过预定义的<>…</>标签形式组织不同类型的信息

 

现在国际公认的信息标记格式有三种分别是XMLJSONYAML

 

XMLeXtensible Markup Language)叫做扩展标记语言,它是一种与HTML很接近的标记语言。它以标签(Tag)为主来标记信息

<img src=“china.jpg” size=“10”> … </img>

它有名称 Name和属性Attribute

如果标签中没有内容,我们可以用相关的缩写形式,用一个尖括号来表示一个标签。

<img src=“china.jpg” size=“10” />空元素的缩写形式

XML中也可以嵌入注释,它以<!开头,并且以>结尾

<!‐‐ This is a comment, very useful ‐‐>注释书写形式

可以说XMLHTML发展以来的一种通用的信息标记格式

 

JSONJavsScript Object Notation),它是JavaScript语言中面向对象的一种语言形式,简单讲JSON是一种有类型的键值对构建的信息表达方式。键值对是key:value的一个组合,也就是给出一个信息,并且对信息内容做一个定义。其中对信息类型的定义叫,对信息值的描述叫value

要注意,无论是键还是值,它都通过增加双引号来表示它是字符串。说明它是一个有数据类型的键值对。

如果一个键对应多个值的时候,我们使用方括号加逗号[,]的形式来组织

键值对可以嵌套使用,也就是一个键值对放在另一个键值对的值的部分,在嵌套使用时,我们用大括号来表示

总结:JSON用有类型的键值把信息组织起来

“key” : “value”

“key” : [“value1”, “value2”]

“key” : {“subkey” : “subvalue”}

JSON语言使用有类型的键值对,一个很大好处就是对于JavaScript等编程语言来说可以直接将JSON格式变为程序的一部分,使得编写程序大大地简化

 

YAMLYAML Ain’t Markup Language),它在命名的时候使用一种递归的定义。它也使用键值对,不过是无类型键值对key:value。可以用缩进来表达所属的关系,用减号表达并列关系,用竖线表达整块数据,用#表示注释

key : value

key : #Comment

‐value1

‐value2

key :

subkey : subvalue

 

三种信息标记形式的比较

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 ]

}

JSON使用键值对的形式组织信息,但是无论标签还是后面的值,键值都要用双引号来表达它们的类型

 

YAML实例:

firstName : Tian

lastName : Song

address  :

streetAddr : 中关村南大街5

city  : 北京市

zipcode : 100081

prof  :

Computer System

Security

用无类型的键值对来表示,很简洁的关联

 

XML:最早的通用信息标记语言,可扩展性好,但繁琐

JSON:信息有类型,适合程序处理(js),较XML简洁

YAML:信息无类型,文本信息比例最高,可读性好

 

实际使用中:

XML:Internet上的信息交互与传递

JSON:移动应用云端和节点的信息通信,无注释

YAML:各类系统的配置文件,有注释易读

 

二、信息提取的一般方式

信息提取指,从标记后的信息中提取所关注的内容。之前的XML,JSON,YAML的三种形式,无论哪种形式,在信息提取中,包含标记,和信息两部分,我们关心的是所要提取出的内容

 

·方法一:完整解析信息的标记形式,再提取关键信息

用标记解析器去解析XML JSON YAML格式,然后将其中所需要的信息提取出来

例如:bs4库的标签树遍历

优点:信息解析准确

缺点:提取过程繁琐,速度慢

·方法二:无视标记形式,直接搜索关键信息

对信息的文本查找函数即可

优点:提取过程简洁,速度较快

缺点:提取结果准确性与信息内容相关

·融合方法:结合形式解析与搜索方法,提取关键信息

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内容查找方法


import requests
r = requests.get(“http://python123.io/ws/demo.html”)
demo = r.text

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

find_all方法可以在soup的变量中查找里面的信息

它能够返回一个列表类型,存储查找的结果

第一个参数name:对标签名称的检索字符串

 

from bs4 import BeautifulSoup
soup = BeautifulSoup(demo,"html.parser")
print(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>]

 

如果想要同时得到ab,则用一个方括号

print(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>]

 

如果给出的标签名称是True,则显示当前标签的所有信息

for tag in soup.find_all(True):
   print(tag.name)

html

head

title

body

p

b

p

a

a

我们看到这个文档中的所有标签名称被打印了出来

 

希望只显示其中以b开头的标签,包括bbody标签,就需要使用一个新的第三方库,叫做“正则表达式库”

首先引入这个库

正则表达式反馈的结果是以b开头的所有表达的信息

import re
for tag in soup.find_all(re.compile('b')):
   print(tag.name)

body

b

 

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

我们查找p标签中中包含course字符串的信息

print(soup.find_all('p','course'))

[<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>]

 

我们也可以对属性值作约定

print(soup.find_all(id='link1'))

[<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">Basic Python</a>]

 

print(soup.find_all(id='link'))

[]

所以我们对属性赋值要做精确的赋值

 

如果我们需要查找包含link的属性,我们就需要引入正则表达式库

print(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>]

 

正则表达式就像平常搜索一样搜索词的一部分,如果不使用正则表达式就需要完整准确地给出词的信息,不多也不少

 

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

如果我们只需要搜索儿子这一层面的信息,我们就把recursive设为False

print(soup.find_all('a',recursive=False))

[]

 

 

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

print(soup.find_all(string='Basic Python'))

['Basic Python']

 

print(soup.find_all(string=re.compile('python')))

['This is a python demo page', 'The demo python introduces several python courses.']

 

<tag>(..) 等价于 <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()参数

 

区别仅在于查找区域的不同以及检索返回的结果个数不同

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值