人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

wikipedia apiを直接たたいてXMLを取得する
phpのsimplexml_load_fileを使ったサンプルコードを書いていただけると助かります。
URLは以下でキーワード(カテゴリ)は「海軍兵学校卒業生一覧_(日本)」です。

この質問は、
http://q.hatena.ne.jp/1329309002
と関連した質問です。

http://ja.wikipedia.org/w/api.php?action=query&prop=revisions&rvprop=content&format=xml&titles=%E6%B5%B7%E8%BB%8D%E5%85%B5%E5%AD%A6%E6%A0%A1%E5%8D%92%E6%A5%AD%E7%94%9F%E4%B8%80%E8%A6%A7_%28%E6%97%A5%E6%9C%AC%29

●質問者: kohhi
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● shell631
●150ポイント

以下のスクリプト(UTF-8で保存してください)をお試しください。
関数getWikiに見出し語$keywordを渡すと、XML文がそのまま返るようになっています。

途中、ZIP解凍のための一時処理ファイルを作るので、スクリプトのあるディレクトリを書き込み可能にしていただくか、定数ZIPFNAMEの値を書き込み可能なディレクトリ名を含むファイル名に変更してください。

<?php
define('ZIPFNAME', '_TMP_.ZIP'); //一時処理用ファイル名

//メインプログラム
$keyword = '海軍兵学校卒業生一覧_(日本)'; //検索したい見出し
$xml = getWiki($keyword);
echo $xml; //取得したXML

// Wikipedia APIからXML取得
function getWiki($keyword) {
 $host = 'ja.wikipedia.org';
 $query = urlencode($keyword);
 $path = '/w/api.php?action=query&prop=revisions&rvprop=content&format=xml&titles=' . $query;

 $request = "POST {$path} HTTP/1.1\r\n";
 $request .= "Host: {$host}\r\n";
 $request .= "User-Agent: Mozilla/5.0\r\n";
 $request .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
 $request .= "Accept-Language: ja,en-us;q=0.7,en;q=0.3\r\n";
 $request .= "Accept-Encoding: gzip, deflate\r\n";
 $request .= "Connection: keep-alive\r\n";
 $request .= "\r\n";
 $request .= "\r\n";

 $fp = fsockopen($host, 80);
 if (! $fp) return FALSE;
 fputs($fp, $request);
 //ヘッダ取得
 $len = 0;
 $flag_zip = FALSE;
 while (! feof($fp)) {
 $str = trim(fgets($fp));
 if ($str == '') {
 break;
 } else if (preg_match("/Content-Length: ([0-9]+)/iu", $str, $arr) > 0) {
 $len = $arr[1];
 } else if (preg_match("/Content-Encoding: gzip/iu", $str, $arr) > 0) {
 $flag_zip = TRUE;
 }
 };
 //コンテンツ取得
 $contents = '';
 while (! feof($fp)) $contents .= fread($fp, 1000);
 fclose($fp);

 $xml = '';
 if ($flag_zip) {
 file_put_contents(ZIPFNAME, $contents);
 $fp = gzopen(ZIPFNAME, 'r');
 if (! $fp) break;
 while (! gzeof($fp)) $xml .= gzread($fp, 1000);
 gzclose($fp);
 unlink(ZIPFNAME);
 } else {
 $xml = $contents;
 }

 return $xml;
}
?>

kohhiさんのコメント
早速お返事いただきありがとうございました。 動きました。

2 ● tobeoscontinue
●150ポイント ベストアンサー
<?php
require_once "Text/Wiki/Mediawiki.php";
function translate_mediawiki($text) {
 $wiki= new Text_Wiki_Mediawiki();
 $wiki->setFormatConf('Xhtml','translate',HTML_SPECIALCHARS);
 return $wiki->transform($text,'xhtml');
}

function simplexml_wikipedia($keyword) {
 $url="http://ja.wikipedia.org/w/api.php?action=query&prop=revisions&rvprop=content&format=xml&titles=".urlencode($keyword);
 ini_set("user_agent", "php/5.3.3");
 $xml = simplexml_load_file($url);
 $txt = translate_mediawiki(implode($xml->xpath('//rev')));
 return simplexml_load_string("<?xml version='1.0'?>\n<api>".$txt."</api>");
}
$xml = simplexml_wikipedia("海軍兵学校卒業生一覧_(日本)");
foreach ($xml->xpath('//h3 | //ul/li') as $li) {
echo is_array($li) ? implode($li) : $li."\n";
}
?>

phpのsimplexml_load_fileからja.wikipedia.orgにアクセスすると403で何故か叱られるので
ini_set("user_agent", "php/5.3.3");
でUser_Agentを設定している。環境によっては必要ないかも。
xmlのrevタグに記述されているがwiki記法のままなのでText_Wiki_Mediawikiでxhtmlに変換する。(xmlに出来ればいいのだが)
次にxhtmlをxmlと騙してsimplexml_load_stringで格納する。ただかなり無理がある。
必要な情報がどれか分からないがh3とul/liのものを抜き出してみる。
wikipedia apiを直接たたくのは無理があるように思う。

<?php
function simplexml_zubapita_t($keyword) {
 $url="http://ws.zubapita-t.com/index.php?&keywords=".urlencode($keyword)."&type=xml&size=full";
 return simplexml_load_file($url);
}
$xml = simplexml_zubapita_t("海軍兵学校卒業生一覧_(日本)");
//foreach ($xml->chapters->chapter->sub->chapter as $chapter) {
foreach ($xml->xpath('//sub/chapter') as $chapter) {
 echo $chapter->title."\n".
 $chapter->article."\n\n";
}
?>

サイトに依存することになるがhttp://www.zubapita.jp/2009/03/30/wikipedia_search_api/を使ったほうが簡単のように思う。
ライセンスはGPLだがソースも公開されている。


kohhiさんのコメント
ご回答ありがとうございました。 >wikipedia apiを直接たたくのは無理があるように思う 確かにそうですね。 ご紹介いただいたパーサー勉強してみます。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ