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"))
そのほかにもinsert
やextract
など操作用メソッドが充実しているのでコンテンツやタグを追加したり除去したり柔軟に行えます。
出力
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")