検索エンジンを作る

第14回 テキスト情報の抽出[その1]

この記事を読むのに必要な時間:およそ 3 分

HTML文書フィルタ

HTML文書フィルタは,文字コードの判定と変換を行った後に,構文解析を行うという2つのステップで動作しています。

文字コードの判定と変換

HTML用の文書フィルタでは,テキストファイルと同様に文字コードの判定や,変換処理の機能が必要です。HTMLの場合には<head>のエレメントの中に次のような文字コードの指定表現があるので,これを手がかりにできます。

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

XHTMLの場合にも同様に,ファイルの先頭の次のような文字コードの指定を元に判定できます。

<?xml version="1.0" encoding="UTF-8"?>

また,Unicodeの場合にはファイルの先頭にBOMが付いていることもあるので,こちらも手がかりにできます。XMLファイルの文字コード判定に関しては,次の本に詳しく解説されています。

『改定版標準XML完全解説(上)』中山幹敏,奥井康弘著/技術評論社/ISBN4-7741-1186-4

文字コード指定が記述されていないHTMLやXHTMLの場合には,前述のテキストファイル用文書フィルタでのロジックで自動判定を行っています。

文字コードが判定できたら,ファイルの内容をUTF-16の内部表現に変換します。次にHTMLパーサで構文解析をしながら,テキスト情報を抽出します。HTMLはタグを単純に外してテキスト情報を抽出するだけではだめで,かなり構文に応じた処理が必要になります。

実体参照の展開

内部表現のUTF-16のイメージに変換した状態では,実体参照がそのままになっています。実体参照とは次の表のようなものです。

実体参照文字
&amp; &
&lt; <
&gt; >
&apos; '
&quot; "

HTML内には直接&などのいくつかの文字を記述できないために,これらを実体参照という表現に置き換えて記述します。実体参照で記述されたテキストは,元の文字に戻す作業を構文解析と同時に行っています。

タグ関する特殊処理

構文解析を行いながら,いくつかのタグについて特殊な処理を行っています。

まずは,headの要素中のtitleタグです。<title>と</title>で挟まれた文字列は文書のタイトルの情報なので,タイトルのプロパティとして出力します。

body要素から下のテキスト情報に関しては、script, styleタグに注意しなければなりません。HTMLに埋め込まれたJavaScript等のスクリプトは、次のように記述されます。

<script>
 // JavaScript等のスクリプト
 document.write("Hello!");
</script>

body要素から下のテキスト情報を単純に抜き出してしまうと、このようなスクリプトまで抜き出されてしまいます。当然、全文検索の対象としてはふさわしくない文字列なので(スクリプトだけ検索したいという特殊な用途もあるかもしれませんが⁠⁠、scriptのタグで挟まれた範囲は全て出力対象から外します。

同様の理由で、styleタグで挟まれているCSSの記述範囲も出力対象外とします。styleタグを認識しないブラウザのために、次のようにCSSの記述範囲を<!--と-->で挟んでコメントにすることが推奨されていますが、コメントとせずにCSSを記述し、body内にstyleタグを記述してしまう誤用への対応です(styleタグはhead内で使われることになっていますが、body内に記述される例も良く見受けられます⁠⁠。

<style type="text/css">
<!--
  H1 { color: blue; }
-->
</style>

リンク情報の抽出

HTMLの中に,次のようなリンクの記述が存在したとします。

<a href="....">だるま市</a>

このリンクは,周囲の文章が「だるま市」に関して言及していることを示しています。リンクの記述は,局所的なトピックを詳しく示している可能性があります。そこで,aタグで挟まれているテキストに関しては,本文のテキストとして抽出する以外に,リンク情報のプロパティとして抽出する機能を設けています。

検索時に,検索対象をリンク情報プロパティのみにして検索を行うことができ,目的の文書が意外とよく見つかります。

本文範囲の指定

gihyo.jpのようなCMS(コンテンツマネージメントシステム)では,本文以外に,タイトルやメニューバー,他の記事へのリンク,広告などが入ります。これらをすべて抽出して,全文検索を行うと,目次や関係のないページがヒットしてしまい,検索ノイズが紛れ込みがちです。

この問題に対処するために,本文範囲が指定されていれば,この範囲のみをHTML文書フィルタの出力とするような拡張機能を設けています。残念ながら本文範囲がどこかを明示するようなタグはHTMLでは規定されていないため,次のようなコメントで本文の箇所を示すことにしました。

<!-- CONTENTS:START -->
...本文...
<!-- CONTENTS:END -->

もちろん,この本文範囲を示すコメントは,一般的なルールではありません。CMSのシステム側に手を入れて,本文範囲を明示できれば,検索ノイズを大幅に減らすことができます。イントラネット等での全文検索システムではかなり有効な手段ではないかと考えています。

著者プロフィール

工藤智行(くどうともゆき)

有限会社サイパック取締役社長。システム構築・管理のコンサルティング,ローカライゼーション,文書処理や障害者向けソフトウェアを中心とするプログラミングを長年手がける。 近著『UNIXプログラミングの道具箱』『システム管理現場の鉄則FreeBSD編』等

URLhttp://www.cypac.co.jp/

著書