【AWS】Pythonの開発環境Chaliceを使ってみる - アマゾン売れ筋ランキング


PythonのLambda関数の開発環境**Chalice**を使って、アマゾン売れ筋ランキング（本）の情報をスクレイピングして毎日定時にメールで送信してくれるシステム（とは言っても単に小さなプログラム）をつくってみます。


#１．プログラム概要

本システムはPythonのプログラムのコア機能として、**BeautifulSoup**を使って、アマゾンの「売れ筋ランキング（本）」のページをスクレイピングします。スクレイピングについては以下の記事が詳しいですね。
[PythonでWebスクレイピングする時の知見をまとめておく](https://vaaaaaanquish.hatenablog.com/entry/2017/06/25/202924)


コア機能に、次のAWSの機能を２つ追加します。このプログラムはLambda関数として**CloudWatch Events**で毎日定時に起動されます。また**SES**を使ってスクレイピングの結果をメールでお知らせします。


Lambda関数の開発環境として**Chalice**を使えば、AWSの面倒なRoleやPolcyの設定が自動的に行われるので、楽にdeployできるようになります。またPythonからAWSにアクセスするために定番の**boto3**を使います。

今回のプログラムは、コア機能を除けば、以下の過去記事と同じものです。
[【AWS】Pythonの開発環境Chaliceを使ってみる - CloudWatch Events](https://qiita.com/sand/items/4a4c273872b266af6680)


#２．ライブラリインストール

環境は基本的に以下の記事の環境設定を基本としています。
[【AWS】Python Lambdaのdeploy - Chalice](https://qiita.com/sand/items/4642f417bf0d2b49c7e2)


次にプロジェクトを作成作成します。

```
$ chalice new-project amazon-rank
$ cd amazon-rank
```

BeautifulSoupとlxmlをカレントの**vendor**ディレクトリにインストールします。Chaliceはdeploy時にvendorディレクトリのパッケージを一緒にアップしてくれます。

```
pip install beautifulsoup4 -t vendor
pip install lxml -t vendor
```




#３．ソースコード

```python:app.py
from chalice import Chalice
import boto3
from botocore.exceptions import ClientError
from bs4 import BeautifulSoup
import urllib.request
import datetime

app = Chalice(app_name='amazon-rank')

#パスでなくcronを記述します
@app.schedule('cron(25 1 * * ? *)')   # (1+9)時25分に起動
def cron_handler(event):
    url = "https://www.amazon.co.jp/gp/top-sellers/books/ref=crw_ratp_ts_books"
    data = urllib.request.urlopen(url)
    soup = BeautifulSoup(data, "lxml")

    today = datetime.date.today().strftime('%Y/%m/%d')
    res = ""
    for el in soup.find_all("div", class_="zg_itemRow"):
        rank  = el.find("span", class_="zg_rankNumber").string.strip()
        name  = el.find_all("div", class_="p13n-sc-truncate")[0].string.strip()
        price = el.find("span", class_="p13n-sc-price").string.strip()
        # print("{} {} {}".format(rank, price, name))
        out = "{} {} {}".format(rank, price, name)
        res = res + out + "<br />\n"


    # -- SENDERとRECIPIENTのemailは予めSESでVerifyする必要がある
    SENDER = "Sender Name <verified-mail1@gmail.com>"
    RECIPIENT = "verified-mail2@gmail.com"

    AWS_REGION = "us-west-2"   # オレゴンを設定。SESでは東京は使えない。
    SUBJECT = "アマゾン売れ筋ランキング（本）" + today

    BODY_TEXT = ("アマゾン売れ筋ランキング（本）\r\n" + res)

    BODY_HTML = """<html>
<head></head>
<body>
  <h1>アマゾン売れ筋ランキング（本）</h1>
""" +"<div>\n"+res+ "\n</div></body></html>"

    CHARSET = "UTF-8"
    client = boto3.client('ses',region_name=AWS_REGION)

    try:
        response = client.send_email(
            Destination={
                'ToAddresses': [
                    RECIPIENT,
                ],
            },
            Message={
                'Body': {
                    'Html': {
                        'Charset': CHARSET,
                        'Data': BODY_HTML,
                    },
                    'Text': {
                        'Charset': CHARSET,
                        'Data': BODY_TEXT,
                    },
                },
                'Subject': {
                    'Charset': CHARSET,
                    'Data': SUBJECT,
                },
            },
            Source=SENDER,
        )

    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        print("Email sent! Message ID:"),
        print(response['ResponseMetadata']['RequestId'])

    return today    # 適当なreturn値
```


#４．deployと実行ログ

deployします。AWSコンソールでの面倒な設定は一切必要ありません。

```
$ chalice deploy
Creating deployment package.
Updating policy for IAM role: amazon-rank-dev
Updating lambda function: amazon-rank-dev-cron_handler
Resources deployed:
  - Lambda ARN: arn:aws:lambda:ap-northeast-1:335191601883:function:amazon-rank-dev-cron_handler
```

以上で毎日１０時２５分にアマゾンの売れ筋ランキングがメールで送られてくるようになります。



deployしたものをザックリ削除したい時は以下のコマンドでOKです。簡単でいいですね。

```
$ chalice delete
```


また実行ログは、CloudWatchの画面で確認できます。Lambda関数の画面から辿っていった方がうまくたどり着けると思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/61915/3eb0c757-2a2b-2997-a18f-7b5db4accecc.png)


#５．送信されたメール

送られてきたメールは以下の通りです。日本国紀は昨日は３位でしたが、また２位に浮上していますね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/61915/16dc73c4-ac68-b3df-6dec-9a23d9f1fcbf.png)




#★最近の投稿
[Python でいろいろスクレイピング](https://qiita.com/sand/items/f2466320c8dde905cb3b)
[【AWS】Pythonの開発環境Chaliceを使ってみる - アマゾン売れ筋ランキング](https://qiita.com/sand/items/cfdc9957caa0aee63c0f)
[【AWS】Pythonの開発環境Chaliceを使ってみる - CloudWatch Events](https://qiita.com/sand/items/4a4c273872b266af6680)
[【AWS】Pythonの開発環境Chaliceを使ってみる - API Key](https://qiita.com/sand/items/2f8615b03c6f24c85b49)
[【AWS】Python Lambdaのdeploy - Chalice](https://qiita.com/sand/items/4642f417bf0d2b49c7e2)
[【AWS】Python Lambdaのdeploy - CloudFormation](https://qiita.com/sand/items/2b918a29bf08bfb86d32)