01 NOTEゼロワンノートは、転職・独立したい人のサービス開発・転職・副業・起業を応援するサイトです。

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

Pythonでスクレイピング
前回は、スクレイピングでヘッダー情報を付与する方法とその目的を紹介しました。

これまで紹介してきたスクレイピングの方法では、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%
参考ソースコードはこちらです。

まとめ

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