Perl入学式 東京第3回、ピザパーティのお題を解く
Perl入学式 東京の第3回にサポーターとして参加させてもらいました。勉強会終了後のピザパーティーで出たお題をやってみたので、そのことについて書いてみます。
やりたいこと
グーグルの検索トレンドデータからキーワードランキングをつくります。ランキングに加えて前日からの推移も含めます。
Googleトレンドのデータは以下のエンドポイントからJSON形式で取れます。
https://trends.google.com/trends/api/dailytrends?geo=JP&ed=yyyymmdd
わかばたいむすさんの記事に詳しくあります。
wakabatimes.com
やってみてわかったこと
・順位の差を求めることができませんでした。前日だとランキング圏外になっていたからです。
・Googleトレンドをみると正しいランキングがすぐわかります。
Google Trends
コード
月初の順位前日比を求めるところと結果の出力はさぼっています。
use strict; use warnings; use feature 'say'; binmode(STDOUT, ":utf8"); use JSON::XS qw/decode_json/; use LWP::Simple; use DateTime; use DDP; # Googleトレンドのエンドポイントにいれる日付をyyyymmddの形式でつくる my $dt = DateTime->now( time_zone => 'Asia/Tokyo' ); my $yyyymmdd = $dt->ymd('/'); my ($y, $m, $d) = split(/\//, $yyyymmdd); my @days = (); # 月初から本日までの日にちを配列にいれる(例. 1,2,3...) if ( $d ne "1" ) { my $c = 1; my @array; $array[$d - 1] = ''; @days = map { $c++; } @array; } else { @days[0] = "1"; } # yyyymmdd形式の文字列に変換する my @dates = (); for my $day ( @days ) { my $dt = DateTime->new( time_zone => 'Asia/Tokyo', year => $y, month => $m, day => $day, ); push(@dates, $dt->ymd('')); } # 配列に用意した各日付のデータをGoogleに問い合わせる my $rankings = {}; for my $target_day (@dates) { say "day => $target_day"; my $rank = 1; my $content = get("https://trends.google.com/trends/api/dailytrends?geo=JP&ed=$target_day"); my $json = substr($content, 6); # 1行目のごみを取り除く my $data = decode_json($json); # 検索ワードのデータまで掘る my $article_array_ref = $data->{default}->{trendingSearchesDays}[0]->{trendingSearches}; # 検索ワードはランク順にならんでいるので、ループしながらランクを付けられる for my $article ( @$article_array_ref ) { my $query = $article->{title}{query}; say $query; $rankings->{$target_day}{$query}{rank} = $rank; $rank++; } } # ランキングにくわえて前日との順位差を入れるハッシュレフを別につくる my $trends = $rankings; my @dates_copy = @dates; shift @dates_copy; my @from_second_day_to_later_days = @dates_copy; my $prev_day = shift @dates; # 検索ワードごとに前日のランクとの差を求める(ただし、前日だとランク圏外になっていて存在しなかった) for my $target_day (@from_second_day_to_later_days) { for my $query ( keys %{$rankings->{$target_day}} ) { my $trend; if ( defined($rankings->{$prev_day}{$query}) ) { $trend = $rankings->{$prev_day}{$query} - $rankings->{$target_day}{$query}; } else { $trend = "new"; } $trends->{$target_day}{$query}{trend} = $trend; } } # デバッグプリント p $trends;
標準出力(一部抜粋)
20190109 { NGT { rank 10, trend "new" }, りんご病 { rank 15, trend "new" }, アジアカップ { rank 9, trend "new" }, サッカーアジアカップ { rank 7, trend "new" }, サッカー日本代表 { rank 5, trend "new" }, トルクメニスタン { rank 3, trend "new" }, バーチャルさんは見ている { rank 14, trend "new" }, ピーチジョン { rank 13, trend "new" }, 兼高かおる { rank 6, trend "new" }, 友井雄亮 { rank 2, trend "new" }, 家売る女 { rank 8, trend "new" }, 尾田栄一郎 { rank 4, trend "new" }, 山口真帆 { rank 1, trend "new" }, 志村けん { rank 12, trend "new" }, 摂津正 { rank 17, trend "new" }, 武田玲奈 { rank 18, trend "new" }, 玉川徹 { rank 16, trend "new" }, 馬毛島 { rank 11, trend "new" } }, 20190110 { はあちゅう { rank 17, trend "new" }, スキャンダル専門弁護士 { rank 5, trend "new" }, ディビジョン { rank 18, trend "new" }, ワンピース { rank 4, trend "new" }, 京王観光 { rank 12, trend "new" }, 刑事ゼロ { rank 10, trend "new" }, 宇賀なつみ { rank 11, trend "new" }, 川谷絵音 { rank 13, trend "new" }, '日本 対 トルクメニスタン' { rank 3, trend "new" }, 星座 { rank 9, trend "new" }, 松本人志 { rank 15, trend "new" }, 森川葵 { rank 14, trend "new" }, 楠ろあ { rank 7, trend "new" }, 盾の勇者の成り上がり { rank 6, trend "new" }, 福男 { rank 8, trend "new" }, 竹下亘 { rank 16, trend "new" }, 純烈 { rank 1, trend -33088 }, 雨宮萌果 { rank 2, trend "new" }