Beautiful Soup - 修改樹結構



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 版本開始,extend() 方法已新增到 Tag 類中。它將列表中的所有元素新增到標籤中。

示例

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

輸出

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

插入內容

可以使用 **insert()** 方法在 Tag 元素的子元素列表中指定位置新增元素,而不是在末尾新增新元素。Beautiful Soup 中的 insert() 方法的行為類似於 Python 列表物件上的 insert()。

在下面的示例中,一個新的字串被新增到 <b> 標籤的第 1 個位置。生成的解析文件顯示了結果。

示例

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

輸出

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

Beautiful Soup 還具有 **insert_before()** 和 **insert_after()** 方法。它們各自的目的是在給定的 Tag 物件之前或之後插入標籤或字串。以下程式碼顯示了在 <b> 標籤之後新增字串“Python 教程”。

示例

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

輸出

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

另一方面,insert_before() 方法在下面使用,在 <b> 標籤之前新增“這是一個”文字。

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

輸出

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

清除內容

Beautiful Soup 提供了多種方法從文件樹中移除元素的內容。每種方法都有其獨特的特性。

**clear()** 方法是最直接的方法。它簡單地移除指定 Tag 元素的內容。以下示例顯示了其用法。

示例

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

輸出

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

可以提取標籤或字串。以下示例顯示了 antag 被提取。

示例

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()),則可以組合兩個解析的文件。2524

示例

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>
廣告