from bs4 import BeautifulSoup

Python

https://qiita.com/itkr/items/513318a9b5b92bd56185 より

インストール

$ pip install beautifulsoup4

使い方

BeautifulSoupオブジェクトの作成

平文のHTMLを扱う場合

from bs4 import BeautifulSoup
html = """
    <html>
    ...
    </html>
"""
soup = BeautifulSoup(html)

URLは直接扱えないのでwebサイトを扱う際はurllib2などと組み合わせる

import urllib2
from bs4 import BeautifulSoup
html = urllib2.urlopen("http://example.com")
soup = BeautifulSoup(html)

ここでHTMLパーサーについての警告が出る場合はメッセージに従ってパーサーを指定

soup = BeautifulSoup(html, "html.parser")

シンプルなタグの取得方法

HTMLの中からAタグをすべて取得するには

soup.find_all("a")

これで取得できるオブジェクト<class 'bs4.element.ResultSet'>はlistのように扱う

すべてのタグではなく先頭の一つだけ取得するには

soup.find("a")

もしくは

soup.a

soup.find("a")soup.aは、タグがそのHTMLに存在しない場合はNoneが返ります。

取得したタグの情報

取得したタグの属性を取得するには

soup.a.get("href")

取得したタグの中の文字を取得するには

soup.a.string

当然入れ子になっているタグを取得することもできます

soup.p.find_all("a")

条件を絞ったタグの取得

属性などで条件を絞ってタグを取得することも簡単にできます。例えば<a href="/link" class="link">のようにclassがlinkでhrefが/linkのaタグをすべて取得するには

soup.find_all("a", class_="link", href="/link")

または

soup.find_all("a", attrs={"class": "link", "href": "/link"})

上記一つ目の書き方で注意するのはclassはPythonでは予約語なのでclass_になります。

また、タグを指定しなくても構いません。

soup.find_all(class_="link", href="/link")
soup.find_all(attrs={"class": "link", "href": "/link"})

正規表現を使ったタグの取得

BタグやBODYタグなどbで始まるタグをすべて取得するには

import re
soup.find_all(re.compile("^b"))

”link”を含むhref属性を持っているタグをすべて取得するには

import re
soup.find_all(href=re.compile("link"))

タグの中の文字列に”hello”を含むAタグをすべて取得するには

import re
soup.find_all("a", text=re.compile("hello"))

cssセレクタを使ったタグの取得

find_allの代わりにselectを使うとcssセレクタを使ってタグを取得することができます。

soup.select("#link1")
soup.select('a[href^="http://"]')

書き換え

タグに属性を追加する

a = soup.find("a")
a["target"] = "_blank"

タグを外すのはunwrapを使います

html = '''
<div>
    <a href="/link">spam</a>
</div>
'''
soup = BeautifulSoup(html)
soup.div.a.unwrap()
soup.div
# <div>spam</div>

逆に新しくタグをつける場合はsoup.new_tagでタグを作ってwrapで追加します。

html = '''
<div>
    <a href="/link">spam</a>
</div>
'''
soup = BeautifulSoup(html)
soup.div.a.wrap(soup.new_tag("p"))

そのほかにもinsertextractなど操作用メソッドが充実しているのでコンテンツやタグを追加したり除去したり柔軟に行えます。

出力

prettifyを呼び出すことできれいに整形して文字列として出力が出来ます。

soup.prettify()
# <html>
#  <head>
#   <title>
#    Hello
#   </title>
#  </head>
#  <body>
#   <div>
#    <a href="/link">
#     spam
#    </a>
#   </div>
#   <div>
#    ...
#   </div>
#  </body>
# </html>
soup.div.prettify()
# <div>
#  <a href="/link">
#   spam
#  </a>
# </div>

HTMLパーサーについて

soup = BeautifulSoup(html, "lxml")
タイトルとURLをコピーしました