前回の続きGo言語でTwitterAPIを使ってツイート検索
用意するもの
Consumer API keys
Access token
Access token secret
こちらを参照してください:https://ahiru8usagi.hatenablog.com/entry/TwitterAPI_KeyAndToken
ソースコード
まずはOAuth認証
config := oauth1.NewConfig(consumerKey, consumerSecret)
token := oauth1.NewToken(token, tokenSecret)
httpClient := config.Client(oauth1.NoContext, token)
ここまでは前回と一緒。
今回は利用するJSONデータについてもメモ。
//リクエスト
//使わないデータはコメント化するなりして無効化する必要がある。Queryだけは必須。
type Request struct{
Query string `json:"query"`
Next string `json:"next"`
}
//レスポンス
//RequestParametersというのがあったけど今回は無視。
type Response struct{
Results []Tweet `json:"results"`
Next string `json:"next"`
}
ResultsがTweetオブジェクトの配列を返してくる。SandboxのSearchAPIでは一度の要求で100個までのツイートしか取れないから、前に返ってきたResponseの中にあるNextを次の要求の時に指定してさらに100個のデータを取ってくる必要がある。Nextが返ってこなかった場合データを取りつくしたことになる。
Requestを投げてresponseのbodyを見るとちゃんとデータが返ってきているのにJSONをパースすることができなかったが、どうやらResultsがresultsになっていたようだ。もしかすると最初の文字は大文字じゃないとダメなのかも。
次はResponseを受け取ってくる関数。
func search(client *http.Client, search *Request)(Response, error){
encoded, err := json.Marshal(search)
//今回はPOST
req, err := http.NewRequest(
"POST",
"https://api.twitter.com/1.1/tweets/search/30day/[Dev environment label].json",//30dayかfullarchive
bytes.NewBuffer(encoded),
)
if err != nil {
return Response{}, err
}
req.Header.Set("Content-Type", "application/json")
//レスポンス
response, err := client.Do(req)
if err != nil {
return Response{}, err
}
b, err := ioutil.ReadAll(response.Body)
if err != nil {
return Response{}, err
}
var result Response
json.Unmarshal(b, &result)
response.Body.Close()
return result ,nil
}
指定するURLは30日間のツイートを取るのか、制限なしでツイートを取ってくるのかによって変わってくる。
前者の場合
https://api.twitter.com/1.1/tweets/search/30day/[Dev environment label].json
後者の場合
https://api.twitter.com/1.1/tweets/search/fullarchive/[Dev environment label].json
[Dev environment label]は図1へ行ったところにある図2の文字列のこと。
図1:TwitterAPIリファレンスの画面
最後にmain関数で受け取ったツイートを表示できるようにする。
func main(){
config := oauth1.NewConfig(consumerKey, consumerSecret)
token := oauth1.NewToken(token, tokenSecret)
httpClient := config.Client(oauth1.NoContext, token)
result, err := search(httpClient, &Request{
Query:"#golang",
})
if err != nil{
fmt.Println(err)
}
for _, tweet := range result.Results{
fmt.Println("text:"+tweet.Text)
}
}
JSONのところでも書いたが、100個以上ツイートを取りたい場合、前回受けっとったNextの値を次のRequestに入れる必要がある。今回、この最低限の機能ができたあたりで無料使用期間が来てしまってデバッグがしばらくできなくなってしまったためそこまで試せていないが(お恥ずかしい…)、アルゴリズムは多分
はじめの要求(Next指定なし)
↓
次の要求(Next指定あり)
↓
次の要求(Next指定あり)
↓以下ループ処理
.
.
.
↓
データ終わり(Nextが返ってこなくなった)
みたいな感じになるかも。
今回もTweetオブジェクトの内容やRequest、Responseも完全には説明できていないので、もっと詳しく見たいという方はAPIリファレンスを参照してください。