概述
Python网络爬虫与信息提取笔记01-Requests库入门
Python网络爬虫与信息提取笔记02-网络爬虫之“盗亦有道"
Python网络爬虫与信息提取笔记03-Requests库网络爬虫实战(5个实例)
本文索引:
- BeautifulSoup库的安装
- BeautifulSoup库的基本元素
- 基于bs4库的HTML内容遍历方法
- 基于bs4库的HTML格式化和编码
1、Beautiful Soup库安装
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。Beautiful Soup会帮你节省数小时甚至数天的工作时间。
安装只有一步,我们使用管理员权限打开cmd,输入下面这串代码
pip install beautifulsoup4
这样就算完成了。
下面我们测试一下库的安装,演示HTML页面地址:https://python123.io/ws/demo.html
1、我们打开这个页面,是这样的,然后鼠标右键打开网页源代码
2、那么我们之前学到的requests库的get方法,就可以获取这个网页的源代码,那么我们结合requests库和新安装的BeautifulSoup库来试一下。首先打开IDLE,导入requests库,获取到这个hyml页面的源代码内容
3、接着我们先将这个代码内容赋给变量demo,然后导入BeautifulSoup库,导入使用语句是
from bs4 import BeautifulSoup
然后使用一个soup变量,对刚才的demo变量进行解析处理,其中使用的html参数parser,就是用来解析格式的。最后输出美化后的代码:
我们看到输出的页面是已经处理过的,这说明我们的BeautigulSoup库也安装成功了。
其实其中最关键的就是这两行代码:
from bs4 import BeautifulSoup
soup = BeautifulSoup('<p>data</p>','html.parser')
第一行为导入库,第二行中的连个参数分别是:
- <p>data</p>:表示需要解析的html格式的信息,也可先将其付给一个变量,再传进来
- html.parser:这个是要解析html格式所需的解析器。
2、BeatifulSoup库的基本元素
- 对Beautiful Soup库的理解
我们知道,html是一组尖括号<>组织起来的一组标签所组成的内容,标签之间存在上下游关系,形成一个所谓的“标签树”,像上面那样的html内容,所以我们可以理解Beautiful Soup库是解析、遍历、维护“标签树”的功能库。
- Beautiful Soup库的引用
一般情况下,我们最常使用的是from bs4 import BeautifulSoup,这一种说明是我们从bs4库中引入一个类,叫BeautifulSoup,注意这里B和S大写。
我们怎么理解Beautiful Soup类呢?
一般的这个类用来解析的html或者xml的文档,这个文档与标签树是一一对应的,经过BeautifulSoup库的转换,我么就可以理解为将其转换成了一个Beautiful Soup类,这个Beautiful Soup类就可以代替这个标签树,
- 前面我们提到了HTML解析器,其实beautifulsoup还提供了另外4种解析器
解析器 | 使用方法 | 条件 |
bs4的HTML解析器 | BeautifulSoup(mk,'html.parser') | 安装bs4库 |
lxml的HTML解析器 | BeautifulSoup(mk,'lxml') | pip install lxml |
lxml的XML解析器 | BeautifulSoup(mk,'xml') | pip install lxml |
html5lib的解析器 | BeautifulSoup(mk,'html5lib') | pip install html5lib |
- Beautiful Soup类的基本元素
基本元素 | 说明 |
Tag | 标签,最基本的信息组织单元,分别用<>和</>标明开头和结尾 |
Name | 标签的名字,<p>...</p>的名字是'p',格式:<tag>.name |
Attributes | 标签的属性,字典形式组织,格式:<tag>.attrs |
NavigableString | 标签内非属性字符串,<>...</>中字符串,格式:<tag>.string |
Comment | 标签内字符串的注释部分,一种特殊的Comment类型 |
为了更好的理解Beautiful Soup类的基本元素,我们来回顾一下前面的demo实例:
有一个demo示例页面:http://python123.io/ws/demo.html,通过下面这行代码我们可以获得页面的内容,并将其赋值给demo变量。
>>> import requests
>>> r = requests.get("http://python123.io/ws/demo.html")
>>> r.status_code
200
>>> r.text
'<html><head><title>This is a python demo page</title></head>rn<body>rn<p class="title"><b>The demo python introduces several python courses.</b></p>rn<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:rn<a href="http://www.icourse163.org/course/BIT-268001" class="py1" id="link1">Basic Python</a> and <a href="http://www.icourse163.org/course/BIT-1001870001" class="py2" id="link2">Advanced Python</a>.</p>rn</body></html>'
>>> demo = r.text
1、下面我们说一下获得tag标签的方法,代码如下:
这时,soup变量表示的内容是解析后的demo界面,这时打印出的title界面就是我们浏览器左上方显示信息的地方,这个标签表示的就是那个位置的信息的内容,
下面我们来获取html中.a标签即链接标签的内容,并将其打印(soup.tag返回html文本中第一个标签):
2、获取标签名字的方法
我们不在赘述前面demo变量的定义,直接给出获取标签名字的代码,其中.parent.name是获取标签上一级标签的名称
>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup(demo,"html.parser")
>>> soup.a.name
'a'
>>> soup.a.parent.name
'p'
>>> soup.a.parent.parent.name
'body'
>>>
3、获取标签的属性
我们可以接着上面的代码接着写,直接获取属性的值:
>>> tag = soup.a
>>> tag.attrs
{'href': 'http://www.icourse163.org/course/BIT-268001', 'class': ['py1'], 'id': 'link1'}
>>> tag.attrs['class']
['py1']
>>> type(tag.attrs)
<class 'dict'>
>>> type(tag)
<class 'bs4.element.Tag'>
>>>
这里,我们可以查看标签属性的类型是字典,标签的类型是标签类型,tag.attrs是直接返回整个字典,我们也可以用tag.attrs['class']查看其中属性为键为class的属性值,注意tag标签的属性有0或多个类型,但总能返回一个字典来表示。
4、NavigableString元素
它表示的是标签<>...</>中的字符串信息,我们来查看一下各个标签中的字符串信息:
我们可以看到,各个标签<>之间的内容,如soup.a.string表示的就是<a>...<a>之间的内容,但不包括其他的标签名称,比如我们发现soup.p.string返回的内容并不包括其<>...<>中间的<b>内容,既可以跨越多个标签层次。
5、Comment元素
表示标签内注释的部分,我们查看这段注释的内容和类型,代码如下(注意,格式里面的!--..--被去掉了):
>>> newsoup = BeautifulSoup("<b><!--This is a comment--></b><p>This is not a comment</p>","html.parser")
>>> newsoup.b.string
'This is a comment'
>>> type(newsoup.b.string)
<class 'bs4.element.Comment'>
>>> type(newsoup.p.string)
<class 'bs4.element.NavigableString'>
>>>
这里面的5种元素只是BeautifulSoup库的基本使用,后面的实际案例中会更多的使用。
3、基于bs4库的HTML内容遍历方法
首先我们来回顾一下之前所示例的那个demo实例,因为我们要频繁使用这个例子。
>>> import requests
>>> r = requests.get("http://python123.io/ws/demo.html")
>>> r.status_code
200
>>> r.text
'<html><head><title>This is a python demo page</title></head>rn<body>rn<p class="title"><b>The demo python introduces several python courses.</b></p>rn<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:rn<a href="http://www.icourse163.org/course/BIT-268001" class="py1" id="link1">Basic Python</a> and <a href="http://www.icourse163.org/course/BIT-1001870001" class="py2" id="link2">Advanced Python</a>.</p>rn</body></html>'
>>> demo = r.text
>>> demo
'<html><head><title>This is a python demo page</title></head>rn<body>rn<p class="title"><b>The demo python introduces several python courses.</b></p>rn<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:rn<a href="http://www.icourse163.org/course/BIT-268001" class="py1" id="link1">Basic Python</a> and <a href="http://www.icourse163.org/course/BIT-1001870001" class="py2" id="link2">Advanced Python</a>.</p>rn</body></html>'
>>>
我们可以看到输出的text内容是杂乱的,按照上一篇BeautifulSoup库入门,我们可以对他进行美化程一个树形结构,代码为:
from bs4 import BeautifulSoup
soup = BeautifulSoup(demo,"html.parser")
print(soup.prettify())
我们将其的结构抽象出来就是这样一个树形结构:
这样来看如果我们要遍历这个树形结构,就有三种方式,如图中的下行遍历、上行遍历和平行遍历(左->右)。
下面分别介绍一下这三种遍历方法:
- 标签树的下行遍历:
属性 | 说明 |
---|---|
.contents | 子节点的列表,将<tag>所有儿子结点存入列表 |
.children | 子节点的迭代类型,与.contents类似,用于循环遍历儿子节点 |
.descendants | 子孙节点的迭代类型,包含所有子孙节点,用于循环遍历 |
我们用代码来看一下:
>>> soup = BeautifulSoup(demo,"html.parser")
>>> soup.head
<head><title>This is a python demo page</title></head>
>>> soup.head.contents
[<title>This is a python demo page</title>]
>>> soup.body
<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>
>>> soup.body.contents
['n', <p class="title"><b>The demo python introduces several python courses.</b></p>, 'n', <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>, 'n']
>>> len(soup.body.contents)
5
>>> soup.body.contents[1]
<p class="title"><b>The demo python introduces several python courses.</b></p>
>>>
我们可以看出,我们返回的head.contents的类型是一个列表类型,也就是我们可以用列表的方式进行遍历,其中还可以使用len()方法求这个列表的长度,用下标进行遍历,下标数值从0开始表示第一个。
# 遍历儿子节点
for child in soup.body.children:
print(child)
# 遍历子孙节点
for child in soup.body.children:
print(child)
- 标签树的上行遍历
属性 | 说明 |
---|---|
.parent | 节点的父亲标签 |
.parents | 节点先辈标签的迭代类型,用于循环遍历先辈节点 |
看代码:
>>> soup = BeautifulSoup(demo,"html.parser")
>>> soup.title.parent
<head><title>This is a python demo page</title></head>
>>> soup.html.parent
<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.parent
>>>
我们可以看到,soup.title的父亲标签就是head,而html标签就是树的根节点了,为最高级标签,所以他的父亲标签还是它本身,soup本身的标签则为空,没有返回任何标签,而事实上如果使用循环已知往上进行遍历最终会遍历到soup,所以我们用下面这个循环来进行上行遍历:
>>> for parent in soup.a.parents:
if parent is None:
print(parent)
else:
print(parent.name)
p
body
html
[document]
>>>
- 标签树的平行遍历
属性 | 说明 |
---|---|
.next_sibling | 返回按照HTML文本顺序的下一个平行节点标签 |
.previous_sibling | 返回按照HTML文本顺序的上一个平行节点标签 |
.next_siblings | 迭代类型,返回按照HTML文本顺序的后续所有平行节点标签 |
.previous_siblings | 迭代类型,返回按照HTML文本顺序的前续所有平行节点标签 |
条件:平行遍历发生在同一父亲节点下的各节点间
>>> soup.a.next_sibling
' and '
>>> soup.a.previous_sibling
'Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:rn'
>>> soup.a.next_sibling.next_sibling
<a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">Advanced Python</a>
>>> soup.a.previous_sibling
'Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:rn'
>>> soup.a.previous_sibling.previous_sibling
>>>
我们发现,a标签的下一个标签节点是一个字符串类型,而不是标签类型,这是因为html虽然是由标签类型构成的树形结构,但其实各个标签节点之间还有其他类型的节点,如这个'and',其他的都同上面方法一样。
# 遍历后续节点
for sinling in soup.a.next)siblings:
print(sibling)
# 遍历前续节点
for sibling in soup.a.previous_siblings:
print(sibling)
4、基于bs4库的HTML格式化和编码
我们之前说到,bs4库的内容遍历方法,那么如何让html的内容更加友好的显示,还记得我们之前提到的demo实例,首先我们用requests库或的demo的html代码,再用beautifulsoup库的prettify()库来打印:
>>> import requests
>>> r = requests.get("http://python123.io/ws/demo.html")
>>> r.status_code
200
>>> demo = r.text
>>> demo
'<html><head><title>This is a python demo page</title></head>rn<body>rn<p class="title"><b>The demo python introduces several python courses.</b></p>rn<p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:rn<a href="http://www.icourse163.org/course/BIT-268001" class="py1" id="link1">Basic Python</a> and <a href="http://www.icourse163.org/course/BIT-1001870001" class="py2" id="link2">Advanced Python</a>.</p>rn</body></html>'
>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup(demo,"html.parser")
>>> soup.prettify()
'<html>n <head>n <title>n This is a python demo pagen </title>n </head>n <body>n <p class="title">n <b>n The demo python introduces several python courses.n </b>n </p>n <p class="course">n Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses:n <a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">n Basic Pythonn </a>n andn <a class="py2" href="http://www.icourse163.org/course/BIT-1001870001" id="link2">n Advanced Pythonn </a>n .n </p>n </body>n</html>'
>>> print(soup.prettify())
<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>
>>>
可以看出,在我们使用prettify()方法输出之前,demo获取的r.text的内容是格式混乱的,当我们使用prettify()方法但并未实际输出时,每一个语句后会多出来一个n换行符,且会有一定的空格,这说明已经将内容格式美化了,当我们使用输出语句输出美化后的demo内容时,就会输出格式明朗的"标签树"结构内容。
其实prettify()方法还可以对其中给一个标签的内容进行美化,如下面这个:
>>> print(soup.a.prettify())
<a class="py1" href="http://www.icourse163.org/course/BIT-268001" id="link1">
Basic Python
</a>
>>>
这里需要强调的一点就是prettify()方法可以将html内容自动转换成utf-8的编码格式,这是一种国际通用的支持第三方国家语言显示的编码格式,如下面这个例子:
>>> soup = BeautifulSoup("<p>中文</p>","html.parser")
>>> soup.p.string
'中文'
>>> print(soup.p.prettify())
<p>
中文
</p>
>>>
python之路任重道远,加油!!!
最后
以上就是害怕画板为你收集整理的Python网络爬虫与信息提取笔记04-Beautiful Soup库入门的全部内容,希望文章能够帮你解决Python网络爬虫与信息提取笔记04-Beautiful Soup库入门所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复