Python
python3
BeautifulSoup

Beautiful Soupを使ってスクレイピング

More than 3 years have passed since last update.

環境 Mac, Python3

事前準備

Beautiful Soupとlxmlをインストール

$ pip install beautifulsoup4
$ pip install lxml

途中でエラーが出たけどインストールは成功。
今のところ問題は出てない。

soupの基本形

from bs4 import BeautifulSoup
import urllib.request

# webからhtmlを取得する場合
url = '××××××××××××'
req = urllib.request.Request(url)
response = urllib.request.urlopen(req)
html = response.read()
soup = BeautifulSoup(html, "lxml")
# ローカルのhtmlを直接開くとき
soup = BeautifulSoup(open("index.html"), "lxml")

これからやること

ほしい情報が入っているタグを指定して要素を取得する。

よく使う指定方法

- classを指定
   soup.find(class_='class_name')
   # classの後にアンダーバーがないとエラーがでる。
- idを指定
   soup.find(id="id_name")
   # idはそのまま。
- タグも一緒に指定
   soup.find('li', class_='class_name')
   soup.find('div', id="id_name")

find()では初めにヒットした1件しか取得されません。
複数取得したい場合はfind_all()を使います。

images = soup.find_all('img')
  for img in images:
    ~個別の処理~
soup.select("p > a")
soup.select('a[href="http://example.com/"]')

実行サンプル

soupにhtmlを読み込んでからのサンプルになります。

サンプル1:タグに挟まれたテキストを取得する

sample.html
<html>
  <title>test title</title>
</html>
>>> soup.title
<title>test title</title>
>>> soup.title.string
'test title'

後ろに.stringを追加すると取得できます。

サンプル2:imgタグのsrcを抽出する

sample.html
<html>
  <div id="hoge">
    <img class="fuga" src="http://××.com/sample.jpg"/>
  </div>
</html>

はじめにid="hoge"のdivタグを取得

>>> div = soup.find('div' id="hoge")
<div id="hoge">
  <img class="fuga" src="http://××.com/sample.jpg"/>
</div>

次にdivからclass="fuga"のimgタグを取得

>>> img = div.find('img', class_='fuga')
<img class="fuga" src="http://××.com/sample.jpg"/>
>>> img['src']
"http://××.com/sample.jpg"

実際にはこのパターンでdivを取得する必要はありません。
ですが絞り込む形のサンプルにしたかったのでdivをいれました。

参考
http://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-beautiful-soup