Pynote

Python、機械学習、画像処理について

スクレイピング - Beautiful Soup の DOM ツリーの編集方法 まとめ

要素名を変更する。

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b

# 要素名を変更する。
tag.name = 'blockquote'

print(tag)
# <blockquote class="boldest">Extremely bold</blockquote>

属性を変更、追加、削除する。

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b

# 属性値を変更する。
tag['class'] = 'verybold'

# 属性を追加する。
tag['id'] = 1

# 属性を削除する。
del tag['class']
print(tag)
# <b id="1">Extremely bold</b>

値を変更する。

html = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(html)
tag = soup.a

# 値を変更する。
tag.string = 'New link text.'
print(tag)
# <a href="http://example.com/">New link text.</a>

子を追加する。

子 (値) を1つ追加する。

soup = BeautifulSoup('<a>Foo</a>')

# a 要素に子 'Bar' を追加する。
# 文字列を指定した場合、NavigableString('Bar') を意味する。
soup.a.append('Bar')
print(soup)
# <html><body><a>FooBar</a></body></html>

soup = BeautifulSoup('<a>Foo</a>')

# a 要素に子 NavigableString('Bar') を追加する。
soup.a.append(NavigableString('Bar'))
print(soup)
# <html><body><a>FooBar</a></body></html>

子 (要素) を1つ追加する。

soup = BeautifulSoup('<b></b>')

# タグを追加したい場合は new_tag() でまずタグを作成する。
new_tag = soup.new_tag('a', href='http://www.example.com')
soup.b.append(new_tag)
print(soup)
# <html><body><b><a href="http://www.example.com"></a></b></body></html>

子を複数追加する。

soup = BeautifulSoup('<a>Beautiful</a>')

# a 要素に子 'Soup', 'Guide' を追加する。
soup.a.extend(['Soup', 'Guide'])
print(soup)
# <html><body><a>BeautifulSoupGuide</a></body></html>

要素を挿入する。

子を挿入する。

soup = BeautifulSoup('<a>Foo</a>')

# a 要素に子 'Bar' を挿入する。
soup.a.insert(0, 'Bar')
print(soup)  # <html><body><a>BarFoo</a></body></html>

兄弟を直前に挿入する。

soup = BeautifulSoup('<b>stop</b>')
tag = soup.new_tag('i')

# b の直前に挿入する。
soup.b.insert_before(tag)
print(soup)
# <html><body><i></i><b>stop</b></body></html>

兄弟を直後に挿入する。

soup = BeautifulSoup('<b>stop</b>')
tag = soup.new_tag('i')

# b の直後に挿入する。
soup.b.insert_after(tag)
print(soup)
# <html><body><b>stop</b><i></i></body></html>

子孫ノードを削除する。

html = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(html)
print(soup.a)
# <a href="http://example.com/">I linked to <i>example.com</i></a>

# a タグの子孫をすべて削除する。
soup.a.clear()
print(soup.a)
# <a href="http://example.com/"></a>

指定した要素及びその子孫を DOM ツリーから取り除いて、返す。(pop 操作)

html = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(html)
print(soup.a)
# <a href="http://example.com/">I linked to <i>example.com</i></a>

# 呼び出した要素を DOM ツリーから削除して、その要素を返す。
i_tag = soup.i.extract()
print(i_tag)  # <i>example.com</i>

print(soup.a)
# <a href="http://example.com/">I linked to </a>

指定した要素及びその子孫を DOM ツリーから取り除く。

html = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(html)
print(soup.a)
# <a href="http://example.com/">I linked to <i>example.com</i></a>

# 呼び出した要素を DOM ツリーから削除する。
soup.i.decompose()

print(soup.a)
# <a href="http://example.com/">I linked to </a>

要素を置換する。

html = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(html)
a_tag = soup.a

b_tag = soup.new_tag('b')
b_tag.string = 'example.net'

# i タグを b タグに置換する。
a_tag.i.replace_with(b_tag)
print(a_tag)
# <a href="http://example.com/">I linked to <b>example.net</b></a>

指定した要素で囲む。

soup = BeautifulSoup('<p>I wish I was bold.</p>')

# p タグの値を b タグで囲む。
b_tag = soup.p.string.wrap(soup.new_tag('b'))
print(b_tag)  # <b>I wish I was bold.</b>

print(soup.p)
# <p><b>I wish I was bold.</b></p>

指定した要素を取り除く。

html = '<a href="http://example.com/">I linked to <i>example.com</i></a>'
soup = BeautifulSoup(html)
a_tag = soup.a

# i タグを取り除く。
a_tag.i.unwrap()
print(a_tag)
# <a href="http://example.com/">I linked to example.com</a>

DOM ツリーを HTML で出力する。

formatter='html' とした場合、Unicode 文字は HTML エンティティに変換して出力する。

html = '<p>Il a dit &lt;&lt;Sacr&eacute; bleu!&gt;&gt;</p>'
soup = BeautifulSoup(html)

print(soup.prettify())
# <html>
#  <body>
#   <p>
#    Il a dit &lt;&lt;Sacré bleu!&gt;&gt;
#   </p>
#  </body>
# </html>

# Unicode 文字は HTML エンティティに変換して出力する。
# é が &eacute; に変換されている。
print(soup.prettify(formatter='html'))
# <html>
#  <body>
#   <p>
#    Il a dit &lt;&lt;Sacr&eacute; bleu!&gt;&gt;
#   </p>
#  </body>
# </html>

formatter='html5' とした場合、空タグ (
) は / を付けないで出力する。

soup = BeautifulSoup('<br>')
print(soup.prettify())
# <html>
#  <body>
#   <br/>
#  </body>
# </html>

soup = BeautifulSoup('<br>')
print(soup.prettify(formatter='html5'))
# <html>
#  <body>
#   <br>
#  </body>
# </html>

None を指定した場合はなにも修正せずにそのまま出力する。

soup = BeautifulSoup('<br>')

# 何も変更を加えずに表示する。
print(soup.prettify(formatter=None))
# <html>
#  <body>
#   <br>
#  </body>
# </html>