Edited at

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

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


1.プログラム概要

本システムはPythonのプログラムのコア機能として、BeautifulSoupを使って、アマゾンの「売れ筋ランキング(本)」のページをスクレイピングします。スクレイピングについては以下の記事が詳しいですね。

PythonでWebスクレイピングする時の知見をまとめておく

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

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

今回のプログラムは、コア機能を除けば、以下の過去記事と同じものです。

【AWS】Pythonの開発環境Chaliceを使ってみる - CloudWatch Events


2.ライブラリインストール

環境は基本的に以下の記事の環境設定を基本としています。

【AWS】Python Lambdaのdeploy - Chalice

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

$ chalice new-project amazon-rank

$ cd amazon-rank

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

pip install beautifulsoup4 -t vendor

pip install lxml -t vendor


3.ソースコード


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値



4.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

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

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

$ chalice delete

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

image.png


5.送信されたメール

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

image.png


★最近の投稿

Python でいろいろスクレイピング

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

【AWS】Pythonの開発環境Chaliceを使ってみる - CloudWatch Events

【AWS】Pythonの開発環境Chaliceを使ってみる - API Key

【AWS】Python Lambdaのdeploy - Chalice

【AWS】Python Lambdaのdeploy - CloudFormation