Edited at

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