読者です 読者をやめる 読者になる 読者になる

Python3でGoogle PlayのレビューをSlackに定期投稿

Python3でGoogle PlayのレビューをSlackに定期投稿

f:id:AdwaysEngineerBlog:20160903011918p:plain

こんにちは、エンジニアのワタナベです。

エンジニアのワタナベは最近、会社のAndroidアプリの評価が気になっています。 というのも、レビューを見れば自分たちの仕事が良いのか悪いのか、どのリリースがどれくらい評価なのか、どのように改善すべきで、どこを維持すべきなのかといったことがレビューには詰まっていると思うからです。

しかし、四六時中Google Playを見ているというのも中々できません。

Adwaysでは業務の連絡にSlackを使っています。Slackはこちらの記事にもあるように

これらのユーザーはメッセージをチェックするためだけに来ているのではない。彼らはSlackに住んでいる。平均的ユーザーは平日にSlackで10時間過ごしている。同サービスには、2月時点で平日1日当たり3.2億分のアクティブ利用があり、これは平日1ユーザー当たり140分に相当する。

Slackすごいですね。かく言う私もSlackはふと気づくと見てしまっていたりするときが多いです。 ここにレビューを定期的に投稿したら、もっとレビューを見る機会が増やせそうだと思いました。 そして、思い立ったが吉日です。

残念ながら、Google Playではレビュー取得などのAPIは提供されていないようなので、スクレイピングしてSlackにポストします。 Google PlayのレビューページのHTMLを眺めていたところ、Google Playはレビュー情報を静的にHTMLに入れているようです。

今回はさっくりと作ってしまいたかったので、Pythonで書きました。 Adwaysの業務ではあまり使われていませんが、体感ではRubyよりPythonのほうが小さいスクリプトを作るときは楽チンです(あくまで個人の感想です)。

依存モジュールのインストール

$ pip install requests          # HTTPリクエストを簡単に送れるモジュール
$ pip install beautifulsoup4    # HTMLレキサ&パーサ
$ pip install slacker           # Slackに簡単に投稿できるモジュール

Slackへ投稿

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import requests
from time import sleep
from datetime import datetime
from bs4 import BeautifulSoup
from slacker import Slacker

MAX_STAR = 5

DATE_FORMAT = '%Y년 %m월 %d일'
REVIEW_PAGE = 'https://play.google.com/store/apps/details?id=kr.co.ytop10&hl=ko'
API_KEY = 'Slackで生成したAPIキーを入れる'
SLACK_CHANNEL = '#general'

# Google PlayのレビューがあるページにGETリクエストを送る
res = requests.get(REVIEW_PAGE)

soup = BeautifulSoup(res.text, 'lxml')
messages = []

# HTMLのタグを元にレビュー情報を抽出する
for review in soup.select('.single-review'):
    author = review.select('.author-name')[0].text.strip()
    date = datetime.strptime(review.select('.review-date')[0].text.strip(), DATE_FORMAT)
    
    # style属性のwidth値から評価(★の数)を計算する
    # 20:  ★☆☆☆☆
    # 40:  ★★☆☆☆
    # 60:  ★★★☆☆
    # 80:  ★★★★☆
    # 100: ★★★★★
    black_star = int(re.search(r'width:\s*(\d+)%',
                               review.select('.current-rating')[0].get('style')).group(1)) // (100 // MAX_STAR)
    review_body = review.select('.review-body')[0].text.strip()

    message = {
        'author': author,
        'date': date,
        'black_star': black_star,
        'review_body': review_body,
    }

    messages.append(message)

# Slack投稿用にSlackerインスタンスを作る
slack = Slacker(API_KEY)

# 日付が前日分のレビュー情報をSlackに投稿する
for m in sorted(messages, key=lambda m: m['date']):
    today = datetime.now().date()
    if m['date'].date() >= today.replace(day=today.day - 1):
        message = '\n'.join([
            '[author] {}'.format(m['author']),
            '[date] {}'.format(m['date'].strftime(DATE_FORMAT)),
            '[star] {}'.format('★' * m['black_star'] + '☆' * (MAX_STAR - m['black_star'])),
            '{}'.format(m['review_body']),
            '-' * 100,
        ])

        print(message)
        slack.chat.post_message(SLACK_CHANNEL, message)
        sleep(1)

このコードを実行すると、前日分のレビューがターミナルに表示されつつ、Slackチャンネルにも投稿されます。

Slack投稿の上で編集が必要なのは上のほうにある、定数です。

DATE_FORMAT : Google Playのレビューに表示されている日付のフォーマットです 今回は韓国版予約TOP10だったので、韓国の日付フォーマットになっていますが、取得したい国の言語に合わせて変える必要があります。 例えば、日本語(ja)だと%Y年%m月%d日、英語だと%b %d, %Yです。

REVIEW_PAGE : Google Playのアプリ詳細ページです。 最後の&hl=koの部分を変えれば別な言語のレビューも取得できます。 例えば、&hl=ja&hl=enなどです。

API_KEY : SlackのAPIトークンです。https://api.slack.com/docs/oauth-test-tokensで発行できます。

SLACK_CHANNEL : レビューの投稿先です。

以上の定数を変えれば、他のアプリ・他のチャンネルにレビューを投稿できるようになります。

あとは、cronデーモンに定期的にスクリプトを動かしてもらうようにすれば完了です。

$ crontab -e
MAILTO=""
00 10 * * * bash -lc 'python /path/to/script.py >>/tmp/standard.log 2>>/tmp/error.log'

これで毎朝10時に動くようになりました。 Slackだとすぐに確認できて便利です。 レビューを参考にこれからも良いサービスを作れるようにしていきたいですね。

それでは今回はこれで 次回よろしくお願いします~。