LINEヤフー Tech Blog

LINEヤフー株式会社のサービスを支える、技術・開発文化を発信しています。

テキスト解析 Web API を JavaScript から直接使う( API が CORS に対応しました)

こんにちは。LINEヤフー株式会社でテキストマイニングや自然言語処理などをやっている山下( @yto )です。

最近のことですが、Yahoo!デベロッパーネットワークのテキスト解析 Web API の CORS(Cross-Origin Resource Sharing)対応が完了しました。 CORS についてはここでは解説はしませんが、本稿の観点からざっくり説明すると「別ドメインにあるウェブページ内の JavaScript プログラムからテキスト解析 Web API に直接アクセスして利用できるようになった」ということです。

本稿では、サンプルコードでウェブページからテキスト解析 Web API に直接アクセスする方法を説明していきます。応用例として、Google Chrome 拡張機能のサンプルも紹介します。

Client ID(アプリケーションID)について

テキスト解析 Web API を利用するには Client ID が必要です。 お手数ですが各自 Client ID を取得していただき、 サンプルコード内の

const APPID = 'あなたの Client ID (アプリケーション ID)';

を取得した Clinet ID へ置き換えてご利用ください。

まずは動かしてみる

動作確認用の簡単な HTML ページです。HTML ファイル(index.html など)として保存し、ウェブブラウザで開くと、裏でプログラムがテキスト解析 Web API の「日本語形態素解析」にアクセスし、得られた解析結果を表示します。

<html lang="ja">
  <head>
    <script>
      async function postRequest(query) {
          const APPID = 'あなたの Client ID(アプリケーション ID)';
          const url = 'https://jlp.yahooapis.jp/MAService/V2/parse?appid=' + encodeURIComponent(APPID);
          const response = await fetch(url, {
              method: 'POST',
              mode: 'cors',
              body: JSON.stringify({
                  "id": "A123",
                  "jsonrpc" : "2.0",
                  "method": 'jlp.maservice.parse',
                  "params" : { "q" : query }
              }),
          });
          return await response.json();
      }
      async function main(query) {
          const response = await postRequest(query)
          document.write(response['result']['tokens'].map(x => [x[0], x[3]]))
      }
    </script>
  </head>
  <body onload="main('今日は良い天気です。')" />
</html>

ブラウザには下記のテキストが表示されるかと思います。

今日,名詞,は,助詞,良い,形容詞,天気,名詞,です,判定詞,。,特殊

ポイントは2つあります。 まず、1つ目は、Client ID を Web API に渡すときに、下記のようにリクエスト URL にパラメータを設定すること。

https://jlp.yahooapis.jp/MAService/V2/parse?appid={Client ID}

2つ目はリクエストの mode に cors を設定すること。 これだけです。

インタラクティブなサンプル

入力されたテキストに対してテキスト解析を行うというインタラクティブなサンプルです。

テキスト入力エリアに日本語文を入力して、解析ボタンを押すと、入力された文にルビ(読み仮名)が振られます。 テキスト解析 Web API の「ルビ振り」を利用しています。

先ほどと同様、HTML ファイルとして保存してウェブブラウザで開いてください。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <style>
      * { box-sizing: border-box; }
      textarea { width: 100%; }
    </style>
    <script>
      const APPID = 'あなたの Client ID(アプリケーション ID)';
      async function yapifuri(query) {
          const url = "https://jlp.yahooapis.jp/FuriganaService/V2/furigana?appid=" + encodeURIComponent(APPID);
          const res = await fetch(url, {
              method: 'POST',
              mode: 'cors',
              body: JSON.stringify({
                  "id": "A123",
                  "jsonrpc" : "2.0",
                  "method" : "jlp.furiganaservice.furigana",
                  "params" : { "q" : query, "grade" : 1 }
              }),
          });
          return res.json();
      }
      async function kaiseki() {
          const text = document.querySelector("#input-text").value;
          const j = await yapifuri(text);
          if (!j || !j['result']['word']) return;
          document.querySelector("#output-text").value =
              j['result']['word'].map(
                  x => x['surface'] + (x['furigana'] ? '(' + x['furigana'] + ')' : '')
              ).join("");
      }
    </script>
  </head>
  <body>
    <button onclick="kaiseki()">解析</button>
    <br>
    テキスト入力エリア
    <textarea id="input-text"></textarea>
    テキスト出力エリア
    <textarea id="output-text"></textarea>
  </body>
</html>

図はテキスト入力エリアに「今日は良い天気ですね。」と入力して解析ボタンを押した結果です。 テキスト出力エリアに「今日(きょう)は良い(よい)天気(てんき)ですね。」と表示されました。

Google Chrome 拡張機能のサンプル

CORS 対応のおかげで、ブラウザの拡張機能の中からも直接アクセスできます。 以下が、Google Chrome 拡張機能のサンプルです。ブラウザは Google Chrome を対象とします。

この拡張機能サンプルは、ブラウザで閲覧中のページ内でセレクトしたテキストに対して、テキスト解析 Web API の「キーフレーズ抽出」を適用し、結果を alert() でポップアップ表示します。

図に実行結果を示します。

なお、いろんなサイトで発動すると面倒なのでドメインが (*.yahoo.co.jp/*) の場合のみで動くようにしています。

Google Chrome 拡張機能の導入方法

  • 下記の2つのファイル(後述)を同じフォルダに置きます
    • manifest.json, content-script.js
  • Google Chrome を起動し、chrome://extensions を開きます
  • 右上の「デベロッパー モード」をオンにした後、「パッケージ化されていない拡張機能を読み込む」をクリックし、先ほどのファイルを置いたフォルダを開きます
  • Google Chrome の右上の拡張機能アイコンをクリックし、今回の拡張機能をピン留めしておきます
  • ピン留めしたアイコンをクリックすると、動作の停止などの操作・設定ができます

manifest.json

manifest.json は Google Chrome 拡張機能のための設定ファイルで、基本情報やリソースの指定などを行います。 拡張機能の本体である content-script.js を指定しています。 *.yahoo.co.jp/*以外のドメインのサイトで動かしたい場合は matches を変更してください。

{
    "name": "chex Sample",
    "description": "chex Sample",
    "version": "1.0",
    "manifest_version": 3,
    "content_scripts": [
        {
            "matches": ["https://*.yahoo.co.jp/*"],
            "js": ["content-script.js"]
        }
    ]
}

content-script.js

content-script.js はこの拡張機能の本体です。 ブラウザでページが開かれるとこのファイルが実行されます。 マウスでの選択動作が終わったタイミングで起動する処理をdocument.onmouseup で定義しています。 キーフレーズ抽出 API にアクセスするための関数 yapika() を呼び、その抽出結果キーフレーズを連結して alert() でポップアップします。

document.onmouseup = async function() {
    const selected_text = window.getSelection().toString();
    if (! selected_text) return;
    const j = await yapikp(selected_text);
    const s = j['result']['phrases'].map(x => x['text']).join(" / ");
    if (! s.length) return;
    alert(s);
};
const APPID = 'あなたの Client ID(アプリケーション ID)';
async function yapikp(query) {
    const url = "https://jlp.yahooapis.jp/KeyphraseService/V2/extract?appid=" + encodeURIComponent(APPID);
    const res = await fetch(url, {
        method: 'POST',
	mode: 'cors',
        body: JSON.stringify({
            "id": "A123",
	    "jsonrpc" : "2.0",
	    "method" : "jlp.keyphraseservice.extract",
            "params" : { "q" : query }
        }),
    });
    return res.json();
}

おわりに

テキスト解析 Web API が CORS 対応され、ブラウザから直接アクセスして使えるようになりました。 サイトへのちょっとした機能追加(ページ内の全テキストへの自動ルビ振り、抽出したキーフレーズによる検索クエリ拡張など)が手軽に実現できますので、ぜひご利用いただければと思います。

また、テキスト解析 Web API には今回紹介したサンプルで用いた日本語形態素解析、ルビ振り、キーフレーズ抽出以外にもさまざまな機能があります。 これらは共通のインターフェースでアクセスできるように設計されています(参考)。サンプルを少し変更するだけで簡単に使えますのでぜひお試しください。