目の前のパソコンではなく、サーバーを用いればプログラムを24時間体制で動かすことができます。Pythonで仕事を自動化するには様々な事例が考えられますが、さらに応用範囲が広がります

そのためにはサーバーを準備する必要がありますが、ビジネスパーソンに現実的ではありません。

しかし、サーバーレスを利用すればその必要がなくなります。Pythonのコードをクラウドサービスに登録するだけで、クラウド上でプログラムを稼働できます。

例えば、特定のWebページを定期的にチェックしたり、クラウドストレージに追加されたファイルを即時に変換するなど、自分のパソコンを起動しないで実行できます。

今回はサーバーレスがどのような仕組みなのかを理解できるように、簡単なプログラムで試します。日経新聞社のサイトのドル円為替を1時間ごとにチェックして、自分宛にメールで通知します。

クラウドにはGoogle社のGoogle Cloud Platform(GCPを利用し、その中のサービスの1つである「Cloud Functions」というサーバーレスサービスでプログラムを稼働させます。

本記事の目次
Google Cloud Platformを利用するには、クレジットカードの登録が必要になりますので、課金された場合には支払いが発生します。その点を十分にご理解いただいた上で実行してください。

サーバーレスとは

サーバーレスレス(serverless)とはかなりざっくりと言えば「自分でサーバーを準備する必要がない」ということです。

従来よりリモートでプログラムを24時間稼働するには、専用OSでサーバーを構築するが一般的です。そのため、気軽に準備することは中々難しいのが現状でした。

そのような問題を解決してくれるのがサーバーレスです。面倒なサーバーの運用はクラウドに任せて、ユーザーはプログラムを作成してアップロードするだけです。今回利用するサービスではユーザーは「関数」を作成するだけで、24時間稼働するプログラムを実現できます。

主要なクラウドプラットフォーム

サーバーレスは、おもに以下の3つの主要なクラウドプラットフォームで利用できます。

Amazon社のAWS Lambdaがシェアトップですが、AWSの構成自体が非常に複雑なため、初めての場合には敷居が高すぎます。そこで、サーバーレスとしては後発ですが、最もわかりやすいと考えられるGoogle社のGoogle Cloud Functionsを今回は利用します

Google Cloud Platform(GCP)への登録

Google Cloud FunctionsはGoogle Cloud Platform(GCP)のサービスの一部です。そのため、利用するにはGCPへの登録が必要です。登録はGoogleアカウントがあればすぐできます。

登録の方法は以下のページがとてもわかりやすいので参考にしてください。

これから始めるGCP(GCE)安全に無料枠を使い倒せ(Qiita)

GCPは有料のサービスですが、以下のページに記載されている無料枠を利用できます。

Google Cloud Platform の無料枠(Googleホームページ)

GCP の無料枠(Google Cloud Platform ドキュメント)

GCP利用の注意事項

たとえ無料枠があっても、GCPに登録した時点から常に何らかの原因で課金される可能性があると考えてください。意図しない課金を防ぐために以下の事項は必ずチェックしてください。

課金状況はこまめにチェックする

上記のGoogleのページにあるようにCloud Functionsなら「1か月あたり200万回まで」の無料枠が設定されています。例えば、1つの関数を1時間ごとに1か月間呼び出しても720回ですので、無料枠におさまります。

しかし、今回のような単純は例でも、以下のように複数のサービスが連動しますので、こまめに課金状況は必ずチェックするようにしてください。

今回のプログラムを実行した時の課金明細

cost list

課金状況はGCPの「お支払いの概要」から確認できます。方法は以下のページを参照してください。

費用とお支払い履歴の表示(GCPドキュメント)

予算アラートを設定する

GCPでは始めての利用者のために回数による無料枠とは別に「12か月間$300分の無料トライアル」が提供されています。しかし、間違えて他のサービスを開始し、そのまま放置してしまうとすぐに使い果たしてしまう可能性があります。

このリスクを防止するために、こまめな課金状況の確認だけでなく「予算アラート」も設定してください。設定した予算に応じて通知を受け取ることができます。ただし、通知だけで停止ではないので気をつけてください。設定方法は以下のページを参照してください。

予算アラートの設定(GCPドキュメント)

使わなくなったら無効にする

使わなくなった場合はそのまま放置しないで、「プロジェクトの課金を無効」にしてください。ただし、リソースが自動的に削除されることがあるのでコードや設定内容は控えを取っておいてください。方法と詳細については以下のページを参照してください。

プロジェクトの請求設定の変更 > プロジェクトの課金を無効にする(GCPドキュメント)

さらに、「プロジェクトのシャットダウン(削除)」、「請求先アカウントの閉鎖」も可能です。方法については以下のページを参照してください。

Google Cloud Platform アカウントを閉鎖する(GCPドキュメント)

ご不明な点はGoogleのサポートへ

GCPはクラウドプラットフォームの中では分かりやすいとは言え、やはり詳細まで把握するのは困難です。不明な点がある場合は、Googleのサポート を利用できます。

GCP ▶ プロジェクトの作成

GCPに登録したら、まずプロジェクトを作成します。GCPでは利用するサービスをプロジェクト単位で管理します。今回用いるCloud Functionsも、プロジェクトの中に作成して利用します。

新しいプロジェクトの作成は以下のページが分かりやすいので参考にしてください。

第0回 Google Cloud Platformをはじめよう!(マナティ by マイナビ)

プロジェクト名は任意の適当な名前を入力します。今回は以下のように「scraping-kawase」としました。

create project

Cloud Functionsの作成

プロジェクトを作成したら、Pythonのコードを登録するためのCloud Functionsを作成します。

左上のメニューアイコン をクリックすると左側からメニューが表示されるので、以下のようにCloud Functionsを選択します。

select bashboard

Cloud Functions ▶ 関数の作成

しばらく待つと以下の画面が表示されるので、関数を作成ボタンをクリックします。

create functions

次に「関数の作成」の画面が表示されるので、以下の手順で設定します。

名前、割り当てられるメモリ

名前割り当てられるメモリはデフォルトのままにしておきます。

function name

トリガーの選択

トリガーの部分をクリックして、プルダウンメニューから「Cloud Pub/Sub」を選択します。

select trigger

Cloud Pub/Subとは

Cloud Pub/Subはクラウドのサービス間をメッセージの受け渡しで連携させる仕組みです。今回はスケジュールを管理するCloud Schedulerが定時にメッセージを送信して、それをCloud Functionsが受け取ることで定期的なプログラムの実行を実現しています。

トピックの入力

トピックの部分をクリックすると「新しいトピックを作成…」と表示されるのでクリックします。

select topic

以下のようなダイアログが表示されるので、適当な名前を入力します。今回はfunction-1のトピックであることが分かるように「function-1-topic」としました。

input topic

ソースコード ▶ ランタイムの選択

今回はソースコードをブラウザ画面から入力するので、以下のように「インラインエディタ」を選択します。そして、ランタイムに「Python 3.7」を選択します。

code runtime

Cloud Functions ▶ ソースコードの入力

ここでやっとPythonのソースコードを入力します。ソースコードはmain.pyに、使用する外部ライブラリをrequirements.txtに入力します。

main.py

ソースコードを以下のようにエディタ部分に貼りつけたら、実行する関数に今回は「main」を入力します。

main.py

今回は以下のソースコードを使います。このコードは日経新聞社の為替サイトから現在のドル円レートを読み取り、自分宛にGmailでメールを送信します。

main.py
import requests
from bs4 import BeautifulSoup
import smtplib
from email.mime.text import MIMEText

kawase_url = "https://www.nikkei.com/markets/kawase/"

my_addr = "自分のGmailアドレス"
my_pass = "自分のGmailのアプリパスワード"

# 為替の取得
def get_kawase_price():
    r = requests.get(kawase_url)
    soup = BeautifulSoup(r.content, "html.parser")
    price_elems = soup.select("div.mkc-stock_prices")
    return price_elems[0].getText()

# メッセージの作成
def create_message(from_addr, to_addr, subject, body_txt):
    msg = MIMEText(body_txt)
    msg["Subject"] = subject
    msg["From"] = from_addr
    msg["To"] = to_addr
    return msg

# メールの送信
def send_mail(msg):
    with smtplib.SMTP("smtp.gmail.com", 587) as server:
        server.ehlo()
        server.starttls()
        server.ehlo()
        server.login(my_addr, my_pass)
        server.send_message(msg)

def main(event, context):
    price = get_kawase_price()
    if price:
        msg = create_message(my_addr, my_addr, "ドル円レートお知らせ", price)
        send_mail(msg)

Gmailのアドレスとパスワードは自分のものを入力してください。パスワードはセキュリティの観点からも2段階認証を設定して、今回のサーバーレス用のアプリパスワードを取得することをお勧めします。アプリパスワードの取得方法は以下が参考になります。

Pythonプログラミング通信講座では、実際にPythonでメールを送信します。そこではグーグルのGmailを使用しますので、「アカウント」と「パスワード」の準備をお願いします。 Pythonか…

ここでクラウドが実行する関数は、main()関数になりますが、今回のようにトリガーを「Cloud Pub/Sub」にした場合は、引数を2つ(event, context)必ず設定してください。この引数自体は関数の中で使わなく大丈夫です。

requirements.txt

今回のPythonプログラムでは、「requests」と「BeautifulSoup」の2つの外部ライブラリを利用します。パソコンで実行する時には、pip installでインストールしますが、GCPでは以下のようにrequirements.txtに入力します。

requirements.txt

requirements.txtには以下のように「ライブラリ名>=バージョン」を入力します。入力したら最後に作成ボタンをクリックします。

requirements.txt
requests>=2.22.0
beautifulsoup4>=4.8.1

Cloud Functions ▶ 関数のテスト

関数の作成が完了すると以下のように作成した関数のリストに緑色のチェックが付きます。そうしたら、右端のアイコン をクリックしてメニューから関数をテストを選択します。

functions list

すると以下のような画面が表示されるので、関数をテストボタンをクリックします。

functions text

無事テストが完了すると以下のようにアウトプットに「OK」と表示されます。

functions test result

同時に自分宛にメールが届きます。これで関数が正常に実行できることが確認できました。

mail context

「ログ」の欄は表示されるのに時間がかかることがあるので、そのままにして気にしないでください。

Cloud Schedulerの作成

作成した関数をGCPのCloud Schedulerを利用して定期的に実行します。

左上のメニューアイコン をクリックすると左側からメニューが表示されるので、以下のようにCloud Schedulerを選択します。

select scheduler

すると以下のような画面が表示されるので、ジョブを作成をクリックします。

create job

引き続きジョブの作成を以下の手順で行います。

ロケーションを選択

ジョブを継続させるローケーションはデフォルトのまま次へをクリックします。

job location

以下のような画面が表示されロケーションの準備が始まります(少し時間がかかります)。

job waiting

ジョブの作成

ロケーションの準備が完了するとジョブの設定を入力する画面が表示されます。以下のように入力して最後に作成ボタンをクリックします。

setting job

ここで各項目は以下のような内容になります。

  • 名前は後で分かりやすい適当な名前を入力してください。
  • 頻度0 */1 * * *と入力すると毎時(1時間ごと)に実行します。その他の設定方法はこちら を参照してください。
  • タイムゾーンはプルダウンメニューから「日本標準時(JST)」を選択してください。
  • ターゲットはプルダウンメニューから「Pub/Sub」を選択してください。
  • トピックは関数の作成で設定したfunction-1-topicを入力してください。
  • ペイロードは関数に渡す値ですが、ここでは空を示す{}を入力してください。

Cloud Scheduler ▶ ジョブの実行

これでジョブが作成され、定期的にプログラムが実行されます。

ジョブの即時実行

状態が「有効」になっているので、この状態で1時間ごとに関数(function-1)が実行されますが、今すぐ実行をクリックすれば即時に実行できます。

job list

上では「前回の実行」と「結果」は空欄になっていましたが、今すぐ実行をクリックすると以下のように表示されます。

job list result

今回は頻度を0 */1 * * *と設定したので、16:00:0,17:00:00,18:00:00のようにちょうど1時間ごとに実行されます。

job run

Gmailで自分宛にメールが届いているのを確認できます。

gmail send

ジョブの一時停止・削除

このままにしておくと1時間ごとに実行し続けるので、一時停止または削除するには、以下のようにジョブを選択してから一時停止または削除をクリックします。

job stop remove

最後に

少し準備が面倒に感じられたかもしれませんが、一度準備すれば簡単にリモートでプログラムを実行できます。通常サーバーを準備するのはこんなに簡単にはできません。

今回は当たり障りのないように、為替データの取得を例にしましたが、実際には競合ECサイトの価格を定期的に監視したり、Twitterの自社に関する投稿をチェックするなど多様に応用できます。

さらには、クラウドのストレージやスプレッドシートなどと連携することも可能です。詳しくは以下のGoogleホームページが参考になります。ぜひいろんなアイデアを試してみてください。

Cloud Functions ガイド:チュートリアル(Googleホームページ)