美文网首页Python养成记
27、BeautifulSoup之遍历

27、BeautifulSoup之遍历

作者: 魔方宫殿 | 来源:发表于2022-04-11 00:02 被阅读0次
Life is short, you need Python!

上集回顾:

  1. Tag对象
  2. name属性
  3. attributes属性
  4. 多值属性
  5. 字符串

上集学习了 BeautifulSoup 的 Tag 及其属性。
本集学习最简单的方法得到目标Tag和遍历文档树。

还拿”爱丽丝梦游仙境”的文档来做例子:

html_doc = """
<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>
"""

from bs4 import BeautifulSoup
soup = BeautifulSoup(html_doc, 'html.parser')

通过这段例子来演示怎样从文档的一段内容找到另一段内容

一、Tag的name
操作文档树最简单的方法就是告诉它你想获取的tag的name。如果想获取 <head> 标签,只要用 soup.head :

soup.head
# <head><title>The Dormouse's story</title></head>

soup.title
# <title>The Dormouse's story</title>

这是个获取tag的小窍门,可以在文档树的tag中多次调用这个方法。下面的代码可以获取<body>标签中的第一个<b>标签:

soup.body.b
# <b>The Dormouse's story</b>

通过点取属性的方式只能获得当前名字的第一个tag:

soup.a
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

二、.contents 和 .children
一个Tag可能包含多个字符串或其它的Tag,这些都是这个Tag的子节点.BeautifulSoup提供了许多操作和遍历子节点的属性。
注意: Beautiful Soup中字符串节点不支持这些属性,因为字符串没有子节点。

tag的 .contents 属性可以将tag的子节点以列表的方式输出:

head_tag = soup.head
head_tag
# <head><title>The Dormouse's story</title></head>

head_tag.contents
[<title>The Dormouse's story</title>]

title_tag = head_tag.contents[0]
title_tag
# <title>The Dormouse's story</title>
title_tag.contents
# [u'The Dormouse's story']

BeautifulSoup 对象本身一定会包含子节点,也就是说<html>标签也是 BeautifulSoup 对象的子节点:

len(soup.contents)
# 1
soup.contents[0].name
# u'html'

字符串没有 .contents 属性,因为字符串没有子节点:

text = title_tag.contents[0]
text.contents
# AttributeError: 'NavigableString' object has no attribute 'contents'

通过tag的 .children 生成器,可以对tag的子节点进行循环:

for child in title_tag.children:
    print(child)
    # The Dormouse's story

三、.parent
通过 .parent 属性来获取某个元素的父节点.在例子“爱丽丝”的文档中,<head>标签是<title>标签的父节点:

title_tag = soup.title
title_tag
# <title>The Dormouse's story</title>
title_tag.parent
# <head><title>The Dormouse's story</title></head>

文档title的字符串也有父节点:<title>标签

title_tag.string.parent
# <title>The Dormouse's story</title>

文档的顶层节点比如<html>的父节点是 BeautifulSoup 对象:

html_tag = soup.html
type(html_tag.parent)
# <class 'bs4.BeautifulSoup'>

BeautifulSoup 对象的 .parent 是None:

print(soup.parent)
# None

四、.next_sibling 和 .previous_sibling
看一段简单的例子:

sibling_soup = BeautifulSoup("<a><b>text1</b><c>text2</c></b></a>")
print(sibling_soup.prettify())
# <html>
#  <body>
#   <a>
#    <b>
#     text1
#    </b>
#    <c>
#     text2
#    </c>
#   </a>
#  </body>
# </html>

因为<b>标签和<c>标签是同一层:他们是同一个元素的子节点,所以<b>和<c>可以被称为兄弟节点。一段文档以标准格式输出时,兄弟节点有相同的缩进级别。在代码中也可以使用这种关系。

文档树中,使用 .next_sibling 和 .previous_sibling 属性来查询兄弟节点:

sibling_soup.b.next_sibling
# <c>text2</c>

sibling_soup.c.previous_sibling
# <b>text1</b>

<b>标签有 .next_sibling 属性,但是没有 .previous_sibling 属性,因为<b>标签在同级节点中是第一个.同理,<c>标签有 .previous_sibling 属性,却没有 .next_sibling 属性:

print(sibling_soup.b.previous_sibling)
# None
print(sibling_soup.c.next_sibling)
# None

例子中的字符串“text1”和“text2”不是兄弟节点,因为它们的父节点不同:

sibling_soup.b.string
# u'text1'

print(sibling_soup.b.string.next_sibling)
# None

实际文档中的tag的 .next_sibling 和 .previous_sibling 属性通常是字符串或空白. 看看“爱丽丝”文档:

<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>

如果以为第一个<a>标签的 .next_sibling 结果是第二个<a>标签,那就错了,真实结果是第一个<a>标签和第二个<a>标签之间的顿号和换行符:

link = soup.a
link
# <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>

link.next_sibling
# u',\n'

第二个<a>标签是顿号的 .next_sibling 属性:

link.next_sibling.next_sibling
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>

本集总结:

  1. Tag的name
  2. .contents 和 .children
  3. .parent
  4. .next_sibling 和 .previous_sibling

下集见

相关文章

  • 27、BeautifulSoup之遍历

    上集回顾: Tag对象 name属性 attributes属性 多值属性 字符串 上集学习了 BeautifulS...

  • BeautifulSoup的使用姿势

    BeautifulSoup 是什么 BeautifulSoup库是解析、遍历、维护“标签树”的功能库 安装 注意:...

  • Python的BeautifulSoup包

    pip install BeautifulSoup4 Beautiful Soup库是解析、遍历、维护“标签树”的...

  • BeautifulSoup 遍历和获取

    遍历文档树 直接子节点 要点:.contents .children 属性 .contents tag 的 ....

  • 爬虫之BeautifulSoup(二)--遍历标签树

    遍历标签树 下行遍历 上行遍历 平行遍历 HTML格式化和编码 soup.prettify()

  • BeautifulSoup库-标签解析遍历

    本文主要内容:BeautifulSoup库的介绍,基本元素,标签树的遍历 安装:pip install Beaut...

  • Python之Beautiful Soup库

    Beautiful Soup库是解析、遍历、维护“标签树”的功能库 BeautifulSoup对应一个HTML/X...

  • 爬虫笔记2-解析

    BeautifulSoup 用于解析已经抓取的文件内容。是解析、遍历、维护“标签树”的功能库。 pip insta...

  • 爬虫2

    爬虫之 beautifulsoup BeautifulSoup3目前已经停止开发,推荐现在的项目使用Beautif...

  • 爬虫

    爬虫之 beautifulsoup BeautifulSoup3目前已经停止开发,推荐现在的项目使用Beautif...

网友评论

    本文标题:27、BeautifulSoup之遍历

    本文链接:https://www.haomeiwen.com/subject/lvbbsrtx.html