Pythonでスクレイピング

BeautifulSoup4でid, classを持つDOMを取得して効率化しよう!

前回は、スクレイピングでヘッダー情報を付与する方法とその目的を紹介しました。これまで紹介してきたスクレイピングの方法では、HTMLタグをこ辿ってデータを取得してきました。
今回は、HTMLタグに設定するidやclassを指定して効率よくデータを取得する方法を紹介します。

前回までのソース

前回のソースコードでは、h1やh2といった特定しやすいタグを指定していました。


from bs4 import BeautifulSoup
import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
}
url = "https://weather.yahoo.co.jp/weather"

/* make session and request */
session = requests.Session()
req = session.get(url, headers=headers)
bsObj = BeautifulSoup(req.text, "html.parser")

/* get h1 and h2 dom texts */
print("[h1] " + bsObj.h1.text)
print("[h2] " + bsObj.h2.text)
# print(bsObj.html)

print ("It worked.")

idやclassを指定するには

beautifulsoup4でidやclassを指定するにはfind(...)find_all(...)関数を利用します。
これらは、あるDOMに含まれるタグの中から指定したタグを見つけ出します。指定には、htmlタグやid/classなどが可能です。
利用イメージは次の通りです。

bsObj = BeautifulSoup(req.text, "html.parser")

## find(...) #
teamItem = bsObj.find("div", class_="team")
# => <div class="team">Team A</div>

print(teamItem.string)
# => Team A

## find_all(...) #
nameItems = bsObj.find_all("div", class_="name")
# => <div class="name">Taro</div>
#    <div class="name">Hanako</div>

for name in nameItems:
  print(name.string)
# => Taro
#    Hanako

find(...)find_all(...)関数を利用して天気データを取得する

1. forecastMapを取得

前回に引き続き、Yahoo!天気の天気情報を取得します。最初に、天気情報が表示されているforecastMapのidのついたDOMを取得します。

bsObj = BeautifulSoup(response.text, "html.parser")

# マップ情報を取得
forecastMap = bsObj.find('div', id="forecastMap")

2. 各地の天気情報を取得

# 各地の天気情報を取得
points =  forecastMap.find_all(class_="point")

3. 天気情報からデータを取り出し、表示する

取得した天気情報から、地名・天気・最高気温・最低気温・降水確率といった情報を取り出し、表示してみます。

for p in points:
    # 地名
    name = p.find(class_="name").string
    # 天気
    weather = p.find(class_="forecast").span.string
    # 最高気温
    high = p.find(class_="temp").find(class_="high").string
    # 最低気温
    low = p.find(class_="temp").find(class_="low").string
    # 降水確率
    precip = p.find(class_="precip").string

    print(name, weather, high, "/", low, precip)

4. プログラムを実行し、結果を確認

上記の手順で書いたプログラムを実行し、結果を確認します。各地の天気情報が以下のように表示されます。

$ python3 scraping03.py
[h1] 全国の天気
[h2] 全国概況
札幌 晴後曇 17 / 7 0%
釧路 曇時々晴 14 / 5 0%
仙台 晴れ 20 / 9 0%
東京 晴れ 22 / 12 10%
名古屋 晴後曇 23 / 11 0%
新潟 晴れ 20 / 9 0%
金沢 晴れ 22 / 10 0%
大阪 晴後曇 24 / 13 0%
広島 晴後曇 22 / 12 0%
高知 晴後曇 24 / 11 20%
福岡 曇り 23 / 12 10%
鹿児島 晴後曇 26 / 14 10%
那覇 晴時々曇 27 / 22 20%

参考ソースコードはこちらです。
scraping03.py – hiro-nagami/scraping-sample

まとめ

Webページは、配置や親子関係を明確にしたりスタイルを適用するためにDOMにidclassを指定することが非常に多いです。今回はそれを利用して、効率的にデータを取得する手順を紹介しました。
データを取得する際には、idclass指定を利用して的確かつ効率的に取得できるよう実装していきましょう。

Related post

  1. テクノロジー

    ReactiveXとは?RxJSの入門と導入手順

    Rx (Reactive Extension)とはここ数年で話題になっ…

  2. テクノロジー

    ReactiveXで使うStreamとObserverとは?RxJSでわかりやすく解説

    前回は、ReactiveXとは?RxJSの入門と導入手順について話しま…

  3. テクノロジー

    CSSによるセンタリングの方法と注意点についてのまとめ

    HTMLとかCSSの勉強を始めると、divやsectionなどで作った…

  4. iOSアプリ開発

    iOSアプリ開発者が本当にオススメする6つの技術系サイト

    今回は、iOSアプリエンジニアとして実際に良く参考にしているサイトを紹…

  5. xcode

    iOSアプリ開発

    iOSアプリ開発に必要なXcodeについて知ろう

    「アプリ開発って難しそう」「アプリを作ってみたいけど作り方がわからない…

  6. swiftui

    iOSアプリ開発

    StateとObservableを使ってSwiftUIのビューを変更する方法

    SwiftUIフレームワークを使っているとStateやObserved…

PAGE TOP