.children 只可以获取 tag 的直接节点,而获取不到子孙节点,.descendants 可以满足你 。
# demo 6soup = BeautifulSoup(html_doc, "lxml");head_tag=soup.headfor child in head_tag.descendants: print("child is : ", child)# 输出结果child is :<title>index</title>child is :index
父节点通过 .parent 属性获取标签的父亲节点 。title 的父标签是 head,html 的父标签是 BeautifulSoup 对象,而 BeautifulSoup 对象的父标签是 None 。
# demo 7soup = BeautifulSoup(html_doc, "lxml");title_tag=soup.titleprint(title_tag.parent)print(type(soup.html.parent))print(soup.parent)# 输出结果<head><title>index</title></head><class 'bs4.BeautifulSoup'>None
同时,我们可以通过 parents 得到指定标签的所有父亲标签 。
# demo 8soup = BeautifulSoup(html_doc, "lxml");a_tag=soup.afor parent in a_tag.parents:print(parent.name)# 输出结果pbodyhtml[document]
兄弟节点通过 .next_sibling 和 .previous_sibling 来获取下一个标签和上一个标签 。
# demo 9soup = BeautifulSoup(html_doc, "lxml");div_tag=soup.divprint(div_tag.next_sibling)print(div_tag.next_sibling.next_sibling)# 输出结果<p class="content1">...</p>
你可能会纳闷,调用了两次 next_sibling 怎么只有一个输出呢,这方法是不是有 bug 啊 。事实上是 div 的第一个 next_sibling 是div 和 p 之间的换行符 。这个规则对于 previous_sibling 同样适用 。
另外,我们可以通过 .next_siblings 和 .previous_siblings 属性可以对当前节点的兄弟节点迭代输出 。在该例子中,我们在每次输出前加了前缀,这样就可以更直观的看到 dib 的第一个 previous_sibling 是换行符了 。
# demo 10soup = BeautifulSoup(html_doc, "lxml");div_tag=soup.divfor pre_tag in div_tag.previous_siblings: print("pre_tag is : ", pre_tag)# 输出结果pre_tag is :pre_tag is :<p class="main">我常用的网站<a class="website" href=https://www.isolves.com/it/cxkf/yy/Python/2022-07-04/"https://www.google.com" id="google">GoogleBaiduBing
首页
pre_tag is :前进和后退通过 .next_element 和 .previous_element 获取指定标签的前一个或者后一个被解析的对象,注意这个和兄弟节点是有所不同的,兄弟节点是指有相同父亲节点的子节点,而这个前一个或者后一个是按照文档的解析顺序来计算的 。比如在我们的文本 html_doc 中,head 的兄弟节点是 body(不考虑换行符),因为他们具有共同的父节点 html,但是 head 的下一个节点是 title 。即soup.head.next_sibling=title soup.head.next_element=title
# demo 11soup = BeautifulSoup(html_doc, "lxml");head_tag=soup.headprint(head_tag.next_element)title_tag=soup.titleprint(title_tag.next_element)# 输出结果<title>index</title>index
同时这里还需要注意的是 title 下一个解析的标签不是 body,而是 title 标签内的内容,因为 html 的解析顺序是打开 title 标签,然后解析内容,最后关闭 title 标签 。另外,我们同样可以通过 .next_elements 和 .previous_elements 来迭代文档树 。由遗下例子我们可以看出,换行符同样会占用解析顺序,与迭代兄弟节点效果一致 。
# demo 12soup = BeautifulSoup(html_doc, "lxml");div_tag=soup.divfor next_element in div_tag.next_elements: print("next_element is : ", next_element)# 输出结果next_element is :这是注释内容next_element is :next_element is :<p class="content1">...</p>next_element is :...next_element is :next_element is :<p class="content2">...</p>next_element is :...next_element is :next_element is :
Beautiful Soup 总结本章节介绍了 Beautiful Soup 的使用场景以及操作文档树节点的基本操作,看似很多东西其实是有规律可循的,比如函数的命名,兄弟节点或者下一个节点的迭代函数都是获取单个节点函数的复数形式 。同时由于 HTML 或者 XML 这种循环嵌套的复杂文档结构,致使操作起来甚是麻烦,掌握了本文对节点的基本操作,将有助于提高你写爬虫程序的效率 。
【爬虫利器 Beautiful Soup 之遍历文档】
推荐阅读
- python爬虫之爬取疫情数据
- 微信|新一代会议利器:微信Winodws测试版3.7.5.5上线
- 电话|工信部再出反诈利器 “反诈名片”电话可放心接
- 内网穿透利器-ngrok的图文安装
- 爬虫入门必学——常见的几种网站类型
- 爬虫python入门 爬虫人
- 微博上线“专属会员”,大V变现新利器 微博会员有什么好处
- 保住利润的利器 - 外汇对冲交易 请问什么是对冲机制
- nssm,一个可以把任何exe注册为系统服务的利器
- 验房流程介绍 验房利器和注意事项