Beautiful Soup的简介

Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下:

1、Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序

2、Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了

3、Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度

安装BeautifulSoup

1、BeautifulSoup4通过PyPi发布,所以如果你无法使用系统包管理安装,那么也可以通过easy_install或pip来安装。包的名字是beautifulsoup4这个包兼容Python2和Python3

2、 pip install BeautifulSoup4==4.0.1

安装解析器

1、Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器。其中一个是lxml

2、根据操作系统不同,可以选择pip方法来安装lxml:pip install lxml

各种解析器优缺点

Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快,推荐安装(pip install lxml)

解析器 使用方法 优势 劣势
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”])或BeautifulSoup(markup, “xml”) 速度快、唯一支持XML的解析器 需要安装C语言库
html5lib  BeautifulSoup(markup, “html5lib”)  最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档、不依赖外部扩展   速度慢

BeautifulSoup简介

1、将一段文档传入BeautifulSoup 的构造方法,就能得到一个文档的对象(beautifulsoup对象)。同时也可以传入一段字符串或一个文件句柄

2、首先,文档被转换成Unicode,并且HTML的实例都被转换成Unicode编码

3、然后Beautiful Soup选择最合适的解析器来解析这段文档,如果手动指定解析器,那么Beautiful Soup会选择指定的解析器来解析文档

例1:

from bs4 import BeautifulSoup #导入bs4库html = """
<html><head><title>The Dormouse's story</title></head> <body> <p class="title" name="dromouse"><b>The Dormouse's story</b></p> <p class="story">Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p></body>
</html>
"""soup = BeautifulSoup(html,"lxml")#指定解析器,返回一个beautifulsoup对象print(type(soup))HTML_prettify = soup.prettify() #打印一下soup对象的内容,格式化输出
print(HTML_prettify)"""
<class 'bs4.BeautifulSoup'>
<html><head><title>The Dormouse's story</title></head><body><p class="title" name="dromouse"><b>The Dormouse's story</b></p><p class="story">Once upon a time there were three little sisters; and their names were<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>and<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>; and they lived at the bottom of a well.</p><p class="story">...</p></body>
</html>
"""

例1_1:使用HTML文件来创建beautifulsoup对象

from bs4 import BeautifulSouphtml = open("F:\\test.txt","r",encoding="utf-8")
soup = BeautifulSoup(html,features="lxml") #将本地文件打开,用它来创建soup对象

注:
1、BeautifulSoup()方法返回的是一个bs4.BeautifulSoup对象,我们可以根据这个对象来使用不同的方法来获得HTML中我们需要的数据

2、在BeautifulSoup()方法中感觉最好指定解析器(使用lxml解析器),不然有时候会报错

3、上面例子中使用了prettify()方法:该方法用于格式化打印出获得的内容。这个函数经常用到所以要记住了

四大对象种类

Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

对象名 描述
BeautifulSoup 文档自身:表示的是一个文档的全部内容
Tag 标签对:Tag对象与XML或HTML原生文档中的tag相同,即标签对            
NavigableString  标签值:标签对中的字符串
Comment 注释:文档的注释部分

Tag对象

1、Tag即HTML或XML中的标签对:Tag对象与XML或HTML原生文档中的tag相同

2、HTML中tag是由尖括号包围的关键词,即HTML中的一个个标签。一般是成对出现的。比如<p>和</p>

3、成对的tag里,第一个(不带"/"的)叫开始tag(又叫开放tag),第二个叫结束tag(又叫闭合tag)

4、例如:<title>The Dormouse's story</title>或<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
    ⑴上面的title、a等等HTML标签加上里面包括的内容就是Tag
    ⑵在BeautifulSoup中可以利用beautifulsoup对象下面的方法返回这些标签数据,这些标签数据称为Tag对象(Tag对象指的是整个标签对:从开始标签到结束标签,包括里面的嵌套标签)
    ⑶获取到Tag对象后,可以继续使用其下面的属性(方法)来获取标签对中的具体数据

5、Tag有很多方法和属性,暂时先介绍一下tag对象中最重要的属性:name属性和attributes属性

获取Tag对象

1、从一个beautifulsoup对象中获取指定的Tag对象,可以使用:beautifulsoup对象.标签名
    ⑴要获取哪个标签的Tag对象,就传入哪个标签的标签名

2、注:这种方法返回的Tag对象是所有内容中第一个符合要求的标签
    ⑴即:文档中存在多个同名的标签时,使用"beautifulsoup对象.标签名"返回的始终是第一个符合的标签(至于查找所有符合要求的标签,后面介绍)

例2:

from bs4 import BeautifulSoup #导入bs4库html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""soup = BeautifulSoup(html,"lxml")#指定解析器
HTML_title = soup.title #获取title标签
print("获取到的title标签为:",HTML_title)HTML_head = soup.head #获取header标签
print("获取到的header标签为:",HTML_head)HTML_a = soup.a #获取a标签
print("获取到的a标签为:",HTML_a)HTML_p = soup.p #获取p标签
print("获取到的p标签为:",HTML_p)
print("获取到的p标签类型为:",type(HTML_p))"""
获取到的title标签为: <title>The Dormouse's story</title>
获取到的header标签为: <head><title>The Dormouse's story</title></head>
获取到的a标签为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
获取到的p标签为: <p class="title" name="dromouse"><b>The Dormouse's story</b></p>
获取到的p标签类型为: <class 'bs4.element.Tag'>
"""

注:
1、从上面例子中我们可以看出:可以使用soup对象加标签名轻松地获取这些标签的内容,返回的标签是一个" <class 'bs4.element.Tag'>",即Tag对象

2、不过需要注意的是:它查找的是在所有内容中的第一个符合要求的标签,如果要查询所有符合要求的标签,我们在后面进行介绍

tag对象的name属性

1、每个tag都有自己的名字,其成为tag对象的name属性(name属性:标签对的名称)

2、获取一个Tag对象的name属性,可以使用:Tag对象.name

例3:

from bs4 import BeautifulSoup #导入bs4库html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""soup = BeautifulSoup(html,"lxml")   #指定解析器
soup_tag_name = soup.name    #获取整个BeautifulSoup对象的name属性
title_tag_name = soup.title.name  #获取title标签对象的name属性
head_tag_name = soup.head.name  #获取head标签对象的name属性
a_tag = soup.a    #获取a标签对象
a_tag_name = a_tag.name #获取a标签对象的name属性print("整个BeautifulSoup对象的name属性为:",soup_tag_name)
print("title标签对象的name属性为:",title_tag_name)
print("header标签对象的name属性为:",head_tag_name)
print("a标签对象为:",a_tag)
print("a标签对象的name属性为:",a_tag_name)"""
整个BeautifulSoup对象的name属性为: [document]
title标签对象的name属性为: title
header标签对象的name属性为: head
a标签对象为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
a标签对象的name属性为: a
"""

注:
1、对于soup对象来说:soup对象本身比较特殊,它的name即为[document]

2、对于其他内部标签:输出的值便为标签本身的名称(值类型为字符串)

3、不过感觉获取一个Tag对象的name属性意义不大,毕竟都是通过其标签名来获取的tag对象,然后再通过Tag对象去获取其name属性就显得多此一举了

tag对象的attrs属性

1、attrs属性:指的是一个标签的属性
    ⑴一个标签的属性一般是由键值对组成,属性名=值
    ⑵<blockquote class="boldest">Extremely bold</blockquote>,其中的'class="boldest"'就是标签的属性

2、一个标签可能有很多个属性

3、获取一个Tag对象的attrs属性,可以使用:Tag对象.attrs

4、使用Tag对象的attrs属性可以把标签对的属性以字典形式返回
    ⑴ Tag对象无属性时返回的是一个空字典

例4:

from bs4 import BeautifulSoup #导入bs4库html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""soup = BeautifulSoup(html,"lxml")   #指定解析器
soup_tag_attrs = soup.attrs #获取整个BeautifulSoup对象的attrs属性
title_tag_attrs = soup.title.attrs #获取title Tag对象的attrs属性
head_tag_attrs = soup.head.attrs #获取head Tag对象的attrs属性
a_tag = soup.a      #获取a标签的Tag对象
a_tag_attrs = a_tag.attrs   #获取a Tag对象的attrs属性print("BeautifulSoup对象的attrs属性为:",soup_tag_attrs)
print("titlea标签的Tag对象的attrs属性为:",title_tag_attrs)
print("heada标签的Tag对象的attrs属性为:",head_tag_attrs)
print("a标签的Tag对象为:",a_tag)
print("a标签的Tag对象的attrs属性为:",a_tag_attrs)"""
BeautifulSoup对象的attrs属性为: {}
titlea标签的Tag对象的attrs属性为: {}
heada标签的Tag对象的attrs属性为: {}
a标签的Tag对象为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
a标签的Tag对象的attrs属性为: {'id': 'link1', 'href': 'http://example.com/elsie', 'class': ['sister']}
"""

注:
1、从上面的输出结果可以看出对于soup对象、head标签对、title标签对来说返回的为空字典:其标签对里面没有属性值以及对应的值(key:value)

2、对应存在key:value的标签:使用attrs方法可以将其所有的属性打印输出了出来,得到的类型是一个字典

3、如果想要单独获取某个属性具体的值时,可以使用下面三种方法:
    ⑴使用字典方法:字典索引、字典get()方法
    ⑵使用tag对象的get()方法:soup对象.标签名.get(属性名)
    ⑶使用soup对象.标签名.属性名(键名)

例5:

from bs4 import BeautifulSoup #导入bs4库# 单独的一个标签也是可以构造为BeautifulSoup对象的
html = """<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>"""soup = BeautifulSoup(html,"lxml")   #指定解析器
print("BeautifulSoup对象为:",soup)print("--------")a_tag_attrs = soup.a.attrs
print("a标签的tag对象的属性为:",a_tag_attrs)a_tag_attrs_href_dict = a_tag_attrs["href"] #使用字典的索引
print("通过字典索引获取到的tag对象的属性",a_tag_attrs_href_dict)print("--------")a_tag_attrs_href_dict1 = soup.a.attrs.get("href") #使用字典的get方法
print("通过字典get方法获取到的tag对象的属性",a_tag_attrs_href_dict1)print("--------")a_tag_attrs_href_get = soup.a.get("href")#使用soup对象.标签名.get(属性名)
print(a_tag_attrs_href_get)a_tag_attrs_href = soup.a["href"]#使用soup对象.标签名.属性名(键名)
print(a_tag_attrs_href )"""
BeautifulSoup对象为: <html><body><a class="sister" href="http://example.com/tillie" id="link3">Tillie</a></body></html>
--------
a标签的tag对象的属性为: {'class': ['sister'], 'href': 'http://example.com/tillie', 'id': 'link3'}
通过字典索引获取到的tag对象的属性 http://example.com/tillie
--------
通过字典get方法获取到的tag对象的属性 http://example.com/tillie
--------
http://example.com/tillie
http://example.com/tillie
"""

注:
1、从上面例子中可以看出要获得标签对中具体属性的值时,共有三种方法:
    ⑴使用字典的方法相对于其他两种来说多了一步,会显得麻烦。不过毕竟字典方法用得比较多,用来很熟悉
    ⑵使用使用soup对象.标签名.属性名方法时:需要注意,需要使用中括号将属性名括起来
    ⑶使用get方法,传入属性的名称,这种方法与上面一种第二种是等价的

多值属性

1、一般情况下,对于标签的属性都是以键值对存在的(一键一值,键=值)。但是某些属性可以存在多个值的情况(一键多值)。这种情况就称为多值属性

2、最常见的多值的属性是 class (一个tag可以有多个CSS的class)。还有一些属性rel , rev , accept-charset , headers , accesskey。在Beautiful Soup中多值属性的返回类型是列表

例5_1:

from bs4 import BeautifulSoupsoup = BeautifulSoup('<p class="body strikeout"></p>',"lxml")print("p标签的tag对象为",soup.p)print("p标签的tag对象的属性为",soup.p.attrs)  #其值为一个字典
print("p标签的class属性为",soup.p.attrs.get("class"))css_soup = BeautifulSoup('<p class="body"></p>',"lxml")
print(css_soup.p['class'])"""
p标签的tag对象为 <p class="body strikeout"></p>
p标签的tag对象的属性为 {'class': ['body', 'strikeout']}
p标签的class属性为 ['body', 'strikeout']['body']
"""

注:
1、如果某个属性看起来好像有多个值,但在任何版本的HTML定义中都没有被定义为多值属性,那么Beautiful Soup会将这个属性作为字符串返回

2、将tag转换成字符串时,多值属性会合并为一个值

3、如果转换的文档是XML格式,那么tag中不包含多值属性

例5_3:

from bs4 import BeautifulSoupcss_soup = BeautifulSoup('<p id="my id"></p>',"lxml")
print(css_soup.p['id'])rel_soup = BeautifulSoup('<p>Back to the <a rel="index">homepage</a></p>',"lxml")
print(rel_soup.a['rel'])#如果转换的文档是XML格式,那么tag中不包含多值属性
xml_soup = BeautifulSoup('<p class="body strikeout"></p>', 'xml')
print(xml_soup.p['class'])"""
my id
['index']
body strikeout
"""

NavigableString

1、NavigableString对象:指的是标签对中的数据

2、字符串常被包含在tag内。BeautifulSoup用NavigableString类来包装tag中的字符串

3、获取一个Tag对象中的数据(NavigableString对象),可以使用:Tag对象.string

4、使用"Tag对象.string"方法返回的数据的类型为NavigableString对象,可以使用str()方法将其转为字符串(Unicode字符串)
    ⑴也可以使用str()方法将一个Tag对象转为字符串

例6:

from bs4 import BeautifulSoup #导入bs4库html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story A</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Tillie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3"><!-- Elsie --></a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""soup = BeautifulSoup(html,"lxml")#指定解析器,创建beautifulsoup对象head_string = soup.head.string
p_string = soup.p.stringa_tag = soup.a
a_tag_string = a_tag.stringprint("header标签中的数据为:",head_string)
print("p标签中的数据为:",p_string)print("a标签的tag对象为:",a_tag)
print("a标签中的数据为:",a_tag_string)
print("a标签中的数据的类型为为:",type(a_tag_string))print("转换数据类型后为:",type(str(a_tag_string))) #使用str()方法将NavigableString对象转为字符串
print("转换数据类型后为--tag对象:",type(str(a_tag))) #使用str()方法将tag对象转为字符串
"""
header标签中的数据为: The Dormouse's story
p标签中的数据为: The Dormouse's story A
a标签的tag对象为: <a class="sister" href="http://example.com/elsie" id="link1">Tillie</a>
a标签中的数据为: Tillie
a标签中的数据的类型为为: <class 'bs4.element.NavigableString'>
转换数据类型后为: <class 'str'>
转换数据类型后为--tag对象: <class 'str'>
"""

BeautifulSoup

BeautifulSoup 对象表示的是一个文档的全部内容。大部分时候可以把它当作Tag对象,是一个特殊的Tag,我们可以分别获取它的类型,名称,以及属性来感受一下

例7:

from bs4 import BeautifulSoup #导入bs4库html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""soup = BeautifulSoup(html,"lxml")#指定解析器,创建beautifulsoup对象soup_name = soup.name
print(soup_name)
print(type(soup_name))soup_attrs = soup.attrs
print(soup_attrs)"""
[document]
<class 'str'>
{}
"""

Comment

Comment 对象是一个特殊类型的NavigableString对象,其实输出的内容仍然不包括注释符号,但是如果不好好处理它,可能会对我们的文本处理造成意想不到的麻烦

例8:找一个带注释的标签

from bs4 import BeautifulSoup #导入bs4库html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""soup = BeautifulSoup(html,"lxml")#指定解析器,创建beautifulsoup对象print("a标签的tag对象为:",soup.a)
print("a标签内的数据为:",soup.a.string)  #a标签内的数据为一个注释
print("a标签内的数据的类型为:",type(soup.a.string))"""
a标签的tag对象为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
a标签内的数据为:  Elsie
a标签内的数据的类型为: <class 'bs4.element.Comment'>
"""

注:a标签里的内容实际上是注释,但是如果我们利用 .string 来输出它的内容,我们发现它已经把注释符号去掉了,所以这可能会给我们带来不必要的麻烦

补充

获取Tag对象

获取某个指定的tag有两种情况:一种是获取指定的第一个标签(这种实际中用得很少),另一种是获取指定的全部标签对

获取指定的第一个标签

获取指定的第一个标签就是使用前面介绍的"soup对象.标签名"

例9:soup对象.标签名

from bs4 import BeautifulSouphtml = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""soup = BeautifulSoup(html,"lxml")#一个<class 'bs4.BeautifulSoup'>tag_p = soup.p
print("p标签对为:",tag_p)tag_a = soup.a
print("a标签对为:",tag_a)"""
p标签对为: <p class="title" name="dromouse"><b>The Dormouse's story</b></p>
a标签对为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
"""

注:由上面的结果可以看出
1、获取某个标签对可以使用:soup对象.标签名

2、只是使用这种方法:只能获得整个文档中第一个符合要求的标签(存在多个一样的标签对时只会返回第一个)

3、如果想要的标签对中镶嵌了其他标签对,那么也会把里面镶嵌的标签对一起返回

4、这种方法在实际运用中发现:不能把标签名定义成变量,就是不能通过变量来批量获得一些标签对,所以这种方法有比较大的局限性

获取指定的全部标签对

1、要获取一个文档中某个指定的所有标签,就需要使用find_all()方法:BeautifulSoup对象或Tag对象都可以使用find_all()或find()方法来找其下面的子标签(只是查找范围不一样:BeautifulSoup对象->整个xml对象内,Tag对象->该Tag对象内)

2、其参数可以是很多类型,最常用的是:传入需要获取的标签的标签名

3、find_all()方法返回的是一个由所有符合要求的标签组成的列表

4、find_all()方法这里只是简单的介绍了,后面会详细介绍

5、个人感觉:就是不管HTML或XML文档中有无重复的标签,都最好用find_all()方法来找对应的Tag对象

例9_1:find_all()

from bs4 import BeautifulSouphtml = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""soup = BeautifulSoup(html,"lxml")tag_body = soup.find_all("p") #获取所有p标签的tag对象
print("p标签对为:",tag_body)tag_a = soup.find_all("a")    #获取所有a标签的tag对象
print("a标签对为:",tag_a)"""
p标签对为: [<p class="title" name="dromouse"><b>The Dormouse's story</b></p>, <p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>, <p class="story">...</p>]
a标签对为: [<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
"""

注:由上面的结果可以看出
1、find_all()方法用于返回整个文档中所有符合要求的标签对:返回值是由所有符合要求的tag对象组成的列表(遍历后就是一个个tsg对象)

2、同样的方法还有find()方法:只是说find()方法只是返回第一个符合要求的标签对

3、使用这种方法的话,就可以将标签名定义成变量,所以感觉这种方法比较好

tag对象的name和attrs属性

1、感觉解析过程就是:soup对象->Tag对象->通过tag对象的name、attrs和另外的string属性来获取想要的数据

2、只要是一个tag对象,就可以使用name、attrs和另外的string属性

例10:

from bs4 import BeautifulSouphtml = """
<html><head><title>The Dormouse's story</title></head> <body> <p class="title"><b>The Dormouse's story</b></p> <p class="story">Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p></body>
</html>"""soup = BeautifulSoup(html,"lxml")tag_a_name = soup.a.name
print("a标签对name属性为:",tag_a_name)tag_a_attrs = soup.a.attrs
print("a标签对attrs属性为:",tag_a_attrs)"""
a标签对name属性为: a
a标签对attrs属性为: {'href': 'http://example.com/elsie', 'class': ['sister'], 'id': 'link1'}
"""

注:
1、可以使用:soup.标签名.attrs或soup.标签名.name来获得标签对的name和attrs属性
    ⑴其实分开来看就是先使用soup.标签名来返回tag对象,然后使用tag对象.name、tag对象.attrs来获得name和attrs,以及tag对象.string来获得标签对之间的数据

2、使用这种方法的话也是:只会返回第一个符合要求的标签名的name和attrs(因为返回的只有一个tag对象)

3、标签对的attrs属性返回值是一个字典,可以对其使用字典的方法

4、tag的属性可以被添加,删除或修改,与字典处理方法一致,如:tag['class'] = 'verybold'

例10_1:

from bs4 import BeautifulSouphtml = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""soup = BeautifulSoup(html,"lxml")def parse_msg(tagName):tags = soup.find_all(tagName) #find_all()返回的是一个由tag对象组成的列表,因此需要遍历for tag in tags:print("标签的tag对象为为:", tag)print("标签的名称为:",tag.name)print("标签的属性为:",tag.attrs)print("标签的数据为:", tag.string)parse_msg("a")
parse_msg("p")"""
标签的tag对象为为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
标签的名称为: a
标签的属性为: {'class': ['sister'], 'href': 'http://example.com/elsie', 'id': 'link1'}
标签的数据为:  Elsie
标签的tag对象为为: <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
标签的名称为: a
标签的属性为: {'class': ['sister'], 'href': 'http://example.com/lacie', 'id': 'link2'}
标签的数据为: Lacie
标签的tag对象为为: <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
标签的名称为: a
标签的属性为: {'class': ['sister'], 'href': 'http://example.com/tillie', 'id': 'link3'}
标签的数据为: Tillie标签的tag对象为为: <p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
标签的名称为: p
标签的属性为: {'class': ['story']}
标签的数据为: None
标签的tag对象为为: <p class="story">...</p>
标签的名称为: p
标签的属性为: {'class': ['story']}
标签的数据为: ...
"""

注:
1、上面的流程就是:先使用find_all()方法获取所有符合要求的tag对象组成的列表,然后遍历出每一个tag对象,最后获得每一个tag对象的name、attrs属性以及string

2、也可以可以使用soup.标签名["属性名"]来获取指定名字的attrs属性

2、这种嵌套在里面的标签对,如果返回的是外层的tag对象,那也只能获得外层tag对象的name和attrs属性

NavigableString对象

1、即可以遍历的字符串:就是被包含在tag内的字符串

例11:

from bs4 import BeautifulSouphtml = """
<html><head><title>The Dormouse's story</title></head> <body> <p class="title"><b>The Dormouse's story</b></p> <p class="story">Once upon a time there were three little sisters; and their names were <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; and they lived at the bottom of a well.</p> <p class="story">...</p></body>
</html>
"""
soup = BeautifulSoup(html,"lxml")tag_a_string = soup.a.string
print("第一个a标签对中的字符串:",tag_a_string)
print(type(tag_a_string))for tag_a_name in  soup.find_all("a"):print("as标签对name属性为:",tag_a_name.string)"""
第一个a标签对中的字符串: Elsie
<class 'bs4.element.NavigableString'>
as标签对name属性为: Elsie
as标签对name属性为: Lacie
as标签对name属性为: Tillie
"""

注:从上面的输出结果可以看出
1、获取标签对中的NavigableString对象,可以使用:soup对象.标签名.string的方法来获取(跟前面name或attrs一样,只是说这里的字符串属于另一个对象)。且这种方法只会返回第一个符合要求的标签对中的字符串

2、也可以先试用find_all()的方法先找出全部符合要求的标签对,然后遍历得到每一个标签对内的字符串

3、返回的是一个NavigableString对象:可以通过str()方法可以直接将NavigableString对象转换成Unicode字符串

4、如果想在Beautiful Soup之外使用NavigableString对象,需要调用str()方法,将该对象转换成普通的Unicode字符串,否则就算Beautiful Soup已方法已经执行结束,该对象的输出也会带有对象的引用地址.这样会浪费内存

5、tag中包含的字符串不能编辑,但是可以被替换成其它的字符串,用replace_with()方法(后面单独介绍吧)

解析XML文档

1、使用BeautifulSoup同样能解析XML文档,解析XML文档的方法、步骤与解析HTML文档一样

2、只是说在解析XML文档时最好指定解析器为"xml"

例12:

from bs4 import BeautifulSouphtml = """
<?xml version="1.0" encoding="utf-8"?>
<data> <time>20200706</time>  <country name="Liechtenstein"> <rank>1</rank>  <year type="year">2008</year>  <year type="month" date="week">11</year>  <gdppc>141100</gdppc>  <neighbor name="Austria" direction="E"/></country>
</data>
"""soup = BeautifulSoup(html, 'xml')   # 使用xml解析器,将一个文件或字符串转为BeautifulSoup对象
# print(type(soup)) #返回一个<class 'bs4.BeautifulSoup'>
# print(soup.prettify()) #格式化输出HTML文件tag_year = soup.find_all("year")  # find_all()方法返回文档中全部的year标签组成的列表
print("year标签对有:", tag_year)
for i in tag_year:print("返回的标签类型为:", type(i))  # 返回的是一个字符串型的Tag对象,可以直接使用str()方法进行强转换print(i.name)   # 通过Tag对象的name属性来获得标签的名字print(i.attrs)  # 通过Tag对象的attrs属性来获得标签的属性(为属性名与属性值组成的字典)print(i.string)  # 通过Tag对象的string属性来获得标签对中的数据(值)"""
year标签对有: [<year type="year">2008</year>, <year date="week" type="month">11</year>]
返回的标签类型为: <class 'bs4.element.Tag'>
year
{'type': 'year'}
2008返回的标签类型为: <class 'bs4.element.Tag'>
year
{'type': 'month', 'date': 'week'}
11
"""

例13:

from bs4 import BeautifulSoup"""
解析目标:将标签名及其数据组成字典
[{标签名:值},{标签名:值}]
"""msg = """
<?xml version="1.0" encoding="utf-8"?>
<breakfast_menu> <food> <name>Belgian Waffles</name>  <price>$5.95</price>  <description>two of our famous Belgian Waffles with plenty of real maple syrup</description>  <calories>650</calories> </food>  <food> <name>Strawberry Belgian Waffles</name>  <price>$7.95</price>  <description>light Belgian waffles covered with strawberries and whipped cream</description>  <calories/></food>
</breakfast_menu>
"""def parse_msg(msg):soup = BeautifulSoup(msg, 'xml')# 通过xml可以看到,我们需要的数据都在"food"标签下面,且"food"标签可以存在一个或多个,# 因此可以先找到"food"标签,然后依次根据"food"标签来找其下面的子标签foods = soup.find_all("food")food_info_list = []for food in foods:# 获取所需标签值# food标签下name标签不会存在多个,因此使用find()方法比较方便,这里只是演示下find_all()方法food_name = food.find_all("name")[0].stringfood_price = food.find("price").stringfood_calories = food.find("calories").stringfood_info = {"name":food_name,"price":food_price,"calories":food_calories}food_info_list.append(food_info)return food_info_listfood_info_list = parse_msg(msg)
print(food_info_list)"""
输出:
[{'name': 'Belgian Waffles', 'calories': '650', 'price': '$5.95'}, {'name': 'Strawberry Belgian Waffles', 'calories': None, 'price': '$7.95'}]
这里是找"标签名:值",也可以用同样的方法来找"标签名:属性值"等等
"""

注:

本文是在按照Beautiful Soup 4.2.0 文档学习时记录的。只是为了方便自己以后学习和搜索的,文章中肯定会有错误或者遗漏的,因此如果有幸被您看到,可以直接参考其官方文档:

https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html#string

Python爬虫:BeautifulSoup库相关推荐

  1. 数据之路 - Python爬虫 - BeautifulSoup库

    一.BeautifulSoup介绍 Beautiful Soup就是Python的一个HTML或XML的解析库,可以用它来方便地从网页中提取数据.Beautiful Soup自动将输入文档转换为Uni ...

  2. python爬虫BeautifulSoup库抓取500彩票网竞彩足球信息并在excel表中对中奖赔率设置格式

    目录 前言 数据的储存 格式设置 代码 结果展示 疑惑 前言 上一篇博客记录了使用BeautifulSoup模块抓取500彩票网竞彩足球赛果及赔率,但最后呈现的数据不够细致和美观,对最终开奖的赔率没有 ...

  3. Python爬虫基础库(RBX)的实践_田超凡

    转载请注明原作者:田超凡 20190410 CSDN博客:https://blog.csdn.net/qq_30056341# Python爬虫基础库RBX指的是:Requests Beautiful ...

  4. Python爬虫扩展库scrapy选择器用法入门(一)

    关于BeutifulSoup4的用法入门请参考Python爬虫扩展库BeautifulSoup4用法精要,scrapy爬虫案例请参考Python使用Scrapy爬虫框架爬取天涯社区小说"大宗 ...

  5. Python爬虫-BeautifulSoup

    Python爬虫-BeautifulSoup Python爬虫-BeautifulSoup "美丽汤"的爱恨 使用 爱丽丝文档示例 标签 遍历 find(),findAll() 综 ...

  6. 已解决(Python爬虫requests库报错 请求异常SSL错误,证书认证失败问题)requests.exceptions.SSLError: HTTPSConnectionPool

    成功解决(Python爬虫requests库报错 请求异常,SSL错误,证书认证失败问题)requests.exceptions.SSLError: HTTPSConnectionPool(host= ...

  7. 【python】python爬虫requests库详解

    1.安装:pip install requests 简介:Requests是一个优雅而简单的Python HTTP库,与之前的urllibPython的标准库相比,Requests的使用方式非常的简单 ...

  8. Python爬虫——Requests 库基本使用

    文章目录 Python爬虫--Requests 库基本使用 1.Requests简介和下载 2.Requests 库基本使用 Python爬虫--Requests 库基本使用 1.Requests简介 ...

  9. Python爬虫 —— urllib库的使用(get/post请求+模拟超时/浏览器)

    Python爬虫 -- urllib库的使用(get/post请求+模拟超时/浏览器) 这里写目录标题 Python爬虫 -- urllib库的使用(get/post请求+模拟超时/浏览器) 1.Py ...

  10. Python爬虫高级库之一的lxml库中,ET.parse()是一个非常重要的方法。它可以将任意XML或HTML格式的文档解析成一个ElementTree对象,...

    Python爬虫高级库之一的lxml库中,ET.parse()是一个非常重要的方法.它可以将任意XML或HTML格式的文档解析成一个ElementTree对象,方便我们对结构化的数据进行处理和分析.在 ...

最新文章

  1. 集员法对3D激光雷达和相机的外部校准
  2. MySQL工作中的实际用_数据库在工作中的应用,以及什么是MySQL?
  3. C++ hamming distance汉明距离算法(附完整源码)
  4. linux主机数据拷贝,linux 服务器之间拷贝文件
  5. 函数的傅立叶展开掐死我吧_关于文章《傅里叶分析之掐死教程》的再一点小思考...
  6. java中和char功能相反的是_JAVA基础语法
  7. Maple: 多项式相乘
  8. 机器学习:神经网络实现中的技巧
  9. jflash烧录教程_Jflash烧录(windows)原理分析
  10. netbeans 插件安装
  11. FreeRTOS-CortexM4-相关函数说明
  12. 通过爬虫获取银行名称
  13. Unity3D之矩阵运用
  14. 在家月入5q+有手机就能赚米,推荐14个让你在家就能挣米的软件
  15. Python实现excel表合入
  16. 老挑毛 win7 linux,老挑毛u盘启动工具下载
  17. JAVA编程思想第四版笔记 十、内部类
  18. Linux下使用libpcap进行网络抓包并保存到文件
  19. 前端工程师和后端工程师的区别?
  20. 游戏开发的数学知识(一)三维向量绕某一向量旋转

热门文章

  1. Puppeteer入门
  2. VUE 返回上一页 不刷新页面、重复进入同一页面created重复执行、每次进入页面时都执行created、vue单页面多路由,前进刷新,返回不刷新
  3. ios分屏_升级iPadOS(13.1)正式版后如何分屏?iPadOS分屏方法
  4. root开启有什么坏处吗,手机开启了root对手机有什么影响吗?
  5. 如何简单理解执行上下文?
  6. es内嵌文档查询_Elasticsearch 7.x Nested 嵌套类型查询 | ES 干货
  7. Section 1.快速排序
  8. 搜狗浏览器的页面静音
  9. 3dmax室内设计,建筑视频
  10. SurfaceView 与 TextureView 详解