Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

ReactでGoogleトレンドを挿入してみる

今回はReactにてページにGoogleトレンドを挿入方法についてまとめたいと思います!!
単純には、Googleトレンド自体をページ内に表示すればそれで済む気もしますが、カスタマイズ性は自分で作ったほうが高いので挑戦しました!!

Googleトレンドとは?

特定の期間内でどのようなキーワードが多く検索されているかをチェックすることができるツールです。
検索では、文字以外にも画像やニュース、yutube検索などが行えます。

本ツールを用いることで検索数の動向から現在のトレンドをいち早く知ることができるツールとなります。

■ReactへのGoogleトレンド挿入

pythonだとpytrendsというGoogleトレンド用のAPIが存在するのですが、Reactだとどうなんだろう??
調べてみた結果、APIが用意されておりました。
APIというよりウェジェットですね。

stack overflowにてquestion & answerがなされおり、
そちらにサンプルも載っておりましたので参考にさせて頂くことに。
reactjs - How to Embed Google Trends into React app - Stack Overflow


利用するファイルはApp.jsとGoogleTrend.jsであり、それぞれのコードはこちらになります。

// App.js

import React from "react";
import GoogleTrends from "./GoogleTrends";

export default function App() {
  return (
    <>
      <div id="widget">
        <GoogleTrends
          type="TIMESERIES"
          keyword="Celine Dion"
          url="https://ssl.gstatic.com/trends_nrtr/2051_RC11/embed_loader.js"
        />
      </div>
    </>
  );
}
// GoogleTrends.js

import React from "react";
import ReactDOM from "react-dom";
import Script from "react-load-script";

export default function GoogleTrends({ type, keyword, url }) {
  const handleScriptLoad = _ => {
    window.trends.embed.renderExploreWidgetTo(
      document.getElementById("widget"),
      type,
      {
        comparisonItem: [{ keyword, geo: "US", time: "today 12-m" }],
        category: 0,
        property: ""
      },
      {
        exploreQuery: `q=${encodeURI(keyword)}&geo=US&date=today 12-m`,
        guestPath: "https://trends.google.com:443/trends/embed/"
      }
    );
  };

  const renderGoogleTrend = _ => {
    return <Script url={url} onLoad={handleScriptLoad} />;
  };

  return <div className="googleTrend">{renderGoogleTrend()}</div>;
}

まずGoogleTrends.jsから。
Gooleトレンドでの検索結果表示ウェジェットのコードはこちらになります。

  const handleScriptLoad = _ => {
    window.trends.embed.renderExploreWidgetTo(
      document.getElementById("widget"),
      type,
      {
        comparisonItem: [{ keyword, geo: "US", time: "today 12-m" }],
        category: 0,
        property: ""
      },
      {
        exploreQuery: `q=${encodeURI(keyword)}&geo=US&date=today 12-m`,
        guestPath: "https://trends.google.com:443/trends/embed/"
      }
    );
  };

"type"には表示するグラフ、keywordには検索ワードが代入されます。
また、"geo"にて検索対象国を設定します。
コードはUSですが、JPにすることで日本国内指定が可能になります。

こちらのウェジェットを、

  const renderGoogleTrend = _ => {
    return <Script url={url} onLoad={handleScriptLoad} />;
  };

により画面描画時に表示するようなコードになっています。

このGooleトレンドのウェジェットをページに挿入(埋め込む)ためのコードが、
App.jsのこちらにあたります。

      <div id="widget">
        <GoogleTrends
          type="TIMESERIES"
          keyword="Celine Dion"
          url="https://ssl.gstatic.com/trends_nrtr/2051_RC11/embed_loader.js"
        />

GoogleTrendsタグで、typeとkeywordとurlを指定する必要があります。
typeとkyewordは先ほど記載した通り、
"type"には表示するグラフ、keywordには検索ワード
が該当します。
urlは基本的にはこちらのソース流用で問題ないです。

こちらを実行すると確かにkeywordに指定した検索ワードに対するGoogleトレンド結果が表示されました。

■サンプルコード改良

サンプルだと検索ワードをソースに埋め込まないといけないため、自由にワード入力・検索ができないです。
そこで、ワード入力によりGoogleトレンド結果が表示できるようにコードの修正を試みました!!

が、、、どうもにも簡単ではない😢
どうにも、

  const handleScriptLoad = _ => {
    window.trends.embed.renderExploreWidgetTo(

の箇所で、

<Script url={url} onLoad={handleScriptLoad} />

のようにonLoadでコールした場合には有効になるのだが、それ以外のパターンでは

window.trends.embed.renderExploreWidgetTo

がこんな感じでundefinedになってしまう。。。

Uncaught TypeError: Cannot read property 'embed' of undefined

複数回連続でアクセスされると負荷がかかるから初回時のみ有効になる仕様にしているのかな?
window.trends.embedはGoogleトレンドが提供している部分だからこちらからだとどうしようもない😨


ということで、苦肉の策!!
検索画面と結果表示画面を分けることにしました!!

画面遷移方法については別ブログにまとめるとして、結果はこんな感じになりました!!
f:id:Elsammit:20201003145048g:plain



コードはこちら。

//App.js

import React from "react";
import GoogleTrends from "./GoogleTrends";
import "./style.css";
import { BrowserRouter, Route, Link } from 'react-router-dom'

export default class Google extends React.Component  {
  constructor (props) {
    super(props);
    this.state = {
        Search:"",
        type:"TIMESERIES",
        url:"https://ssl.gstatic.com/trends_nrtr/2051_RC11/embed_loader.js",
    };
  }

  doSomething = () =>{
    var ElementName = "SearchName";
    console.log(ElementName)
    var input = document.getElementById(ElementName).value;
    
    this.setState({
      Search:input
    })
  }

  InputForm = () => {
    return(
      <div>
        <h1> Googleトレンド検索画面</h1>
        <input type="text" id="SearchName" maxLength="50"/><br/>
        <button>
            <Link to='/about' onClick={this.doSomething}>確定</Link>
        </button>
      </div>
    );
  }

  ResultForm = () =>{
    const {Search} = this.state;
    return (
      <div>
        <h1> Google検索結果</h1>
        <div id="widget">
          <GoogleTrends
            type="TIMESERIES"
            keyword={Search}
            url="https://ssl.gstatic.com/trends_nrtr/2051_RC11/embed_loader.js"
          /> 
          <button>
            <Link to='/'>戻る</Link>
          </button>
        </div>
      </div>
    );
  }

  render(){
    return (<div>
      <BrowserRouter>
        <div>
          <Route path='/about' component={this.ResultForm} /> 
          <Route exact path='/' component={this.InputForm} />
        </div>
      </BrowserRouter>
    </div>);
    }
  }

■最後に

今回自前でGoogleTrends.jsを用意しましたが、APIを公開している方もいらっしゃいました。
https://github.com/null-none/widget-google-trends

ただ、こちらを利用すると
syntaxErrorが発生してしまい、うまく利用できませんでした。
GitHubのIssueにも上がっている問題でOpen状態なので現在修正中なのかな??それともドロップかな??
このようにAPIとして提供いただけると利用側はとても便利ですね。

後、せっかくGoogleトレンドがページに挿入できるようになったので何かいいアプリ作れたらいいな😊