PHP と MediaWiki API を使ってウィキペディアの情報に接続する

PHP を使用して MediaWiki API から Wikipedia のエントリーを検索、取得、変更する

究極のオンライン百科事典であるウィキペディアには、人間の知識のさまざまな側面に関する何百万ものエントリーがあります。これらのエントリーに対して、Web アプリケーション開発者は Wikipedia API を使用してアクセスし、検索することができます。この記事では Wikipedia API を取り上げ、この API を PHP アプリケーションのコンテキストで使用する例として、ウィキペディアのコンテンツに含まれる各種の要素を PHP を使って検索および取得する方法を説明します。

Vikram Vaswani, Founder, Melonfire

Photo of Vikram VaswaniVikram Vaswani は、オープンソースのツールと技術を専門とするコンサルティング・サービス会社、Melonfire の創業者で、現在 CEO を務めています。彼は、『Zend Framework: A Beginners Guide』および『PHP: A Beginners Guide』の著者でもあります。



2011年 6月 17日

はじめに

よく使われる頭文字語

  • API: Application Program Interface
  • CSRF: Cross-Site Request Forgery
  • HTML: HyperText Markup Language
  • HTTP: HyperText Transfer Protocol
  • IP: Internet Protocol
  • JSON: JavaScript Object Notation
  • OOP: Object-Oriented Programming
  • PEAR: PHP Extension and Application Repository
  • REST: REpresentational State Transfer
  • WDDX: Web Distributed Data eXchange
  • XHTML: Extensible Hypertext Markup Language
  • XML: Extensible Markup Language
  • YAML: YAML Ain't Markup Language

ほとんどの人々はウィキペディアについて耳にしたことがあるはずです。ウィキペディアは一般の人々によって提供される情報のリポジトリーであり、考えられる限りの項目をほぼすべて網羅し、誰もが Web ブラウザーで閲覧することができます。探している情報が何であれ、それはウィキペディアで見つかるはずです。しかも、その情報の詳細を余すところなく説明していることも珍しくありません。さらに、ウィキペディアの情報は誰もが編集できるように公開されているため、常に最新の関連情報が掲載されています。

一方、ほとんどの人々がウィキペディアについて知らないことが 1 つあります。それは、ウィキペディアの背後には、強力な Web サービス API があることです。開発者はこの API を使用して、ウィキペディアのコンテンツにアクセスしたり、検索したり、カスタム Web アプリケーションにコンテンツを統合したりすることができます。HTTP 上で動作し、XML をはじめとするさまざまなフォーマットでデータを返すことができるこの Wikipedia API は、プログラミングの世界で自由に利用することができます。この API のおかげで、ウィキペディアの巨大なコンテンツ・データベースに支えられた、あらゆる種類のカスタム Web アプリケーションを作成できるようになっています。

この記事では、Wikipedia API について簡単に紹介し、この API を私のお気に入りのプログラミング言語である、PHP に統合して使用する方法を説明します。Wikipedia API の基本的な動作を説明した後、カテゴリーの一覧を表示する方法、カテゴリーまたはキーワードでエントリーを検索する方法、エントリーを取得して表示する方法、そしてリモートからコンテンツを追加および編集する方法を具体的に手ほどきします。


API の概要

PHP コードの詳細を探る前に、Wikipedia API について少し説明しておきます。まず、この記事では「Wikipedia API」と呼んでいますが、これはウィキペディア専用の API ではないことに注意してください。この API は、実際には MediaWiki をベースとするアプリケーションの一部であり、ウィキペディアもこの MediaWiki をベースに実行されます。したがって、この記事で概説する手法と API メソッドは、MediaWiki をベースとする他のあらゆるウィキにも適用することができます。MediaWiki および完全な MediaWiki API リファレンス・マニュアルへのリンクは、どちらも「参考文献」に記載されています。

あらゆる HTTP ベースのサービスの例に漏れず、この API が機能する仕組みは、1 つ以上の引数が入力として含まれる HTTP リクエストを受け入れ、リクエスト側のクライアントが構文解析して使用できるようなレスポンスを返すというものです。大抵の場合、レスポンスのフォーマットは XML です。これは、最近のほとんどすべてのプログラミング言語は XML の構文解析に対応できることが理由ですが、他のフォーマット (JSON、WDDX、YAML、あるいはシリアライズした PHP など) のレスポンスをリクエストすることもできます。

API に対する各 HTTP リクエストには、action (アクション) パラメーターが必須パラメーターとして含まれていなければなりません。このパラメーターで指定する要求アクションは、クエリー、編集または削除操作、認証リクエスト、そしてそれ以外にサポートされているアクションのいずれか 1 つにすることができます。この必須パラメーターに加え、選択した操作によっては追加の引数を渡す必要があります。例えば、クエリーの場合には検索キーワード、編集または削除操作の場合にはページ・タイトル、認証の場合にはユーザー名とパスワードを渡します。

この API の動作を確かめるには、お好みの Web ブラウザーで以下の URL にアクセスしてください (注: この URL は実際には 1 つの文字列ですが、表示の関係上、2 行に分かれています)。

http://en.wikipedia.org/w/api.php?action=query&list=allcategories&acprop=size
          &acprefix=hollywood&format=xml

上記のメソッドは、接頭辞「hollywood」で始まるウィキペディアのカテゴリーのうち、最初の 10 個を一覧にして返します。リスト 1 に、このリクエストに対する XML レスポンスを、そのまま手を加えていない状態で示します。

リスト 1. API フィードの例
<?xml version="1.0"?>
<api>
  <query>
    <allcategories>
      <c size="31" pages="28" files="0" subcats="3" 
        xml:space="preserve">Hollywood</c>
      <c size="0" pages="0" files="0" subcats="0" 
        xml:space="preserve">Hollywood's Rock Walk inductees</c>
      <c size="0" pages="0" files="0" subcats="0" 
        xml:space="preserve">Hollywood, California</c>
      <c size="1" pages="1" files="0" subcats="0" 
        xml:space="preserve">Hollywood, Florida</c>
      <c size="0" pages="0" files="0" subcats="0" 
        xml:space="preserve">Hollywood, Los Angeles, California</c>
      <c size="0" pages="0" files="0" subcats="0" 
        xml:space="preserve">Hollywood.com/celebrity/Wanda Shelley</c>
      <c size="0" pages="0" files="0" subcats="0" 
        xml:space="preserve">Hollywood Actors</c>
      <c size="0" pages="0" files="0" subcats="0" 
        xml:space="preserve">Hollywood Actress</c>
      <c size="0" pages="0" files="0" subcats="0" 
        xml:space="preserve">Hollywood Blacklist</c>
      <c size="2" pages="2" files="0" subcats="0" 
        xml:space="preserve">Hollywood Boulevard</c>
    </allcategories>
  </query>
  <query-continue>
    <allcategories acfrom="Hollywood Cemetery (Richmond)" />
  </query-continue>
</api>

カテゴリーおよびページの一覧表示

API の動作を理解できたところで、次はコードを見てみましょう。この記事全体を通して前提とするのは、読者の皆さんが HTML と XML を使い慣れていること、そして最新バージョンの Zend Framework がインストールされた Apache/PHP 開発環境を実際に使用できることです。また、記事で使用する PHP コンポーネントは OOP の原則に従って作成されているので、PHPでクラスとオブジェクトを扱う方法について基本的な知識を持っていることも前提となります。

API を使用するには、GET および POST リクエストを送信してレスポンスを処理できる HTTP クライアントが必要になります。これに適しているのが Zend Framework の Zend_Rest_Client コンポーネントです。このツールは、PHP アプリケーションと REST ベースの Web サービスの統合に取り組む開発者のために設計されたもので、サービス・エンドポイントに対して GET、POST、PUT、および DELETE リクエストを実行するには、この Zend_Rest_Client を使用することができます。XML レスポンスは Zend_Rest_Client_Response オブジェクトのインスタンスとして返されるため、個々のレスポンス・プロパティーに容易にアクセスすることができます。

リスト 2 に、PHP スクリプトのコンテキストで Zend_Rest_Client を使用して、リスト 1 のカテゴリーを取得し、表示するプロセスを示します。

リスト 2. ウィキペディアのカテゴリーの一覧を表示する
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// define category prefix
$prefix = 'hollywood';

try {
  // initialize REST client
  $wikipedia = new Zend_Rest_Client('http://en.wikipedia.org/w/api.php');

  // set query parameters
  $wikipedia->action('query');
  $wikipedia->list('allcategories');
  $wikipedia->acprefix($prefix);
  $wikipedia->format('xml');

  // perform request
  // iterate over XML result set
  $result = $wikipedia->get();
} catch (Exception $e) {
    die('ERROR: ' . $e->getMessage());
}
?>
<html>
  <head></head>
  <body>
    <h2>Search results for categories starting with 
      '<?php echo $prefix; ?>'</h2>
    <ol>
    <?php foreach ($result->query->allcategories->c as $c): ?>
      <li><a href="http://www.wikipedia.org/wiki/Category:
        <?php echo $c; ?>"><?php echo $c; ?></a></li>
    <?php endforeach; ?>
    </ol>
  </body>
</html>

リスト 2 は、最初に Zend Framework のオートローダーを初期化した上で、Zend_Rest_Client コンポーネントをロードします。Wikipedia API サービス・エンドポイントをコンストラクターの引数として、Zend_Rest_Client オブジェクトのインスタンスが作成および初期化された後は、リクエスト・パラメーターが定義されて追加されます。このリクエストが、クライアント・オブジェクトの get() メソッドによって API に送信されます。サーバーからの XML レスポンスは、Zend_Rest_Client が受信すると自動的に一連の SimpleXML オブジェクトに変換されるため、レスポンスにアクセスするには標準のオブジェクト・プロパティー表記を使用することができます。

図 1 に、リスト 2 の出力の内容を示します。

図 1. ウィキペディアのカテゴリーの一覧を表示する Web ページ
「hollywood」で始まるウィキペディアのカテゴリーが一覧表示された Web ページのスクリーン・キャプチャー

Zend_Rest_Client を使用してリクエスト・パラメーターをサーバーに渡す方法に注目してください。各パラメーターを指定するためには、そのパラメーターと同じ名前を持つクライアント・メソッドを呼び出して、メソッドに値を最初の引数として渡します。例えば、action=query パラメーターをリクエストに追加するためにスクリプトが呼び出すのは、$client->action('query') です。詳細については、Zend_Rest_Client の資料 (「参考文献」にリンクを記載) を読んでください。

カテゴリーに含まれるページの一覧を取得することもできます。それには、クエリーがカテゴリーではなく、カテゴリーのメンバーの一覧を返すように変更します。この場合には当然、カテゴリーの名前を入力として API に渡さなければなりません。まさにこのタスクに対処するのが、リスト 3 です。

リスト 3. カテゴリーに含まれるページの一覧を表示する
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// define category
$cat = 'Greek_legendary_creatures';

try {
  // initialize REST client
  $wikipedia = new Zend_Rest_Client('http://en.wikipedia.org/w/api.php');

  // set query parameters
  $wikipedia->action('query');
  $wikipedia->list('categorymembers');
  $wikipedia->cmtitle('Category:'.$cat);
  $wikipedia->cmlimit('30');
  $wikipedia->format('xml');

  // perform request
  // iterate over XML result set
  $result = $wikipedia->get();
} catch (Exception $e) {
    die('ERROR: ' . $e->getMessage());
}
?>
<html>
  <head></head>
  <body>
    <h2>Search results for pages in category 
      '<?php echo $cat; ?>'</h2>
    <ol>
    <?php foreach ($result->query->categorymembers->cm as $c): ?>
      <li><a href="http://www.wikipedia.org/wiki/
        <?php echo $c['title']; ?>">
        <?php echo $c['title']; ?></a></li>
    <?php endforeach; ?>
    </ol>
  </body>
</html>

リスト 3 はカテゴリーの名前を指定して、その名前を cmtitle パラメーターを使って API に渡します。cmlimit パラメーターにも注目してください。これは、返される結果の数を指定するパラメーターです。前の例と同じく、Zend_Rest_Client はリクエストを送信して XML レスポンスを SimpleXML オブジェクトに変換するので、クエリーの実行結果を簡単に構文解析して表示することができます。

図 2 に、リスト 3 の出力を示します。

図 2. 選択されたカテゴリーに含まれるウィキペディアのページを一覧表示する Web ページ
選択された「Greek_legendary_creatures」カテゴリーに含まれるウィキペディアのページを一覧表示する Web ページのスクリーン・キャプチャー

全文検索の実行

次は、特定のキーワードと一致するページを検索する場合について検討してみましょう。このタスクは、前のセクションで使用したクエリーと同じクエリーによって簡単に実現することができます。ただし、この場合にはカテゴリーのメンバーではなく、検索結果の一覧を表示する必要があります。リスト 4 に、このプロセスを示します。

リスト 4. 全文検索の結果を一覧表示する
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// define search query
$query = 'michelangelo';

try {
  // initialize REST client
  $wikipedia = new Zend_Rest_Client('http://en.wikipedia.org/w/api.php');

  // set query parameters
  $wikipedia->action('query');
  $wikipedia->list('search');
  $wikipedia->srwhat('text');
  $wikipedia->format('xml');
  $wikipedia->srsearch($query);

  // perform request
  // iterate over XML result set
  $result = $wikipedia->get();
} catch (Exception $e) {
    die('ERROR: ' . $e->getMessage());
}
?>
<html>
  <head></head>
  <body>
    <h2>Search results for '<?php echo $query; ?>'</h2>
    <ol>
    <?php foreach ($result->query->search->p as $r): ?>
      <li><a href="http://www.wikipedia.org/wiki/
        <?php echo $r['title']; ?>">
        <?php echo $r['title']; ?></a> <br/>
      <small><?php echo $r['snippet']; ?></small></li>
    <?php endforeach; ?>
    </ol>
  </body>
</html>

リスト 4 では、前と同じく query をアクションとして指定していますが、パラメーターが多少異なります。まず list パラメーターによって、これが全文検索操作であることを指定しており、srsearch パラメーターでは検索キーワード (この例では「michelangelo」) を指定しています。また、srwhat パラメーターを指定しているのも重要な点です。この srwhat パラメーターによって、検索をページ・タイトルで実行するか、ページ・テキストで実行するかを指定します。

検索結果のエントリーごとに、ページ・タイトル、サイズ、ワード・カウント、名前空間 (これについては後で詳しく説明します)、およびページのコンテンツのスニペットが含まれます。これで、このデータを HTML による Web ページとしてフォーマット設定して表示することができます (図 3 を参照)。

図 3. ウィキペディアの検索結果の一覧を表示する Web ページ
ウィキペディアで「michelangelo」を検索した結果が一覧表示された Web ページのスクリーン・キャプチャー

サンプル・アプリケーション: ウィキペディア検索

実際には、検索キーワードがスクリプトにハードコーディングされることはありません。キーワードはユーザーによって入力されるものです。そこで、リスト 5 ではリスト 4 をよりインタラクティブにするために、ユーザーがアプリケーションに検索語を入力すると、検索語と一致するウィキペディアのページが表示されるように改善しています。

リスト 5. インタラクティブなウィキペディア検索ツール
<html>
  <head></head>
  <body>
    <h2>Search</h2>
    <form method="post">
      Search: <input type="text" name="q" />
    </form>

    <?php
    // if form submitted
    if (isset($_POST['q'])) {
      // load Zend classes
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Rest_Client');

      try {
        // initialize REST client
        $wikipedia = new Zend_Rest_Client('http://en.wikipedia.org/w/api.php');

        // set query parameters
        $wikipedia->action('query');
        $wikipedia->list('search');
        $wikipedia->srwhat('text');
        $wikipedia->format('xml');
        $wikipedia->srsearch($_POST['q']);

        // perform request
        // iterate over XML result set
        $result = $wikipedia->get();
      } catch (Exception $e) {
          die('ERROR: ' . $e->getMessage());
      }
    ?>
    <h2>Search results for '<?php echo $_POST['q']; ?>'</h2>
    <ol>
    <?php foreach ($result->query->search->p as $r): ?>
      <li><a href="http://www.wikipedia.org/wiki/
      <?php echo $r['title']; ?>">
      <?php echo $r['title']; ?></a> <br/>
      <small><?php echo $r['snippet']; ?></small></li>
    <?php endforeach; ?>
    </ol>
    <?php 
    }
    ?>

  </body>
</html>

リスト 5 には何も複雑なところはありません。ここでは単に、ユーザーの入力の有無を追加でチェックして、入力されている場合には、その入力を srsearch パラメーターに渡しているだけです。図 4 に、初期状態の Web フォームと検索結果を示します。

図 4. ウィキペディア検索用 Web フォームと検索結果
ウィキペディア検索用 Web フォームと「fruit fly」の検索結果を示すスクリーン・キャプチャー

ページのコンテンツの取得

MediaWiki API を使用すれば、現在のバージョンまたは前のバージョンのページのコンテンツにアクセスすることもできます。それには、クエリー・アクションに prop=revisions パラメーターを追加します。この場合に指定する必要があるのは、クエリーに返させるページのタイトルです。この方法をリスト 6 に示します。

リスト 6. ページのコンテンツを取得する
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// define page title
$query = 'The A Team';

try {
  // initialize REST client
  $wikipedia = new Zend_Rest_Client('http://en.wikipedia.org/w/api.php');

  // set query parameters
  $wikipedia->action('query');
  $wikipedia->prop('revisions');
  $wikipedia->rvprop('content');
  $wikipedia->format('xml');
  $wikipedia->redirects('1');
  $wikipedia->titles($query);

  // perform request
  // get page content as XML
  $result = $wikipedia->get();
  $content = $result->query->pages->page->revisions->rev;
} catch (Exception $e) {
    die('ERROR: ' . $e->getMessage());
}
?>
<html>
  <head>
  </head>
  <body>
    <h2>Page result for '<?php echo $query; ?>'</h2>
    <div>
      <?php echo $content; ?>
      </script>
    </div>
  </body>
</html>

リスト 6 のクエリーは、今まで見てきたクエリーとは少し異なり、list (一覧) の代わりに prop (プロパティー) を使用しています。プロパティーは、一連のページに対してどの情報を取得するかを指定するために使用します。使用できるプロパティーは、ページのメタデータ、リビジョン、リンク、画像、テンプレート、カテゴリーなど多数あります。

リスト 6 のクエリーは、プロパティーに revisions を指定し、さらに rvprop パラメーターを使用してリビジョンごとに取得するプロパティーを指定します (この例の場合は、取得するプロパティーとしてリビジョンのコンテンツだけを指定しています)。以前の複数のリビジョンを取得するための rvlimit というパラメーターもありますが、ここでは最後の (つまり、現在の) リビジョンだけを関心の対象としているので、上記のクエリーではこのパラメーターを指定していません。

図 5 に、リスト 6 の出力を示します。

図 5. Wikitext のコンテンツを表示する Web ページ
Wikitext のコンテンツが、フォーマット設定されていない、ひと続きのテキスト・ストリングとして表示された Web ページのスクリーン・キャプチャー (トピック: The A-Team)

図 5 を見るとわかるように、リスト 6 の出力は、指定されたページのウィキ・マークアップ (Wikitext) フォーマットのコンテンツです。このデータを Web アプリケーションで使用するには、ウィキ・マークアップから XHTML マークアップに変換しなければなりません。このタスクに対処する既製のコンバーターは数多くありますが、なかでも特に優れているのは、PEAR の Text_Wiki パッケージです。このパッケージは、Wikitext と多種多様なフォーマットとの間の変換をすることができます。

Text_Wiki パッケージをインストールするには、シェル・プロンプトで以下のコマンドを実行するだけです。

shell> pear install Text_Wiki
shell> pear install Text_Wiki_Mediawiki

上記のコマンドを実行すると、PEAR インストーラーが PEAR パッケージ・サーバーに接続し、該当するパッケージをダウンロードして、システムの適切な場所にインストールしてくれます。手動でパッケージをインストールしたいという場合には、「参考文献」に記載されているダウンロード・リンクにアクセスしてください。

パッケージのインストールが完了したら、Text_Wiki コンバーターを使用するようにリスト 6 を修正してください。修正後のコードは、リスト 7 のようになります。

リスト 7. ページのコンテンツを取得して XHTML に変換する
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// load wikitext converter
require_once 'Text/Wiki.php';

// instantiate a Text_Wiki object from the given class
// and set it to use the Mediawiki adapter
$wiki = & Text_Wiki::factory('Mediawiki');

// set some rendering rules  
$wiki->setRenderConf('xhtml', 'wikilink', 'view_url', 
  'http://en.wikipedia.org/wiki/');
$wiki->setRenderConf('xhtml', 'wikilink', 'pages', false);
  
// define page title
$query = 'The A Team';

try {
  // initialize REST client
  $wikipedia = new Zend_Rest_Client('http://en.wikipedia.org/w/api.php');

  // set query parameters
  $wikipedia->action('query');
  $wikipedia->prop('revisions');
  $wikipedia->rvprop('content');
  $wikipedia->format('xml');
  $wikipedia->redirects('1');
  $wikipedia->titles($query);

  // perform request
  // get page content as XML
  $result = $wikipedia->get();
  $content = $result->query->pages->page->revisions->rev;
} catch (Exception $e) {
    die('ERROR: ' . $e->getMessage());
}
?>
<html>
  <head>
  </head>
  <body>
    <h2>Page result for '<?php echo $query; ?>'</h2>
    <div>
      <?php echo $wiki->transform($content, 'Xhtml'); ?>
      </script>
    </div>
  </body>
</html>

リスト 7 は、Text_Wiki オブジェクトを初期化して、このオブジェクトが Mediawiki アダプターを使用するように設定します。続いて、内部ウィキ・リンクに使用するデフォルトの URL 接頭辞をはじめ、XHTML 変換に使用するいくつかのパラメーターも指定します。次に、API を使用して指定のページのコンテンツを取得し、それを Text_Wiki オブジェクトの transform() メソッドに渡すことによって、コンテンツを XHTML に変換します。図 6 に更新後のコードによる出力を示します。

図 6. XHTML に変換された後のウィキ・コンテンツを表示する Web ページ
XHTML に変換された後のフォーマット設定されたウィキ・コンテンツが表示された Web ページのスクリーン・キャプチャー (トピック: The A-Team)

図 6 で明らかなように、Text_Wiki パッケージは Wikitext から標準 XHTML への変換をかなり上手に行いますが、完璧なわけではなく、Wikitext マークアップのすべての側面が考慮されているわけではありません (例えば、Infobox を処理することは一切できません)。このパッケージを使っても必要なことをすべて行えるわけではないと判断した場合には、代わりに Steve Blinch の Wikitext パーサー (「参考文献」を参照) を使用することを検討してください。このパーサーは Wikitext の構文解析および変換の代替手段となります。


URL 参照検索の実行

Wikipedia のクエリー API が持つ興味深い側面は、この API では、特定の URL を参照するページを検索できることです。この機能は、例えば自分の Web サイトがウィキペディアのエントリー内でどれくらい頻繁に参照されているのかを調べたいといった場合に非常に重宝します。

このようなクエリーを実行するには、クエリーを調整することで、クエリーが外部 URL の一覧を使用し、チェックの対象とする特定の URL を渡すようにしなければなりません。リスト 8 に、これを実現する方法を示します。

リスト 8. 特定の URL を参照するページの一覧を表示する
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// define category prefix
$url = 'httpd.apache.org';

try {
  // initialize REST client
  $wikipedia = new Zend_Rest_Client('http://en.wikipedia.org/w/api.php');

  // set query parameters
  $wikipedia->action('query');
  $wikipedia->list('exturlusage');
  $wikipedia->euquery($url);
  $wikipedia->eulimit('30');
  $wikipedia->eunamespace('0');
  $wikipedia->format('xml');

  // perform request
  // iterate over XML result set
  $result = $wikipedia->get();
} catch (Exception $e) {
    die('ERROR: ' . $e->getMessage());
}
?>
<html>
  <head></head>
  <body>
    <h2>Search results for pages referencing URL 
      '<?php echo $url; ?>'</h2>
    <ol>
    <?php foreach ($result->query->exturlusage->eu as $r): ?>
      <li><a href="http://www.wikipedia.org/wiki/
      <?php echo $r['title']; ?>"><?php echo $r['title']; ?>
      </a></li>
    <?php endforeach; ?>
    </ol>
  </body>
</html>

標準の action および list パラメーターの他に、リスト 8 ではチェック対象の URL (この例では、Apache Web サイト) を指定する euquery パラメーター、検索先のウィキの名前空間を指定する eunamespace パラメーターも追加しています。ここで注意する点として、URL は「http://」プロトコル接頭辞を付けずに指定しなければなりません。クエリーの実行結果は、通常の方法で構文解析および処理されて、図 7 のような出力が生成されることになります。

図 7. 特定の URL を参照するページの一覧を表示する Web ページ
特定の URL (httpd.apache.org) を参照するページの一覧が表示された Web ページのスクリーン・キャプチャー

リスト 8 の名前空間については、簡単に説明しておく価値があります。MediaWiki API は、ウィキに含まれる各種のコンテンツにそれぞれ異なる名前空間を定義しています。各名前空間は、ページ・タイトルに追加された接頭辞によって識別されます。例えば、ユーザー・ページには常に「User:」という名前空間接頭辞が付き、カテゴリー・ページには「Category:」という名前空間接頭辞が付くといった具合です。

それぞれの名前空間には整数値も関連付けられています。この整数値は、検索クエリーをフィルタリングするために使用することができます。名前空間の整数値および接頭辞を網羅した一覧は MediaWiki の資料 (「参考文献」にリンクを記載) で調べることができますが、以下に、最もよく使用される名前空間の整数を抜粋して一覧にします。

  • 0: コンテンツ・ページのデフォルト名前空間
  • 1: トーク・ページの名前空間
  • 2: ユーザー・ページの名前空間
  • 6: ファイルの名前空間
  • 14: カテゴリー・ページの名前空間

上記の一覧から、リスト 8 では eunamespace パラメーターによってクエリーをコンテンツ・ページのみに制限していることが明らかにわかります。この制限を取り除くと、指定された URL が含まれるユーザー・ページとトーク・ページを含む大量の結果が返されることになります。


ページの追加および編集

この記事で今まで記載したリストはすべて、API のクエリー・アクションに焦点を当て、API を使用してコンテンツ・リポジトリーからさまざまなタイプのデータを取得する方法を説明するためのものでした。その一方、この API はクエリー以外にも多数のアクションをサポートします。例えば、新しいページの作成や、既存のページの編集などです。これらのタスクを実行するには、API の編集アクションを呼び出して、編集または作成するページのタイトルと、ページまたはセクションのコンテンツを渡します。

すべての編集操作には、トークンを伴っていなければなりません。トークンにより、ユーザー・リクエストの妥当性が保証され、CSRF 攻撃から保護されるからです。トークンは通常、英数字ストリングからなり、特殊な +\ のシーケンスで終わります。匿名ユーザーの場合、トークンには +\ シーケンスしか含まれません。

トークンには、編集リクエストが関連付けられている必要があります (リスト 9 を参照)。

リスト 9. ページを編集する
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

try {
  // initialize REST client
  $wikipedia = new Zend_Rest_Client('http://en.wikipedia.org/w/api.php');

  // set query parameters
  $wikipedia->action('edit');
  $wikipedia->title('Wikipedia:Sandbox');
  $wikipedia->section('new');
  $wikipedia->summary('My Section');
  $wikipedia->text('Some text');
  $wikipedia->token('+\\');
  
  // POST page data 
  $wikipedia->post();
} catch (Exception $e) {
}
?>

リスト 9 では、以下のリクエスト引数が新しく使用されています。

  • title 引数は、編集するページを指定します。上記の例で、編集対象となっているのは、特殊なウィキペディア・サンドボックス・ページです。これは実験およびテスト専用のページで、定期的に自動消去されます。
  • section 引数は、編集するセクションの番号を指定します。「new」という特殊なキーワードを使用すると、新しいセクションが追加されます。この引数を省略した場合には、ページ全体が置換されることになります。
  • summary 引数は、セクションのタイトルを指定します (新規セクションを作成する場合)。
  • text 引数には、セクションまたはページのコンテンツが含まれます。
  • token 引数は、編集操作のトークンを指定します。

もう 1 つ注意する点として、これまで記載したリストとは異なり、編集リクエストは GET ではなく、POST を使って送信する必要があります。リスト 9 で、リクエストを送信するために Zend_Rest_Client の post() メソッドを使用しているのは、そのためです。Wikipedia API は POST リクエストに対しては XML レスポンスを返さないため、Zend_Rest_Client がレスポンスを読み取ると、SimpleXML 例外を発生させます。そのため、リスト 9 では例外を捕捉するようにコーディングされているにも関わらず、実際には例外に対して何の処理も行ないません。この方法の代わりに、Zend_Http_Client を使用して、手動で POST パケットを作成するという方法を使うことも可能です。

リクエストが完了すると、ターゲット・ページが変更されていることがわかるはずです。そして、ページの改訂履歴には、システムの IP アドレス (匿名ユーザーの場合) またはユーザー名 (認証済みユーザーの場合) が表示されます。改訂履歴のエントリーには、日時スタンプ、IP アドレスまたはユーザー名、編集インジケーターの種類、そしてサイズ (バイト単位) も示されます。図 8 に、その一例を示します。

図 8. API を介して行われた編集内容を示すウィキペディア・ページの改訂履歴
API を介して行われた編集内容を示すウィキペディア・ページの改訂履歴のスクリーン・ショット

まとめ

この記事の最後のほうのセクションでは、MediaWiki API を使用してウィキペディアの情報を取得し、PHP による Web アプリケーションに統合する方法を速習しました。また、eunamespace (名前空間)、prop (プロパティー)、list (一覧) といった、この API ならではの特異な側面について簡単に説明するとともに、この API はウィキからデータを読み取るためだけでなく、データをウィキに書き込むためにも使用できることも実演しました。

この記事で説明した内容は、あくまでも氷山の一角でしかありません。最後に取り上げた極めて強力なクエリー・モジュールでアクセスできるウィキ・コンテンツは、画像やファイル、ユーザー・データやページの改訂データなどを始めとし、他にも多数あります。最も多用することになるのは、このクエリー・モジュールであることに間違いはありませんが、他にも存在するモジュールを使用することによって、ユーザーのクリック回数、編集回数、ユーザー登録数などの統計の計算、記事のフィードバックの送信、ユーザー・プロフィール情報の取得、ページ編集のロールバック、ファイルのアップロード、ユーザー・ウォッチリストの操作など、さまざまな操作を行うことができます。

記事に記載した例から明らかなように、MediaWiki API は、ウィキペディアや他の MediaWiki ベースのウィキなどのコンテンツを中心として独創的な新しいアプリケーションの構築を目指す開発者にとって柔軟なツールとなります。ぜひ、実際に使って確かめてみてください。

参考文献

学ぶために

製品や技術を入手するために

  • MediaWiki: PHP で作成されたオープンソースのウィキ・パッケージをダウンロードしてください。
  • Zend Framework: Zend Framework をダウンロードして、よりセキュアで信頼性に優れ、幅広く利用可能な API を備えた最新の Web 2.0 アプリケーションおよび Web サービスを構築してください。
  • PEAR Text_Wiki コンポーネント: Text_Wiki サブクラスに共通のベース・エンジンをダウンロードしてください。
  • PEAR Text_Wiki_MediaWiki コンポーネント: Text_Wiki 用の Mediawiki パーサーをダウンロードしてください。
  • Steve Blinch の Wikitext パーサー: MediaWiki ウィキからページを取得して構文解析する単純なクラスをダウンロードして試してみてください。このクラスは、ほとんどのテキスト・フォーマット設定およびイメージ処理マークアップを処理します。
  • IBM 製品の評価版: DB2、Lotus、Rational、Tivoli、および WebSphere のアプリケーション開発ツールとミドルウェア製品を体験するには、評価版をダウンロードするか、IBM SOA Sandbox のオンライン試用版を試してみてください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML, Open source, Web development
ArticleID=679234
ArticleTitle=PHP と MediaWiki API を使ってウィキペディアの情報に接続する
publish-date=06172011