Twitter API と Cloud Vision API を使って楽にデータを収集する

はじめに

GameWithのアドベントカレンダー2日目です。

qiita.com

やりたいこと

サービスを作ろうと思った時、データの調達がネックになることがあるかと思います。
その解決方法として、Cloud Vision API が雑にデータを集めるのに便利そうなので
ゲームのデータを例に試してみようと思います。

方法

以下の流れで進めます。
- Twitter APIで特定のハッシュタグがついているツイートを取得する
- ツイートに添付されている画像を取得する
- 画像をCloud Vision APIに投げてタイトルを取得する
- タイトルとアイコン(画像)のデータを蓄積していく

Twitter API の利用

今回対象にするハッシュタグ#あなたを作り上げたゲーム4選 です。
定期的に多くの人が投稿しており、1ツイートに4タイトル分の画像が添付されています。
デベロッパー登録をすればダッシュボードで各トークンを発行できます。
エンドポイントごとに色々と制限がついているんですが、
無料版だとSearch APIは7日以内のツイートしか検索できない制限がありました...
(宇宙の 法則が 乱れる!)

'use strict'

equire('dotenv').config()
const twitter = require('twitter')

const authConfig = {
    consumer_key: process.env.CONSUMER_API_KEY,
    consumer_secret: process.env.CONSUMER_API_SECRET_KEY,
    access_token_key: process.env.ACCESS_TOKEN,
    access_token_secret: process.env.ACCESS_TOKEN_SECRET
}

const client = new twitter(authConfig)

const main = () => {
    client.get(
        'search/tweets',
        {
            q: '#あなたを作り上げたゲーム4選',
            count: 2,  // 7日以内のツイート2件しかなかった...

        }, (error, tweets, response) => {
            if (error) {
                console.log('error', error)
            }
            for (let item in tweets.statuses) {
                let tweet = tweets.statuses[item];
                // tweet url
                console.log('https://twitter.com/'+tweet.user.screen_name+'/'+tweet.id_str)
                if (tweet.extended_entities) {
                    let urls = tweet.extended_entities.media
                    for (let i in urls) {
                        // media url
                        console.log(urls[i].media_url_https)
                    }
                }
            }
        }
    )
}

main()

Cloud Vision API の利用

ローカルにファイルを置いて指定するか、またはCloud Storageのパスを指定して利用できます。
今回は数件しかデータを引っ張ってこられなかったので、ローカルにダウンロードして簡易に試してみました。

'use strict'

async function main() {
    const vision = require('@google-cloud/vision')
  
    const client = new vision.ImageAnnotatorClient()
  
    const [result] = await client.webDetection('PATH/TO/FILE')

    console.log('description(score):')
    const webEntities = result.webDetection.webEntities
    webEntities.forEach(item => console.log(item.description+"("+item.score+")"))
  }
  
  main().catch(console.error);

結果

今回選んだテーマだと、ゲームの内容がわかりやすいパッケージ画像が多く使われていたので、
結構な高確率で正解のタイトルを導き出せていました。
PlayStation 2 などの属性データもちゃんと整理すれば、リッチなデータになりそうです。
この精度であれば、アニメ、漫画はもちろん、本や車など色々なカテゴリで利用できそうな気がします。

取得できたデータの結果例

## シャドウハーツ2
description(score):
PlayStation 2(1.564976692199707)
Shadow Hearts: Covenant(1.2087900638580322)
Shadow Hearts(1.1695201396942139)
Shadow Hearts: From the New World(1.0350451469421387)
Director's cut(0.6541000008583069)
Role-playing game(0.5997999906539917)
Role-playing video game(0.4950000047683716)
Resident Evil: Director's Cut(0.3718999922275543)

## ファイナルファンタジー10
description(score):
Final Fantasy X(1.6647182703018188)
Final Fantasy XV(0.9572311043739319)
PlayStation 2(0.7267500162124634)
Final Fantasy(0.6920100450515747)
Final Fantasy X-2(0.6174630522727966)
Role-playing game(0.5641999840736389)
Final Fantasy VI(0.5611650347709656)
Role-playing video game(0.4462999999523163)

## ルール オブ ローズ
description(score):
PlayStation 2(1.1223961114883423)
Rule of Rose(1.105049967765808)
Survival horror(0.7020999789237976)
Silent Hill(0.503849983215332)
Soundtrack(0.4196000099182129)
Survival game(0.39160001277923584)
Psychological horror(0.32030001282691956)
horror video game(0.31380000710487366)

終わりに

Twitter API の制限に引っ掛かり上手くデータの蓄積までできなかったので、
スクレイピングなど別の方法で代用して進めていこうと思います。

今回は GoogleVision AI を利用しているので、 Google Cloud Platform内で完結するのが楽な気がしています。 以下のようにほぼ Firebase を触るだけでよさそうです。

スクリプトの定期実行 = Cloud Functions
データの蓄積 = Cloud Firestore / Cloud Storage
データを使ったWebサービス = Firebase Hosting

Cloud Vision API は ↓でブラウザ上でも使えるのでみなさん試してみてください。

cloud.google.com