レシピ提案アプリ part1

はじめに

これからレシピ提案アプリの検討から実装までどのような経緯、技術で作っていったのかをまとめていきます。

自分の中でどのように考えて作ったのかなどを中心に記載していきます。

この章で学べること

  1. Jupyter Labの環境構築
  2. pythonでスクレイピング
  3. スクレイピングの考え方

1.Jupyter Labの環境構築

環境構築では、Dockerを利用してローカルマシン上でJupyter Labを利用できるようにします。

なぜDockerを使うのか

大きな理由としては、プロジェクトごとに環境構築をしておきたいからです。

Dockerを使わずにローカルマシンにインストールして展開する方法もあるのですが、そうするとローカルマシンには基本的に一つのバージョンしか選択できないため、pythonのバージョンを上げたい場合や、切り替えたい場合に一手間かかってしまいます。

複数プロダクトを管理し始めるとそれぞれバージョンが異なることが考えられます。

そうなった際に、プロダクトの環境ごとDockerで構築しておけば個別で管理することができ、バージョンアップの際もそのプロダクトへの影響だけを考えれば良くなるため、よりスムーズに開発を行うことができます。

Jupyter Labとは何か

Jupyter Labとは、Web ベースのPython開発環境です。

ブラウザ上でソースコードを書き、実行することが可能です。

実行結果を画面で確認できるため、データ分析などのインタラクティブに結果を確認したい場合によく利用されます。

今回のスクレイピングに関しても、実行して結果を画面上表示して少しずつ進めるというのがやりやすいため、Jupyter Labを採用しています。

ちなみにGoogle ColaboratoryでもJupyter Lab とほぼ同じ機能を利用できるため、環境構築がめんどくさい場合はGoogle Colaboratoryを利用するでも良いかと思います。(その場合一部利用制限があるため注意してください)

Dockerもついでに使えるようになりたいなーという方は、普段からDockerを利用する癖をつけておくと良いかと思います。

環境構築

ローカルマシン上で Dockerを利用可能にするためには、Dockerのインストールが必要になります。

Docker

終わったらインストールできているか確認してみます。

以下のコマンドをターミナルなどに打ち込んで実行してみてください。

docker -v

結果としてdockerのバージョンが表示されたらOKです。

表示されない場合は公式サイト見て、手順問題ないか確認してみてください。

Dockerのインストールができたら、Dockerファイルを書いてきます。

今回はDockerについての説明は省略します。

Dockerfileというファイルを作成して、そこに以下をコピペしてください

FROM ubuntu:latest
 
# update
RUN apt-get -y update && apt-get install -y \
  sudo \
  wget \
  vim \
  chromium-browser \
  && apt-get install chromium-chromedriver
 
#install anaconda3
WORKDIR /opt
# download anaconda package and install anaconda
# archive -> https://repo.continuum.io/archive/
RUN wget https://repo.anaconda.com/archive/Anaconda3-2022.05-Linux-x86_64.sh && \
  sh /opt/Anaconda3-2022.05-Linux-x86_64.sh -b -p /opt/anaconda3 && \
  rm -f Anaconda3-2022.05-Linux-x86_64.sh
# set path
ENV PATH /opt/anaconda3/bin:$PATH
ENV PYTHONPATH="/work/sbiartauction:$PYTHONPATH"
 
# update pip and conda
RUN pip install --upgrade pip \
  conda install Selenium \
  conda install chromedriver-binary==97.0.4692.71.0
 
WORKDIR /
RUN mkdir /work
 
# execute jupyterlab as a default command
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--allow-root", "--LabApp.token=''"]

ターミナル or コマンドプロンプトなど開いて、Doclerfileがあるディレクトリまで移動したら以下のコマンドを実行してください。

docker build -t jupiterlab --platform linux/amd64 .
docker run -d -p 8888:8888 -v ~/Develop/bwta/jupiter/ds_python:/work --name my-lab jupiterlab

実行できたら、ブラウザを開いて、http://localhost:8888 へとアクセスしてみてください。

これでJupyter Labが開けていれば完了です。

2.pythonでスクレイピング

スクレイピングとは

スクレイピングは、Webサイトから必要なデータを収集・抽出することです。

pythonを使ってスクレイピングすると、プログラムによって自動的にデータを収集・抽出できるようになるため、何千、何万件ものデータを簡単に集めることができるようになります。

pythonを使ってスクレイピングするのにおすすめなライブラリとして、BeautifulSoupというものがあります。

BeautifulSoupとは

BeautifulSoupとは、HTMLのデータを扱いやすいように解析、加工してくれるライブラリになります。

まずWebページにアクセスすると、HTMLというデータが返されます。

HTMLとは、「ハイパーテキスト・マークアップ・ランゲージ(Hyper Text Markup Language)」のことで、Webページを作成するための言語です。

例えばhttps://freestylelab.net/にアクセスすると、

<!DOCTYPE HTML>
<html>
  <body>
  ...
  </body>
</html>

という、データが返されます。

スクレイピングする際にもこのHTMLの中から必要なデータを取得する必要があるのですが、BeautifulSoupというライブラリを使うことで簡単に取得できるようになります。

言葉だけ読んでいても分かりづらいと思うので、実際にやってみましょう。

Jupyter LabでBeautiful Soupを使ってみる

まずhttp://localhost:8888を開きます。

最初の画面でPython3を選択します。

新しいファイルが開けたら、以下のコードを書き込み、実行します。

from bs4 import BeautifulSoup
import urllib.request as req
url = 'https://recipe.rakuten.co.jp/'
res = req.urlopen(url)
soup = BeautifulSoup(res, 'html.parser')
print(soup)

すると、HTMLのデータが取得できていることが確認できるかと思います。

3.スクレイピングの考え方

スクレイピングするときに必要な情報はHTMLの構造についてです。

開発者ツールを開いて、その構造を確認してみましょう。

ブラウザを開いた状態で、以下のショートカットで開けるかと思います。

Mac: option + command + i

Windows: Ctrl + Shift + i

開発者ツールを開いた状態で、再度上記ショートカットを実行することで閉じることもできます。

開発者ツールを開くと、以下のような画面が確認できるかと思います。

右側の赤枠で囲った部分が開発者ツールになります。

これをみてみるとわかると思いますが、先ほどJupyter LabからBeautiful Soupを使って表示したデータと同じような構造のデータが見えていると思います。

スクレイピングするときは、以下のような流れで設計を行います。

  1. データを取得したいサイトを開く
  2. 開発者ツールを開きながら、取得したいデータがどのページにあるか確認する
  3. どのページからどのように遷移させると網羅的に取得できそうかを検討する

まず自動でデータを網羅的に取得するために、楽天レシピではどのような構造になっているかを把握します。

まずTopページを見て、そこから欲しい情報までどのようにアクセスできるか、また網羅的にアクセスするためにはどこから情報を取得すれば良いかを確認します。

コードを書き始める前に、上記のようにどのように取得すれば良いかを確認・検討しておくことをお勧めします。

確認・検討せずにコードを書き始めてもある程度できてしまうことも多いです。

一回しか使わないのであれば良いのですが、今後メンテナンスしていく必要があるなら考えて作るようにしましょう。

なぜならWebサイトは定期的にアップデートされ、今までのやり方で取得できなくなることがよくあるためその際に汚いコードだと修正が困難で、後で自分を苦しめることになるからです。

話をスクレイピングに戻すと、楽天レシピでは料理を検索するには2パターンあります。

  1. フリーワードで料理名から検索する
  2. レシピカテゴリ一覧からカテゴリごとに検索する

今回はさまざまなレシピを網羅的に取得したいので、カテゴリごとに検索する方法を選択します。

データ取得までの全体の流れとしては、以下のような流れになります。

  1. Topページ(https://recipe.rakuten.co.jp/)
    • レシピカテゴリ一覧の料理から探す欄にある料理名(カテゴリ)を取得する
  2. カテゴリごとのランキングページ(https://recipe.rakuten.co.jp/search/料理名
    • 1で取得した料理名をもとに、ランキングページを表示する
    • ランキングからレシピのタイトルと、そのレシピへのリンクを取得する
  3. レシピページ(https://recipe.rakuten.co.jp/recipe/{:id}
    • 2で取得したレシピへのリンクから、レシピページを表示する
    • 必要な材料と、レシピの手順を取得する
  4. 取得結果の出力

ここまでで実装の準備ができたので、次からは実際にコードを書いていこうと思います。