今回は、与えられたURLのワードクラウドを表示するプログラムをPHPで作ってみることにする。
目次
サンプル・プログラム
| WordCloud.php | サンプル・プログラム本体。 |
| .pahooEnv | クラウドサービスを利用するためのアカウント情報などを記入する .env ファイル。 使い方は「各種クラウド連携サービス(WebAPI)の登録方法」を参照。include_path が通ったディレクトリに配置すること。 |
| pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 2.2.0 | 2023/12/16 | 日本語形態素解析V2対応 |
| 2.1 | 2021/10/02 | PHP8対応,リファラチェック改良 |
| 2.1 | 2017/04/09 | PHP7対応 |
| 2.0 | 2014/08/02 | 大幅改訂 |
| 1.1 | 2009/06/20 | chunked対応、ぱふぅ家のホームページ以外に対応 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 2.0.1 | 2025/08/11 | getParam() bug-fix |
| 2.0.0 | 2025/08/11 | pahooLoadEnv() 追加 |
| 1.9.0 | 2025/07/26 | getParam() 引数に$trim追加 |
| 1.8.1 | 2025/03/15 | validRegexPattern() debug |
| 1.8.0 | 2024/11/12 | validRegexPattern() 追加 |
準備:PHP の https対応
Windowsでは、"php.ini" の下記の行を有効化する。
extension=php_openssl.dllLinuxでは --with-openssl=/usr オプションを付けて再ビルドする。→OpenSSLインストール手順
これで準備は完了だ。
準備:pahooInputData 関数群
また、各種クラウドサービスに登録したときに取得するアカウント情報、アプリケーションパスワードなどを登録した .pahooEnv ファイルから読み込む関数 pahooLoadEnv を備えている。こちらについては、「各種クラウド連携サービス(WebAPI)の登録方法」をご覧いただきたい。
必要な機能
- URLからコンテンツを取り出す。
- コンテンツから単語を切り出し、出現頻度を数える。
- 出現頻度の高い単語ほど大きく表示する。
3.は、後述する 関数によって実現する。
準備:初期値など
WordCloud.php
64: // 初期値(START) =============================================================
65:
66: // 表示幅(ピクセル)
67: define('WIDTH', 600);
68:
69: // -- 以下のデータは .env ファイルに記述可能
70: // Yahoo! JAPAN Webサービス アプリケーションID【各自で設定】
71: // 取得方法:https://www.pahoo.org/e-soul/webtech/php06/php06-01-02.shtm#Yahoo
72: if (isset($_ENV['PAHOO_YAHOO_APPLICATION_ID'])) {
73: define('YAHOO_APPLICATION_ID', $_ENV['PAHOO_YAHOO_APPLICATION_ID']);
74: } else {
75: define('YAHOO_APPLICATION_ID', '');
76: }
77:
78: // リクエストURL【変更不可】
79: define('YAHOO_MAService_URL', 'https://jlp.yahooapis.jp/MAService/V2/parse');
80:
81: // ワードクラウドを表示するときの最大フォントサイズ(%)
82: define('MAX_FONT_SIZE', 250);
83: // ワードクラウドを表示するときの最小フォントサイズ(%)
84: define('MIN_FONT_SIZE', 80);
85:
86: // リンク先の検索対象ドメイン名
87: define('SEARCH_DOMAIN', 'pahoo.org');
88:
89: // サンプルURL
90: define('DEF_URL', 'https://www.pahoo.org/e-soul/webtech/php01/php01-01.shtm');
91:
92: // 初期値(END) ===============================================================
取得したIDは、.pahooEnv ファイルに記入するか、定数 APPLICATION_ID に格納する。
解説:ワードクラウドの作成
WordCloud.php
275: /**
276: * ワードクラウドを作成する
277: * @param array $items 情報を格納した配列
278: * @return string ワードクラウド(HTML)
279: */
280: function getWordCloud($items) {
281: $outstr = '';
282: $n = 0;
283:
284: // 出現頻度の最大値・最小値を調べる
285: $countMax = 0;
286: $countMin = 0;
287: foreach ($items as $surface=>$val) {
288: if (isDisplayWord($surface, $val['pos'])) {
289: if ($val['count'] > $countMax) $countMax = $val['count'];
290: if ($val['count'] < $countMin) $countMin = $val['count'];
291: }
292: }
293: $k = (MAX_FONT_SIZE - MIN_FONT_SIZE) / ($countMax - $countMin);
294:
295: foreach ($items as $surface=>$val) {
296: if (isDisplayWord($surface, $val['pos'])) {
297: $n++;
298: $count = $val['count'];
299: $fsize = (int)($k * $val['count'] + MIN_FONT_SIZE);
300: if ($fsize < MIN_FONT_SIZE) $fsize = MIN_FONT_SIZE;
301: if ($fsize > MAX_FONT_SIZE) $fsize = MAX_FONT_SIZE;
302: $link = getLink($surface);
303: if ($n > 1) $outstr .= ",\n";
304: $outstr .=<<< EOT
305: <span style="font-size: {$fsize}%;">
306: <a href={$link}>{$surface}</a>
307: </span>
308:
309: EOT;
310: }
311: }
312: return $outstr;
313: }
ある単語の表示フォントサイズ(%) $ S_n $ は下記の計算式で算出する。
$$ S_n = k C_n + S_{min} \] \[ k = \frac{S_{max} - S_{min}}{C_{max} - C_{min}} $$
$ S_{max} $ ‥‥最小表示フォントサイズ(%)
$ S_{min} $ ‥‥最大表示フォントサイズ(%)
$ C_{max} $ ‥‥単語の最大出現回数
$ C_{min} $ ‥‥単語の最小出現回数
$ C_n $ ‥‥ある単語の出現回数
WordCloud.php
239: /**
240: * ワードクラウド表示時における個々の単語のリンク先URLを取得する
241: * @param string $surface 見出し語
242: */
243: function getLink($surface) {
244: $url = 'https://www.google.com/search?hl=ja&lr=lang_ja&q='; // Google検索
245: $site = SEARCH_DOMAIN; // 検索絞り込みドメイン名
246:
247: return $url . urlencode($surface) . '+site%3A' . $site;
248: }
ここでは、その単語をGoogle検索に投げ、その際に site で絞り込み検索を指定するようにした。$site には自サイトのURLを入れておけばいいだろう。
解説:コンテンツの取り出し
WordCloud.php
155: /**
156: * コンテンツの必要な部分を読み込む
157: * @param string $url コンテンツのURL
158: * @return string 読み込んだコンテンツ/FALSE=失敗
159: */
160: function myGetContents($url) {
161: $instr = @file_get_contents($url);
162: $instr = mb_convert_encoding($instr, INTERNAL_ENCODING, 'auto');
163: if ($instr == FALSE || $instr == '') return FALSE;
164:
165: // scriptを除く
166: $arr = array();
167: $ss = preg_match('/\<body.*?\>(.*?)<\/body\>/imsu', $instr, $arr);
168: $ss = preg_replace('/\<script.*?\>.*?<\/script\>/imsu', '', $arr[1]);
169: $ss = preg_replace('/\<style.*?\>.*?<\/style\>/imsu', '', $ss);
170: $ss = preg_replace('/\ \;/imsu', '', $ss); // を除く
171: $ss = strip_tags($ss); // タグを除く
172: $ss = html_entity_decode($ss); // 特殊文字を通常文字に変換
173: $outstr = preg_replace('/\n|\r|\r|\t/', '', $ss); // 改行、タブを除く
174:
175: return $outstr;
176: }
まず、URLの全体を getParse に渡すのは非合理的だ。ヘッダやフッタなど、コンテンツとして分析する必要がない部分も含まれてしまう。
そこで用意したのがユーザー関数 myGetContents である。
まず、関数 file_get_contents を使ってコンテンツ全体を変数 $instr に取り込む。
次に、 preg_match を使って、<body> タグ内だけ切り出す。
続いて、<script> タグや<style> タグ内は省く。特殊文字 無視する。
最後に、関数 strip_tags 、 html_entity_decode 、 preg_replace を使い、HTMLやPHPのタグ、特殊文字、改行・タブなどを消去しておく。
ユーザー関数 my_get_contents については、解析したサイトの状況に合わせて変更してほしい。
質疑応答
define('REFER_ON', '');【回答】
アプリケーションIDを入力し、リンク先ドメイン名を入力サンプルURLをワードクラウドを作りたいページにし、以上の変更を加えたのに、上記の結果に。
まだほかに修正する個所があるのでしょうか
プログラムが使用しているYahoo!JAPANのWebAPI「日本語形態素解析」がバージョンアップし、旧バージョンは使用できなくなりました。プログラムを新しいバージョンに対応させましたので、お試しください。
また、アプリケーションエラーを表示したときは、プログラム冒頭にある FLAG_RELEASE の定義を
define('FLAG_RELEASE', FALSE);
としていただくことで、詳しいエラーを表示するようになります。
参考サイト
- PHPで形態素解析を行う:ぱふぅ家のホームページ
- PHPでURLエンコードを行う:ぱふぅ家のホームページ
- PHPでキーフレーズを取り出す:ぱふぅ家のホームページ
