Dataiku×Webデータで分析を豊かにする

突然ですが、みなさまはこんな経験をしたことが有りませんか?
  • 分析をしたいテーマが有るが、データを持っていない
  • 機械学習に追加したい特徴がある
  • Web情報を取りまとめて構造化したい
  • データを集めるところから分析までを一気通貫でオペレーションしたい

そんなみなさまに、今回はDataikuを使ってデータを取得する方法をいくつかご紹介したいと思います!

API経由で取得する

API経由で取得する場合は、pythonで取得してデータフレームにするときのように簡単にデータセットを構築することが可能です。

ただし、前段として以下の準備が必要です。

  • APIのライブラリを含むPython環境
  • APIキー

具体的な手順としては、pythonのコードレシピを作成

Outputとなるデータセットを定義し、レシピを作成。(もちろんAPIに投げたい項目のリストをインプットすることも可能です。)

コードを書きます。

以下はyfinanceという株価取得のAPIを用いて、株価の情報を取得するスクリプトのサンプルです。

# -*- coding: utf-8 -*-
import dataiku
import pandas as pd, numpy as np
from dataiku import pandasutils as pdu
import datetime
import yfinance as yf

# Compute recipe outputs
# yfinanceという株価取得のAPIを使用し、日経平均を取得
# ターゲットには複数銘柄も指定可能です
target = '^N225'

API_data_df = yf.download(target, period='7d', interval="1d")

# 日付列を追加
API_data_df['Date'] = API_data_df.index

# Write recipe outputs
API_data = dataiku.Dataset("hogehoge")
API_data.write_with_schema(API_data_df)

コードの実行環境をライブラリが有る環境に変更します。

Dataikuで独自のPython環境を構築する方法は、公式ドキュメントをご確認ください。

コードを実行します。

成功すると日経平均のデータセットが出力されます。

Web情報をスクレイピングする

Web情報をスクレイピングする場合は、事前にいくつかの準備が必要です。

  • Google Chromeと対応するChromedriverのインストール
  • Selenium, bs4のインストール

Google Chromeについてはローカルで使用しているDataiku DSSであればローカルのものでも動くと思いますが、

GCPなどのクラウドリソースで運用しているDataiku環境の場合は、対応するノードにGoogle Chromeをインストールする必要が有ります。

Chromedriverについては、対応するバージョンのchromedriver-binaryをDataiku DSSのCode Envsの設定から、

chromedriver-binary==[バージョン番号]

という形で指定することでインストールできます。

Selenium, bs4についても同じようにインストールしてみてください。

事前準備できたことを確認するためには、以下のGoogleのホームページにアクセスし、タイトルを取得するスクリプトを実行してみてください。結果として’Page title: Google’と帰ってくれば、スクレイピングの環境の構築が完了しています。

from selenium import webdriver
from bs4 import BeautifulSoup
import chromedriver_binary  # 自動的にパスが設定されます

# WebDriverの設定
options = webdriver.ChromeOptions()
options.add_argument('--headless')  # ヘッドレスモードで実行
driver = webdriver.Chrome(options=options)

try:
    # Googleのホームページを開く
    driver.get('https://www.google.com')

    # BeautifulSoupを使用してページのタイトルを取得
    soup = BeautifulSoup(driver.page_source, 'html.parser')
    title = soup.find('title').text

    # ページのタイトルを表示
    print(f'Page title: {title}')

finally:
    # WebDriverを閉じる
    driver.quit()

環境構築が完了すると、いよいよスクレイピングを行うのですが、その前に以下の点に注意する必要が有ります。

  • スクレイピングを禁止しているWebサイトでないか
    • 規約で禁止されている場合、法的に問題無いことを確認の上、対応を検討してください。
  • 短期間に大量のリクエストを投げるようなスクリプトになっていないか

上記に配慮して、今回はGoogle mapで’新橋 レストラン’と検索した結果をデータセットにまとめてみたいと思います。

APIの時と同様、コードレシピに以下のコードを入力し実行します。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import time
import pandas as pd
import chromedriver_binary  # Adds chromedriver binary to PATH
import dataiku

# GoogleマップのURLを設定
url = "https://www.google.com/maps/search/%E6%96%B0%E6%A9%8B+%E3%83%AC%E3%82%B9%E3%83%88%E3%83%A9%E3%83%B3/"

# WebDriverの設定
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(options=options)

# Googleマップにアクセス
driver.get(url)

# ページが完全に読み込まれるのを待つ
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CLASS_NAME, "Nv2PK"))
)

# スクロールして更にレストランを読み込む(必要に応じて調整)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(3)

# BeautifulSoupでHTMLを解析
soup = BeautifulSoup(driver.page_source, "html.parser")
restaurants = soup.find_all("div", class_="Nv2PK THOPZb CpccDe")

# レストラン情報を格納する辞書を初期化
restaurant_data = []

# レストラン情報を取得し辞書に追加
for restaurant in restaurants:
    restaurant_info = {}
    for element in restaurant.find_all(class_=True):
        class_name = " ".join(element['class'])  # 複数のクラス名を結合
        text = element.get_text(strip=True)
        if class_name in restaurant_info:
            restaurant_info[class_name] += f' | {text}'
        else:
            restaurant_info[class_name] = text
    restaurant_data.append(restaurant_info)

# ブラウザを閉じる
driver.quit()

# 辞書をDataFrameに変換
Crawled_data_df = pd.DataFrame(restaurant_data)

# Write recipe outputs
Crawled_data = dataiku.Dataset("Output_data")
Crawled_data.write_with_schema(Crawled_data_df)

これを実行すると、以下のようなデータセットが作成されます。

各列はWebページの内部的なクラス名になっていますが、それを対応する項目名に置き換えて必要なものだけを抽出するレシピを挟むことで、Webサイトの改変などでクラス名が変わるまでは綺麗なデータセットとして使うことができます。

さらに、このデータをインプットとしてレビュー情報を取得し、レビュー分析を行うなど、スクレイピングが選択肢に入ってくると分析の幅がより広がることでしょう。

まとめ

今回は、DataikuでAPIやスクレイピングのコードを実行し、データセットを作成する方法をまとめました。

ちなみに、弊社ではShtockDataと呼ばれるより大規模で、より構造化されたデータセットを定期的に取得するサービスを提供しており、市場変化の検出、競合他社の商品、サービスの価格や性能の比較に活用されています。

皆様のDataikuでの分析が、Webデータを組み合わせることでより深まることを願っております。

ShtockData

お問い合わせフォーム

お問い合わせ項目を選択してください