BeautifulSoup学习笔记(二)

上回学到了遍历文档树,现在来通过“爱丽丝梦游仙境”这段例子学习从文档的一段内容找另一段内容。

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 sister; and their names were
<a href = "http://example.com/elisie" class = "sister" id = "link1">Elisie</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可能包含多个字符串或其他的Tag,这些都是这个Tag的子节点。BeautifulSoup提供了许多操作和遍历子节点的属性。
注意:BeautifulSoup中字符串节点不支持这些属性,因为字符串没有子节点

tag的名字


操作文档树最简单的方法就是告诉它你想获取的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>

如果想要得到所有的<a>标签,或是通过名字得到比一个tag更多的内容的时候,就需要用到Search the tree中描述的方法。比如:find_all()或findAll()

soup.findAll('a')
# [<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>, 
# <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, 
# <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

findAll()将会返回一个列表

.contents和.children


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>]
head_tag.contents[0]
# <title>The Dormouse's story</title>
head_tag.contents[1]
# The Dormouse's story

html标签是BeautifulSoup对象的子节点,字符串没有子节点,所以它没有.contents属性:

len(soup.contents)
# 1
soup.contents[0].name
# html
text = soup.title.contents[0]
text.contents
# AttributeError: 'NavigableString' object has no attribute 'contents'

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

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

子孙节点 .descendants


.contents和.children属性仅包含了tag的直接子节点。例如,<head>标签只有一个直接子节点<title>

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

但是<title>标签也包含了一个子节点:字符串“The Dormouse's story”,这种强开下字符串“The Dormouse's story”也属于<head>标签的子孙节点。.descendants属性可以对所有的tag的子孙节点进行递归循环:

for child in head_tag.descendants:
    print(child)
# <title>The Dormouse's story</title>
# The Dormouse's story

上面的例子中,<head>标签只有一个子节点,但是有2个子孙节点:<title>节点和<title>的子节点,BeautifulSoup有一个直接子节点(html节点),却又很多子孙节点:

len(list(soup.children))
# 1
len(list(soup.descendants))
# 25
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容