1. 文档树格式化输出soup.prettify()
还是以官方的示例代码为例,首先进行变量定义,然后再进行代码解析,html案例代码如下
"""<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>"""
代码运行时在spyder里面的Ipython界面进行
进行文档树格式化输出,前面博客有提到过,soup.prettify()方法是将代码以Unicode编码输出,每个XML/HTML标签都独占一行
2. HTML的3个基本要素识别:标签、属性、元素
2.1 标签
● soup.标签名
● 首先要知道有这样找到标签的方法
● 后续主要用.find() / .find_all()来寻找
● soup.标签名.name :返回该标签的名字
● 示例
2.2 属性
● soup.标签名.attrs
●返回属性,对象类型为字典
● soup.标签名[‘属性名’]
●返回该标签的某属性
● 示例
2.3 元素
● soup.标签名.text
●直接输出字符串str
● soup.标签名.text 与 soup.标签名.string → 建议选择前者,按照下面的案例代码进行讲解
'''<html><td>some text</td> <td></td><td><p>more text</p></td><td>even <p>more text</p></td></html>'''
针对同一个案例代码,使用soup.标签名.text 与 soup.标签名.string 方法,输出结果如下
从上面的输出可以看出,td标签里面没有内容时候,.text返回是空,但是.string返回的是None,还有最重要的一点是,如果td标签里面含有子节点的时候,这里面还有内容时,两者的使用区别就显示出来了,对比上面的最后的输出(一个为None,一个将td里面的所有文字内容全部输出),原因在于如果标签包含了多个子节点时,.string 方法无法确定应该调用哪个子节点的内容, 输出结果有可能是 None
3. 搜索文档树
核心方法是:find() 和 find_all(),这里以下面的代码作为案例
"""
<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>
"""
3.1 find(name , attrs, …)
● 寻找标签(如果只有一个标签可以使用.find(),如果是多个就是下面要介绍的方法)
● 可以通过属性寻找
●注意:由于class在Python中是内置语句,所以class的属性应该加下划线:class_
● 可以通过.text直接输出元素
● 示例
3.2 find_all( name , attrs , …)
● 寻找所有tag子节点标签
● 可以寻找多个标签
● 示例
● 寻找多标签某一标签下的文本数据
●可以采用下标的方式进行,如下
3.3 实例讲解(豆瓣读书网址为例)
豆瓣读书,网页如下
首先获取网页信息并解析网页(注意返回的r,要以r.text的形式输入到BeautifulSoup()中)
找一下页标题,一般是只有一个,可以直接使用soup.title
通过检查,进行信息标签查找,可以发现,所有书的相关内容都是在一个大的标签【div class=‘article’】里面,而且,所有具体的书的信息都是在【ul class=‘subject-list’】标签下面,单个书的信息都在【li class=‘subject-item’】内
因此获得单本书所在的标签或者内容,代码实现如下
ul = soup.find('ul', class_ = 'subject-list')
lis = ul.find_all('li')
至此就可以获得每本书对应的标签信息,比如输出第一个标签信息
比如要获得小王子这本书的url,就可以使用如下代码
如果要获取小王子这本书的简介内容,可以使用如下代码
还有其他的一些内容可以获取,这里就介绍到这里
4. 遍历文档树
4.1 节点关系
● 子(Children):一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点
● 父(Parent):每个Tag或字符串都有父节点
● 兄弟(Sibling):同一个元素的子节点可以成为兄弟节点
● 示例
这里还是以官方的代码作为示例
"""
<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>
"""
4.2 子节点
.contents
● 将tag的子节点以列表的方式输出
● 示例(这里就省略了前面的创建soup变量的过程,和之前的一样)
.children
● 生成器,可以对tag的子节点进行循环
● 示例
注意:如果要进行循环的话,这里需要将b_ch = soup.body.children语句再运行一下,如下,才可以输出最终的结果
.descendants
● 可以对所有tag的子孙节点进行递归循环
● 包括子节点,及子节点的子节点(子孙节点)
● 示例(如果使用标签的方式找不到的话,就可以采用这种方式来查找)
4.3 父节点
.parent
● 获取某个元素的父节点(比如获取title的父节点)
.parents
● 递归得到元素的所有父辈节点
● 示例
4.4 兄弟节点
html代码案例
"<a><b>text1</b><c>text2</c></b></a>"
.next_sibling 和 .previous_sibling
● 查询兄弟节点
.next_siblings 和 .previous_siblings
● 对当前节点的兄弟节点迭代输出
● 示例
最后可以尝试使用兄弟节点来查找豆瓣读书里面各本书之间的关系,这里就不叙述了