Beautiful Soup 简明教程

Beautiful Soup - Modifying the Tree

Beautiful Soup 库的一个强大功能是可以操作解析后的 HTML 或 XML 文档并修改其内容。

Beautiful Soup 库具有不同的函数来执行以下操作 -

  1. 向文档的现有标签添加内容或新标签

  2. 在现有标签或字符串之前或之后插入内容

  3. 清除已存在标签的内容

  4. 修改标签元素的内容

Add content

您可以通过在 Tag 对象上使用 append() 方法向现有标签的内容添加内容。它像 Python 的列表对象的 append() 方法一样工作。

在以下示例中,HTML 脚本有一个 <p> 标签。使用 append() 附加附加文本。

Example

from bs4 import BeautifulSoup

markup = '<p>Hello</p>'
soup = BeautifulSoup(markup, 'html.parser')
print (soup)
tag = soup.p

tag.append(" World")
print (soup)

Output

<p>Hello</p>
<p>Hello World</p>

使用 append() 方法,您可以在现有标签的末尾添加新标签。首先使用 new_tag() 方法创建一个新 Tag 对象,然后将其传递给 append() 方法。

Example

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())

Output

<b>
   Hello
   <i>
      World
   </i>
</b>

如果您必须向文档添加字符串,则可以附加 NavigableString 对象。

Example

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())

Output

<b>
   Hello
   World
</b>

从 Beautiful Soup 4.7 版本开始,extend() 方法已添加到 Tag 类中。它将列表中的所有元素添加到标签中。

Example

from bs4 import BeautifulSoup

markup = '<b>Hello</b>'
soup = BeautifulSoup(markup, 'html.parser')

tag = soup.b
vals = ['World.', 'Welcome to ', 'TutorialsPoint']
tag.extend(vals)
print (soup.prettify())

Output

<b>
   Hello
   World.
   Welcome to
   TutorialsPoint
</b>

Insert Contents

您不必在末尾添加新元素,而是可以使用 insert() 方法在 Tag 元素的子项列表中给定位置添加元素。Beautiful Soup 中的 insert() 方法的行为类似于 Python 列表对象上的 insert()。

在以下示例中,新字符串被添加到 <b> 标记,位置为 1。结果解析的文档显示结果。

Example

from bs4 import BeautifulSoup, NavigableString

markup = '<b>Excellent </b><u>from TutorialsPoint</u>'
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.b

tag.insert(1, "Tutorial ")
print (soup.prettify())

Output

<b>
   Excellent
   Tutorial
</b>
<u>
   from TutorialsPoint
</u>

Beautiful Soup 还有 insert_before()insert_after() 方法。它们的各自目的是在指定标记对象之前或之后插入标记或字符串。以下代码显示字符 "Python Tutorial" 添加到了 <b> 标记之后。

Example

from bs4 import BeautifulSoup, NavigableString

markup = '<b>Excellent </b><u>from TutorialsPoint</u>'
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.b

tag.insert_after("Python Tutorial")
print (soup.prettify())

Output

<b>
   Excellent
</b>
Python Tutorial
<u>
   from TutorialsPoint
</u>

另一方面, insert_before() 方法如下使用,以在 <b> 标记之前添加 “Here is an” 字符。

tag.insert_before("Here is an ")
print (soup.prettify())

Output

Here is an
<b>
   Excellent
</b>
Python Tutorial
<u>
   from TutorialsPoint
</u>

Clear the Contents

Beautiful Soup 提供多种方法,从文档树中删除元素的内容。这些方法各自具有独特的功能。

clear() 方法最为直接。它仅仅删除指定标记元素的内容。以下示例显示了它的使用情况。

Example

from bs4 import BeautifulSoup, NavigableString

markup = '<b>Excellent </b><u>from TutorialsPoint</u>'
soup = BeautifulSoup(markup, 'html.parser')
tag = soup.find('u')

tag.clear()
print (soup.prettify())

Output

<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 代码如下

Example

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())

Output

<html>
</html>

extract() 方法从文档树中删除标记或字符串,并返回已删除的对象。

Example

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)

Output

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>

你可以提取标记或字符串。以下示例显示提取一个标记。

Example

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)

Output

<ol id="HR">
   <li>Ankita</li>
</ol>

更改 extract() 语句以删除第一个 <li> 元素的内文本。

Example

obj.find_next().string.extract()

Output

<ol id="HR">
   <li>Ankita</li>
</ol>

另一种方法 decompose() 从树中删除标记,然后完全销毁它及其内容 −

Example

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)

Output

<ol id="HR">

<li>Ankita</li>
</ol>

分解的属性返回 True 或 False - 表示元素是否已分解。

Modify the Contents

我们将着眼于 replace_with() 方法,该方法允许替换标记的内容。

正如 Python 字符串一样(不可变),NavigableString 也不能就地修改。但是,使用 replace_with() 可以将标记的内部字符串替换为另一个字符串。

Example

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)

Output

OnLine Tutorials Library

这里有另一个示例,演示了 replace_with() 的用法。如果将 BeautifulSoup 对象作为参数传递给某些函数,例如 replace_with(),则可以合并两个已解析的文档。

Example

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)

Output

<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)

Output

<p><b>Hello Python</b></p>

另一方面, unwrap() 方法用标记中的内容替换该标记。这适合用于剥离标记。

Example

from bs4 import BeautifulSoup

soup = BeautifulSoup("<p>Hello <b>Python</b></p>", 'html.parser')
tag = soup.p
tag.b.unwrap()

print (soup)

Output

<p>Hello Python</p>