那么我们现在就来讲讲第一篇老是提到的遍历文档树以及搜索文档树
我们就不拿其他例子了,直接用文档中的例子
from bs4 import BeautifulSoup
html_doc="""
<html><head><title>The Dormouse's story</title></head>
<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>
"""
soup = BeautifulSoup(html_doc)
一个Tag中可能包含多个字符串或者其他的Tag,这些都是这个Tag的子节点。BeautifulSoup提供了许多操纵和遍历子节点的属性(Beautiful Soup中字符串节点不支持这些属性,因为字符串没有子节点)
想要操纵文档书最简单的方法就是直接告诉它你要的tag的name例如你想要其中的<head>标签
那么就可以直接soup.head
你也可以多次调用这个方法例如
但是通过这个方法只能获得当前名字的第一个也就是说只能获得class = "title"的p标签而不是其他的p标签。如果想要所有的标签那么你可以使用find_all()这个标签
可以看到返回的是一个list
tag的.contents属性可以将tag的子节点以列表的方式输出
BeautifulSoup对象一定会有一个子节点,<html>就是其一个子节点。
但是字符串没有.contents属性因为它没有子节点。我们也可以通过tag的.children生成器对tag的子节点进行循环
contents和children属性仅包含tag的直接子节点就像<body>直接子节点<p>而不包括<b>但是<p>节点又包含<b>,<b>节点又包含字符串节点,这种情况下就出现了子孙节点就同上例中我们就可以用.descendants属性来遍历子孙节点
我们再来看一下明显的区别
如果tag只有一个NavigableString类型的子节点或者只有一个子节点那么tag可以使用.string的方法来得到子节点,两种情况输出的内容相同
但是如果tag中包含多个子节点,tag就没有办法确定.string就不知道要调用哪个所以输出的结果是None
如果tag中有多个字符串那么可以用.strings来循环获取
可以用.stripped_strings除去多余空格的内容,全部是空格的行会被忽略掉,段首和段末的空白会被删除
说回文档树,每一个tag或者字符串都会有父节点,啥子事父节点嘞,父节点简单理解就是这个元素上面的一个标签就这个例子来说<title>的父标签是<head>,这个The Dormouse's story字符串的父节点是<title>,文档的顶层节点比如的父节点是 BeautifulSoup 对象,而BeautifulSoup对象的父节点是None。而.parent可以获得一个父节点,而parents可以获得所有父节点。
说完父节点怎么能不说兄弟节点呢,按父节点的来理解兄弟节点那么兄弟节点就表示是同级的标签,也就是同属于一个父节点的标签在文档树中可以用.next_sibling和.previous_sibling来获取兄弟标签。很好理解.previous_sibling可以获得前一个兄弟标签,而.next_sibling可以获得后一个兄弟标签。如果已经是第一个标签那么.previous_sibling将会返回None,.next_sibling同理。但是要记住父节点不同那么两个标签就不是兄弟标签,还有一点要注意这个例子中又这么一段:
第一个a标签的.next_sibling并不是第二个a标签而是逗号和换行符,仔细看第一个标签的最后是一个逗号和换行,所以不难理解咯。而第二个a标签是逗号换行符的.next_sibling。
.next_sibling或.previous_sibling只能的到前一个或者后一个标签,而.next_siblings或.previous_siblings可以得到所有的前标签或者后标签
再来说说,next_element和.previous_element
这俩玩意看着和之前讲的那个很像功能也有点像。先来说说HTML解析器,HTML解析器就是按照顺序依次带或者关闭标签。而.next_element属性是指向解析过程中下一个被解析对象,当然结果可能会和.next_sibling一样但是大部分时候还是不一样。
就以下例子来说
从这里就可以看出区别。那么.next_elements和.previous_elements就不多说了,同上
网友评论