Beautiful Soup 库的一个强大功能是可以操作解析后的 HTML 或 XML 文档并修改其内容。Beautiful Soup 库有多种函数执行以下操作:
添加内容或新标签到现有文档中的标签
在现有标签或字符串之前或之后插入内容
清除已有标签的内容
修改标签元素的内容
添加内容
你可以通过在 Tag 对象上调用 append()
方法来添加到现有标签的内容。这与 Python 列表对象的 append()
方法相似。
在下面的例子中,HTML 脚本包含了一个 <p>
标签。通过 append()
方法附加额外文本。
示例
from bs4 import BeautifulSoup
markup = '<p>Hello</p>'
soup = BeautifulSoup(markup, 'html.parser')
print (soup)
tag = soup.p
tag.append(" World")
print (soup)
输出
<p>Hello</p>
<p>Hello World</p>
通过 append()
方法,你可以在现有标签的末尾添加一个新的标签。首先使用 new_tag()
方法创建一个新的 Tag 对象,然后将其传递给 append()
方法。
示例
from bs4 import BeautifulSoup, Tag
markup = '<b>Hello</b>'
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.b
tag1 = soup.new_tag('i')
tag1.string = 'World'
tag.append(tag1)
print (soup.prettify())
输出
<b>
Hello
<i>
World
</i>
</b>
如果你需要向文档添加字符串,可以附加一个 NavigableString
对象。
示例
from bs4 import BeautifulSoup, NavigableString
markup = '<b>Hello</b>'
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.b
new_string = NavigableString(" World")
tag.append(new_string)
print (soup.prettify())
输出
<b>
Hello
World
</b>
从 Beautiful Soup 版本 4.7 开始,Tag
类中增加了 extend()
方法。它会将列表中的所有元素添加到标签中。
示例
from bs4 import BeautifulSoup
markup = '<b>Hello</b>'
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.b
vals = ['World.', 'Welcome to ', 'Yoagoa']
tag.extend(vals)
print (soup.prettify())
输出
<b>
Hello
World.
Welcome to
Yoagoa
</b>
插入内容
与其在末尾添加新的元素,你可以使用 insert()
方法在 Tag
元素的孩子列表中的指定位置添加元素。Beautiful Soup 中的 insert()
方法的行为与 Python 列表对象上的 insert()
方法相似。
在下面的例子中,在 <b>
标签位置 1 处添加了一个新的字符串。结果的解析文档显示了结果。
示例
from bs4 import BeautifulSoup, NavigableString
markup = '<b>Excellent </b><u>from Yoagoa</u>'
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.b
tag.insert(1, "Tutorial ")
print (soup.prettify())
输出
<b>
Excellent
Tutorial
</b>
<u>
from Yoagoa
</u>
Beautiful Soup 也有 insert_before()
和 insert_after()
方法。它们的目的分别是将标签或字符串插入到给定的 Tag
对象之前或之后。下面的代码显示了字符串 "Python Tutorial" 被添加到了 <b>
标签之后。
示例
from bs4 import BeautifulSoup, NavigableString
markup = '<b>Excellent </b><u>from Yoagoa</u>'
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.b
tag.insert_after("Python Tutorial")
print (soup.prettify())
输出
<b>
Excellent
</b>
Python Tutorial
<u>
from Yoagoa
</u>
另一方面,使用 insert_before()
方法,在 <b>
标签之前添加了 "Here is an " 文本。
tag.insert_before("Here is an ")
print (soup.prettify())
输出
Here is an
<b>
Excellent
</b>
Python Tutorial
<u>
from Yoagoa
</u>
清除内容
Beautiful Soup 提供了不止一种方式来移除文档树中的元素内容。每种方法都有其独特的特性。
clear()
方法是最直接的一种。它简单地移除指定 Tag
元素的内容。下面的例子展示了它的使用。
示例
from bs4 import BeautifulSoup, NavigableString
markup = '<b>Excellent </b><u>from Yoagoa</u>'
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.find('u')
tag.clear()
print (soup.prettify())
输出
<b>
Excellent
</b>
<u>
</u>
可以看到 clear()
方法移除了内容,保留了标签。
对于下面的例子,我们解析以下 HTML 文档,并对所有标签调用 clear()
方法。
<html>
<body>
<p> The quick, brown fox jumps over a lazy dog.</p>
<p> DJs flock by when MTV ax quiz prog.</p>
<p> Junk MTV quiz graced by fox whelps.</p>
<p> Bawds jog, flick quartz, vex nymphs.</p>
</body>
</html>
这是使用 clear()
方法的 Python 代码。
示例
from bs4 import BeautifulSoup
fp = open('index.html')
soup = BeautifulSoup(fp, 'html.parser')
tags = soup.find_all()
for tag in tags:
tag.clear()
print (soup.prettify())
输出
<html>
</html>
extract()
方法从文档树中移除标签或字符串,并返回被移除的对象。
示例
from bs4 import BeautifulSoup
fp = open('index.html')
soup = BeautifulSoup(fp, 'html.parser')
tags = soup.find_all()
for tag in tags:
obj = tag.extract()
print ("Extracted:",obj)
print (soup)
输出
Extracted: <html>
<body>
<p> The quick, brown fox jumps over a lazy dog.</p>
<p> DJs flock by when MTV ax quiz prog.</p>
<p> Junk MTV quiz graced by fox whelps.</p>
<p> Bawds jog, flick quartz, vex nymphs.</p>
</body>
</html>
Extracted: <body>
<p> The quick, brown fox jumps over a lazy dog.</p>
<p> DJs flock by when MTV ax quiz prog.</p>
<p> Junk MTV quiz graced by fox whelps.</p>
<p> Bawds jog, flick quartz, vex nymphs.</p>
</body>
Extracted: <p> The quick, brown fox jumps over a lazy dog.</p>
Extracted: <p> DJs flock by when MTV ax quiz prog.</p>
Extracted: <p> Junk MTV quiz graced by fox whelps.</p>
Extracted: <p> Bawds jog, flick quartz, vex nymphs.</p>
你可以提取标签或字符串。下面的例子展示了如何提取 <li>
元素。
示例
html = '''
<ol id="HR">
<li>Rani</li>
<li>Ankita</li>
</ol>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
obj=soup.find('ol')
obj.find_next().extract()
print (soup)
输出
<ol id="HR">
<li>Ankita</li>
</ol>
更改 extract()
语句以移除第一个 <li>
元素的内文。
示例
obj.find_next().string.extract()
输出
<ol id="HR">
<li>Ankita</li>
</ol>
还有一个 decompose()
方法,它从树中移除标签,然后完全销毁该标签及其内容。
示例
html = '''
<ol id="HR">
<li>Rani</li>
<li>Ankita</li>
</ol>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
tag1=soup.find('ol')
tag2 = soup.find('li')
tag2.decompose()
print (soup)
print (tag2.decomposed)
输出
<ol id="HR">
<li>Ankita</li>
</ol>
decomposed
属性返回 True 或 False —— 表明元素是否已被分解。
修改内容
我们将查看 replace_with()
方法,它允许替换标签的内容。
就像 Python 字符串是不可变的一样,NavigableString
也不能就地修改。然而,可以使用 replace_with()
替换标签内的字符串。
示例
from bs4 import BeautifulSoup
soup = BeautifulSoup("<h2 id='message'>Hello, Tutorialspoint!</h2>",'html.parser')
tag = soup.h2
tag.string.replace_with("OnLine Tutorials Library")
print (tag.string)
输出
OnLine Tutorials Library
这里还有一个 replace_with()
的例子。如果你传递一个 BeautifulSoup 对象作为参数给某个函数如 replace_with()
,可以组合两个解析文档。
示例
from bs4 import BeautifulSoup
obj1 = BeautifulSoup("<book><title>Python</title></book>", features="xml")
obj2 = BeautifulSoup("<b>Beautiful Soup parser</b>", "lxml")
obj2.find('b').replace_with(obj1)
print (obj2)
输出
<html><body><book><title>Python</title></book></body></html>
wrap()
方法使用你指定的标签包裹一个元素。它返回新的包装器。
示例
from bs4 import BeautifulSoup
soup = BeautifulSoup("<p>Hello Python</p>", 'html.parser')
tag = soup.p
newtag = soup.new_tag('b')
tag.string.wrap(newtag)
print (soup)
输出
<p><b>Hello Python</b></p>
另一方面,unwrap()
方法用标签内的内容替换掉标签。这对于剥离标记很有用。
示例
from bs4 import BeautifulSoup
soup = BeautifulSoup("<p>Hello <b>Python</b></p>", 'html.parser')
tag = soup.p
tag.b.unwrap()
print (soup)
输出
<p>Hello Python</p>