python之信息组织与提取方法学习笔记

1,前言

我们已经明白了如何处理HTML文本,想一想,一锅粥,print,就会有神奇的出现。但是在标签中或者说网页里的一些信息我们应该怎么提取呢,看到文章的标题,或许你已经猜到了,那我们就看一看是不是和大家的猜想一样?

2,信息标记的三种形式

2.1,什么是信息标记

如果是一组信息,你阔能会很快看出来是什么意思,

如果是一组信息呢?

小明、2001、软件工程、北京。

看上去是再说一个事,但是就很难理解。因此我们就要用到信息标记,整理一下:

姓名:小明

出生年份:2001

所学专业:软件工程

居住地:北京

这样看是不是就清晰了。

  • 标记后的信息可形成信息组织结构,增加了信息维度。
  • 标记后的信息可用于通信、存储、或展示
  • 标记的结构与信息一样具有重要价值
  • 标记后的信息更利于程序的理解和运用

以上就是他的相关概念,不难理解,通过上面演示也可以看出很重要吧

2.2,HTML的信息标记

  • HTML:(hyper text Markup language)超文本标记语言
  • HTML是www(World Wide Web)的信息组织方式
  • 可以将声音、图像、音频等超文本的信息嵌入到文本当中
  • HTML通过预定义的<>...</>的标签形式组织不同类型的信息

这四点似曾相识。之前也大概描述过。就是再说网页,网页有图片、音频、声音等等等。

2.3,信息标记种类、

说了那么多,都是铺垫。仿佛并不是我们想要知道的

目前,世上公认的信息标记种类有三种形式:XML、JSON和YAML、几人看到这了,让我们分别了解一下。

2.3.1,XML

  • XML:(eXtensible Markup Language)可扩展标记语言

  • 空格元素的缩写形式

    <img src="china.jpg" size="10" />
    
  • 注释书写形式‘

    <!--This is a comment, very useful -->
    
  • xml通过标签形式来构建所有信息,有三种经常使用的方式

    <name>...</name>:标签中有内容

    <name />:标签中没有内容

    <!-- -->:注释

与html接近,也有标签tag、名字name、属性attribute。

看上去是不是和HTML相似,你有的我也有。

其实在历史发展中先有了HTML格式,再有了xml格式。因此可以说xml格式是基于HTML格式发展以来的一种通用的信息表达形式

3.3.2, JSON

  • JSON:(JavaScript Object Notation)

  • 有类型的键值对:key: value

    信息类型的定义是key;信息值得描述value。

  • 用法

    "姓名": "小明"
    "出生年份": 2001
    

    **注:**增加“”表示他是字符串类型,如果是数字,请忽略。

    当一个键有多个值的时候

    "name":  ["小明", "小刚"]
    

    也可以嵌套使用:

    "小明": {
    		"性别":“男”,
    		“专业”: "软件工程"
    			}
    

    键值对嵌套采用{,}形式。

  • 他的所有格式总结如下:

    "key" : "vaule"

    "key" : ["vaule1", "vaule2"]:一个键有多个值

    "key" : {"subkey": "subvalue"}:嵌套形式

3.3.3,YAML

  • YAML:YAML Ain’t a Markup Language

    无类型键值对 key:value

  • 使用方法

    姓名 : 小明
    

    我们以JSON相比会发现yaml仅字符串,没有双引号。

    我们也可以通过缩进的方式表达所属关系

    小明 :
    	性别 :专业 : 软件工程
    

    -表达并列关系

    软件工程 :
    	- 小明
    	- 小红
    

    |表示整块数据,#:表示注释

    yaml: |  # 一段yaml介绍
    YAML(/ˈjæməl/,尾音类似camel骆驼)是一个可读性高,用来表达数据序列化的格式。YAML参考了其他多种语言,包括:C语言、Python、Perl,并从XML、电子邮件的数据格式(RFC 2822)中获得灵感。Clark Evans在2001年首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。当前已经有数种编程语言或脚本语言支持(或者说解析)这种语言。
    
  • 所有使用方式

    key : vaule
    key : #Comment
    - value1
    - value2
    key :
    	subkey : subv
    

3, 三种信息标记形式的比较

3.1,回顾

我们先回顾一下三种不同信息标记形式

  1. XML

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

    <>和标签表达信息

  2. JSON

    "key" : "vaule:
    "key" : ["vaule1", "vaule2"]
    "key" : {"subkey": "subvalue"}
    

    用有类型的键值对表达信息

  3. YAML

    key : vaule
    key : #Comment
    - value1
    - value2
    key :
    	subkey : subv
    

    用无类型键值对表达信息

3.2,实例

我们再分别看一下他们的实例

  1. XML

    <person>
    	<fistName>Tian</fistName>
        <lastName>Song</lastName>
        <address>
        	<streeAddr>中关村南大街5号</streeAddr>
            <city>北京市</city>
            <zipcode>100081</zipcode>
        </address>
        <prof>Computer System</prof><prof>Security</prof>
    </person>
    

    关键信息用标签组织起来,一眼望去大部分都是标签,有效信息就那么几个。

  2. JSON

    {
    	"fistName" : "Tian" ,
    	"lastName" : "Song" ,
    	"address" :{
    					"streeAddr" : "中关村南大街5号" ,
    					"city" : "北京市" ,
    					"zipcode" : "100081"
    				} ,
    	"prof" : [ "Computer System" , "Security"]
    }
    

    可以看出有类型的字符串,必须有双引号

  3. YAML

    fistName : Tian
    lastName : Song
    address : 
    	streeAddr : 中关村南大街5号
    	city : 北京市
    	zipcode : 100081
    prpf :
    - Computer System
    - Security
    

    看上去比前两个都简洁

    3.3,三种信息标记i形式的比较

  4. XML:最早的通用信息标记语言,扩展性好,但繁琐。常用于inter上的信息交互与传递。

  5. json:信息有类型,适合程序处理(js),比XML简洁。常用于移动应用云端和节点的信息通信,无注释。

  6. YAML:信息无类型,文本信息比例最高,可读性好。常用于各类系统的配置文件,有注释易读。

没有对比就没有伤害,这三种形式,要我选择我肯定喜欢YAML,洁简,看起来很舒服,当我们不能否认其他两种没有任何用,json经常用于程序接口,需要不知道什么是接口,XML在互联网上也很吃香,但是对于我这种学习者也是YAML确实不错。

4,信息提取的一般方式

说过了信息标记,那么标记后的信息如何提取出来呢?

信息提取,是指从所标记的信息中提取内容,无论哪种形式,都有两部分组成标记和信息,我们关心的是我们所要提出的信息内容,

有三种方法,我们看看

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

    XML,JSON,YAML需要标记解析器,例如:bs4库的标签树遍历

    优点:信息解析准确

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

    虽然没有试过,但是看到bs4库的遍历,想到了HTML,他们的工作原理应该和HTML很相像,需要记住整个文件的信息组织,做到认识和了解。

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

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

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

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

    这个类似word里面的Ctrl+F,速度确实快,但是准确性不好说。

  3. 融合方法

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

    XML,JSON,YAML。搜索

    需要标记解析器及文本查找函数。

4.1,实例

我们提取HTML页面中所url链接

思路,通过分析网页,可以看到a标签里有ur链接,

image

再找到head属性

我们做出代码

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

会发现有两个新面孔,.find_all().get()表示问题保留,看下面。

5,基于bs4库的HTML内容查找方法

4.1,回顾

image

想必这个图片大家已经不再陌生了吧?

4.2,<>.find_all()方法

之前,我们遇到了一个方法,<>.find_all(),我们现在了解一下

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

find:查找的意思。

<>.fild_all(name, attrs, resursive, string, **kwargs)

一共有五个参数,了解一下。

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

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

    我们试试检索p标签

    >>> soup.find_all("p")
    [<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>]
    

    可以看到返回了一个列表,里面有结果。

    我还想看看b标签

    >>> soup.find_all(["p","b"])
    [<p class="title"><b>The demo python introduces several python courses.</b></p>, <b>The demo python introduces several python courses.</b>, <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>]
    >>> 
    

    如果给出的标签是True,返回soup所有标签

    >>> for tag in soup.find_all(True):
    	print(tag.name)
    
    html
    head
    title
    body
    p
    b
    p
    a
    a
    

    如果说返回以b开头的标签呢?

    这里我们就需要用到正则表达式库了,我们一起来看看

    import re
    >>> for tag in soup.find_all(re.compile("b")):
    	print(tag.name)
    
    body
    b
    

    标签需要以b开头。

  • attrs:对标签属性值的检索字符串,可标注属性检索。检索某一个标签中是否包含了某些字符信息。

    查看p标签有没有包含course信息

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

    返回了p标签属性有course的信息。

    当然也阔以对属性值做一些约定,比如查找id="link1"作为查找元素。

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

    可以看出,打印出来了。

    如果是link呢?

    >>> soup.find_all(id="link")
    []
    

    会发现是空的。然而,这个错误我也在之前犯过。应该全部输入,当然也不是不可以吗,上面提到过正则表达式,这里依然可以完成。

    ->>> 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。

    什么意思呢,我们搜索的是从当前标签开始的以下信息,如果想搜索当前节点儿子的信息,设为false。

    我们先查找a标签下的信息

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

    我们在查找一下a标签的儿子标签节点

    >>> soup.find_all("a",recursive=False)
    []
    

    可以看见为空。直接说他没有儿子。

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

    我们去检索一下字符串 Basic python,

    >>> soup.find_all(string = "Basic Python")
    ['Basic Python']
    

    还是需要我们精准输入,如果输入python,还想出现结果,就需要正则表达式了。

    >>> soup.find_all(string = re.compile("Python"))
    ['Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:\r\n', 'Basic Python', 'Advanced Python']
    

    此时就会打印与python字符串有关的字符串

由于<>.find_all()方法非常常用,因此他还有属于他的简写形式

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

soup(…)等价于soup.find_all(…)`

<>.find_all()`方法还有七个扩展方法

方法说明
find()搜索且只返回一个结果,字符串类型,同find_all()参数。
<>.find_parents()在先辈节点中搜索,返回列表类型,同find_all()参数。
<>.find_parent()在先辈节点中返回一个结果,字符串类型,同find_all()参数。
<>.find_next_siblings()在后序平行节点中搜索,返回类别类型,同find_all()参数。
<>.find_next_sibling()在后序平行节点中返回一个结果,返回类别类型,同find_all()参数。
<>.find_previous_siblings()在前序平行节点中搜索,返回类别类型,同find_all()参数。
<>.find_previous_sibling()在前序平行节点中返回一个结果,返回类别类型,同find_all()参数。

通过之前的所学与一些字眼,我们大概了解,他们只是搜索范围与返回结果不同,而且这6+1个方法也是非常好记,

6,总结

可以说是提取网页内容,但是不是和我想象的不太一样。现在我似乎理解了。是通过HTML文本中使用find_all方法。然后得到我们想要的内容,

这里应该也是对正则表达式有了个认识,就是用来做搜索用的。

这就是以上内容,我的笔记。

谢谢您的,如果文章有错误,欢迎你的指正;如果对您有帮助,是我的荣幸。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值