+use Data::Dumper; # リファレンス覗き用
+use JSON qw/decode_json/
+ ; # json形式のデータをPerlのデータ形式にする
+use LWP::Simple qw/get/; # インターネット上のデータを取得する
+use utf8; # プログラム中に日本語を書く時に利用
+# Googleトレンドの急上昇キーワードをAPIで取得してみる
+# https://wakabatimes.com/google%E3%83%88%E3%83%AC%E3%83%B3%E3%83%89%E3%81%AE%E6%80%A5%E4%B8%8A%E6%98%87%E3%82%AD%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%89%E3%82%92api%E3%81%A7%E5%8F%96%E5%BE%97%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B
+# The Fastest JSON visualizer
+# http://kimihiro-n.site44.com/json_dump/index.html
+# Googleトレンドを取得する日付を配列に入れる
+my @date = ('20181231'); # 開始日
+# 1月18日までの日付(yyyymmdd形式)を組み立てて配列に入れる
+for my $day ( 1 .. 18 ) {
+ # sprintf関数で、$dayが1桁の時は左側に0が入る
+ my $date = '201901' . sprintf( '%02d', $day );
+my %date_query; # date をkeyとするデータ構造
+my %query_date; # query をkeyとするデータ構造
+ # 日付をもとに、非公式APIのURLを1日ずつ組み立てる
+ my $uri = 'https://trends.google.com/trends/api/dailytrends?geo=JP&ed='
+ my $res = get($uri) or die;
+ $res = substr( $res, 6 );
+ # json形式のデータをPerlのデータ構造に変換する
+ my $json = decode_json($res);
+ = @{ $json->{default}->{trendingSearchesDays}->[0]->{trendingSearches}
+# クエリー(検索語)を取り出して、%date_query を組み立てていく
+ while ( my ( $ranking, $body ) = each @trendingSearches ) {
+ my $query = $body->{title}->{query};
+ # ランキングとクエリー(検索語)をハッシュに格納する
+ my %entry = ( ranking => $ranking, query => $query );
+# date_query->{日付} に追加していく
+# (配列リファレンスに、ハッシュリファレンスを追加する)
+ push @{ $date_query{$date} }, \%entry;
+# クエリー(検索語)と日付をkey、ランキングをvalueとするデータ構造を作る
+ $query_date{$query}{$date} = { ranking => $ranking };
+for my $query ( sort keys %query_date ) {
+# クエリー(検索語)のvalueである登場した日付を取得する
+ for my $date ( sort { $a <=> $b } keys %{ $query_date{$query} } ) {
+# クエリー(検索語)の登場回数を日付ごとに count というkey に記録する
+ $query_date{$query}{$date}->{count} = $count;
+# クエリー(検索語)登場した日付を配列リファレンスにpushする
+ push @{ $query_date{$query}{history} }, $date;
+ my @history = @{ $query_date{$query}{history} };
+# 配列の要素の数が1より大きい場合には、過去に出現したと判断
+ if ( scalar @history > 1 ) {
+# 配列の添字を[−2]とすることで、末尾から2番目の要素
+# (前回、クエリー(検索語)が出現した時の日付)を取得し、
+ $query_date{$query}{$date}{last_time} = $history[-2];
+# $date_query からから日付順に処理
+for my $date ( sort { $a <=> $b } keys %date_query ) {
+ my $year = substr( $date, 0, 4 );
+ my $month = substr( $date, 4, 2 );
+ my $day = substr( $date, 6, 2 );
+ print encode( 'utf8', "-- ${year}年${month}月${day}日 --" ), "\n";
+ # $date_query{日付} は配列リファレンス。
+ # その日のクエリー(検索語)を順番に取り出す。
+ for my $entry ( @{ $date_query{$date} } ) {
+# ランキングの順位を2桁にするために sprintf を使う
+# ランキングは0始まりなので、 +1 して人間が読みやすく変換する。
+ my $ranking = sprintf( '%02d', $entry->{ranking} + 1 );
+ my $query = $entry->{query};
+# 前回出現した日付。ない場合には空文字 '' をセットする
+ my $last_time = $query_date{$query}{$date}->{last_time} // '';
+# 前回出現した日付がある場合、それを表示する文字列を作成する
+ my $last_time_ranking = $query_date{$query}{$last_time}{ranking};
+ $last_time_ranking += 1;
+ my $year = substr( $last_time, 0, 4 );
+ my $month = substr( $last_time, 4, 2 );
+ my $day = substr( $last_time, 6, 2 );
+ . "[前回出現:${year}年${month}月${day}日 ${last_time_ranking}位]";
+ # マルチバイト文字列(日本語)を表示するのでencodeする
+ my $encoded_str = encode( 'utf8', $query );
+ printf( "%02d %-20s \n", $ranking, $encoded_str ),;