概要
Beautiful Soup で DOM ツリーに要素を追加したり、既存の要素を削除する方法を解説します。
関連記事
[blogcard url=”https://pystyle.info/scraping-beautiful-soup-how-to-find-elements”]
[blogcard url=”https://pystyle.info/scraping-beautiful-soup-how-to-refer-elements”]
機能一覧
メソッド | 概要 |
---|---|
append(要素) |
子要素の末尾に追加する |
extend(要素) |
子要素の末尾に複数追加する |
`insert(i, 要素) | I 番目の子要素の直前に追加する |
insert_before(要素) |
この要素の直前に追加する |
insert_after'(要素) |
この要素の直後に追加する |
clear() |
この要素の子孫を削除する |
extract() |
この要素を DOM ツリーから削除して返す |
decompose() |
この要素を DOM ツリーから削除する |
replace_with(要素) |
この要素を指定した要素で置き換える |
wrap(要素) |
この要素を指定した要素で囲む |
unwrap() |
この要素 (子孫は含まない) を DOM ツリーから削除する |
prettify() |
この要素を整形した HTML 文字列にして返す |
str(要素) |
この要素を HTML 文字列にして返す |
encode() |
この要素を UTF8 でエンコードされた HTML 文字列にして返す |
要素名を変更する
Tag.name
に文字列を代入することで、要素名を変更できます。
from bs4 import BeautifulSoup
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
# 要素名を変更する。
soup.b.name = "blockquote"
print(soup)
<html><body><blockquote class="boldest">Extremely bold</blockquote></body></html>
属性値を変更、追加、削除する
Tag[<AttributeName>]
に値を代入した場合、指定した属性が存在すれば属性値の変更、存在しない場合は新しく属性を追加することになります。また、属性は del
で削除できます。
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
# 属性値を変更する。
soup.b["class"] = "verybold"
# 属性を追加する。
soup.b["id"] = 1
print(soup)
# 属性を削除する。
del soup.b["class"]
print(soup)
<html><body><b class="verybold" id="1">Extremely bold</b></body></html> <html><body><b id="1">Extremely bold</b></body></html>
値を変更する
Tag.string
に文字列を代入することで、要素の値を変更できます。
soup = BeautifulSoup('<a href="http://example.com/">I linked to <i>example.com</i></a>')
# 値を変更する。
soup.a.string = "New link text."
print(soup.a)
<a href="http://example.com/">New link text.</a>
子を追加する
子要素の末尾に追加する
Tag.append(要素 or 文字列)
で子要素の末尾に文字列や要素を追加できます。
# "a" 要素の子に文字列 "Bar" を追加する。
soup = BeautifulSoup("<a>Foo</a>")
soup.a.append("Bar")
print(soup)
# タグを追加したい場合は new_tag() でまずタグを作成する。
soup = BeautifulSoup("<b></b>")
new_tag = soup.new_tag("a", href="http://www.example.com")
# "a" 要素の子に文字列 "a" 要素を追加する。
soup.b.append(new_tag)
print(soup)
<html><body><a>FooBar</a></body></html> <html><body><b><a href="http://www.example.com"></a></b></body></html>
Tag.extend(要素 or 文字列)
で子要素の末尾に複数の文字列や要素を追加できます。
# "a" 要素の子に文字列 "Soup", "Guide" を追加する。
soup = BeautifulSoup("<a>Beautiful</a>")
soup.a.extend(["Soup", "Guide"])
print(soup)
<html><body><a>BeautifulSoupGuide</a></body></html>
指定した子要素の直前に追加する
Tag.insert(n, 要素 or 文字列)
で n
番目の子要素の直前に文字列や要素を追加できます。
# "a" 要素の子に "Bar" を挿入する。
soup = BeautifulSoup("<a>Foo</a>")
soup.a.insert(0, "Bar")
print(soup)
<html><body><a>BarFoo</a></body></html>
兄弟要素を追加する
指定した要素の直前に追加する
Tag.insert_before(要素 or 文字列)
でこの要素の直前に要素や文字列を追加できます。
# "b" 要素の直前に挿入する。
soup = BeautifulSoup("<b>stop</b>")
tag = soup.new_tag("i")
soup.b.insert_before(tag)
print(soup)
<html><body><i></i><b>stop</b></body></html>
指定した要素の直後に追加する
Tag.insert_after(要素 or 文字列)
でこの要素の直後に要素や文字列を追加できます。
# "b" 要素の直後に挿入する。
soup = BeautifulSoup("<b>stop</b>")
tag = soup.new_tag("i")
soup.b.insert_after(tag)
print(soup)
<html><body><b>stop</b><i></i></body></html>
削除する
子孫ノードを削除する
Tag.clear()
でこの要素のすべての子孫要素を削除できます。
soup = BeautifulSoup('<a href="http://example.com/">I linked to <i>example.com</i></a>')
print(soup.a)
# "a" 要素の子孫をすべて削除する。
soup.a.clear()
print(soup.a)
<a href="http://example.com/">I linked to <i>example.com</i></a> <a href="http://example.com/"></a>
この要素を DOM ツリーから削除して返す
Tag.extract()
でこの要素を DOM ツリーから削除して返します。
soup = BeautifulSoup('<a href="http://example.com/">I linked to <i>example.com</i></a>')
# "i" 要素を DOM ツリーから削除して、その要素を返す。
removed_tag = soup.i.extract()
print(removed_tag)
print(soup)
<i>example.com</i> <html><body><a href="http://example.com/">I linked to </a></body></html>
この要素を DOM ツリーから削除する
Tag.decompose()
でこの要素を DOM ツリーから削除します。
soup = BeautifulSoup('<a href="http://example.com/">I linked to <i>example.com</i></a>')
# "i" 要素を DOM ツリーから削除する。
soup.i.decompose()
print(soup)
<html><body><a href="http://example.com/">I linked to </a></body></html>
この要素のみを DOM ツリーから削除する
Tag.extract()
や Tag.decompose()
との違い、Tag.unwrap()
はこの要素のみを削除し、その子孫要素はそのまま残します。
soup = BeautifulSoup('<a href="http://example.com/">I linked to <i>example.com</i></a>')
# "i" 要素を取り除く。
soup.a.i.unwrap()
print(soup)
<html><body><a href="http://example.com/">I linked to example.com</a></body></html>
要素を置換する
Tag.replace_with(要素 or 文字列)
でこの要素を指定した要素や文字列で置換します。
soup = BeautifulSoup('<a href="http://example.com/">I linked to <i>example.com</i></a>')
b_tag = soup.new_tag("b")
b_tag.string = "example.net"
# "i" タグを "b" タグに置換する。
soup.a.i.replace_with(b_tag)
print(soup)
<html><body><a href="http://example.com/">I linked to <b>example.net</b></a></body></html>
指定した要素で囲む
Tag.wrap(要素)
でこの要素を指定した要素で囲みます。
soup = BeautifulSoup("<p>I wish I was bold.</p>")
# "p" 要素の値を "b" 要素で囲む。
b_tag = soup.p.string.wrap(soup.new_tag("b"))
print(b_tag)
print(soup)
<b>I wish I was bold.</b> <html><body><p><b>I wish I was bold.</b></p></body></html>
DOM ツリーを HTML で出力する
整形した HTML で出力する
Tag.prettify()
で指定した要素以下を整形された HTML 文字列に変換して返します。
formatter="html"
を指定した場合、Unicode 文字は HTML エンティティに変換します。
soup = BeautifulSoup("<p>Il a dit <<Sacré bleu!>></p>")
print(soup.prettify())
# Unicode 文字は HTML エンティティに変換して出力する。
# é が é に変換されている。
print(soup.prettify(formatter="html"))
<html> <body> <p> Il a dit <<Sacré bleu!>> </p> </body> </html> <html> <body> <p> Il a dit <<Sacré bleu!>> </p> </body> </html>
formatter="html5"
を指定した場合、空要素 br
は /
を付けないで変換します。
soup = BeautifulSoup("<br>")
print(soup.prettify())
soup = BeautifulSoup("<br>")
print(soup.prettify(formatter="html5"))
<html> <body> <br/> </body> </html> <html> <body> <br> </body> </html>
formatter=None
を指定した場合、なにも修正せずにそのまま変換します。
soup = BeautifulSoup("<br>")
# 何も変更を加えずに表示する。
print(soup.prettify(formatter=None))
<html> <body> <br/> </body> </html>
整形せずに HTML で出力する
str(Tag)
で指定した要素以下を HTML 文字列に変換できます。また、Tag.encode()
で UTF8 でエンコードしたバイト列に変換できます。
soup = BeautifulSoup("<p>Il a dit <<Sacré bleu!>></p>")
print(str(soup))
print(soup.encode())
<html><body><p>Il a dit <<Sacré bleu!>></p></body></html> b'<html><body><p>Il a dit <<Sacr\xc3\xa9 bleu!>></p></body></html>'
連続する NavigableString
を1つに統合する
DOM ツリーを編集して、連続した NavigableString
ができてしまった場合に、Tag.smooth()
を呼び出すことで1つに統合できます。
soup = BeautifulSoup("<a>Foo</a>")
soup.a.append("Hoge")
soup.a.append("Fuga")
root (BeautifulSoup) └── html (Tag) └── body (Tag) └── a (Tag) ├── 'Foo' (NavigableString) ├── 'Hoge' (NavigableString) └── 'Fuga' (NavigableString)
soup.smooth()
root (BeautifulSoup) └── html (Tag) └── body (Tag) └── a (Tag) └── 'FooHogeFuga' (NavigableString)
コメント