Y!J の日本語形態素解析 Web サービスを使ってみる

いやなんとなくやってみようかと思いまして。

PHP5 でやるとして、まずは curl_multi_exec をラップしたクラスを作成。こんな感じ。

PHP:
  1. <?php                                                                                                                                                             
  2.  
  3. class MultiHttpRequest {
  4.     private $_mh = null;
  5.  
  6.     private $_conn = array();
  7.  
  8.     private $_contents = array();
  9.  
  10.     public function __construct() {
  11.         $this->_mh = curl_multi_init();
  12.     }
  13.  
  14.     public function add_get($id, $url) {
  15.         if (empty($id)) {
  16.             error_log('MultiHttpRequest::addGet: invalid parameter: $id');
  17.             return false;
  18.         }
  19.         if (empty($url)) {
  20.             error_log('MultiHttpRequest::addGet: invalid parameter: $url');
  21.             return false;
  22.         }
  23.         if (isset($this->_mh[$id])) {
  24.             error_log('MultiHttpRequest::addGet: connection already exists: $id');
  25.             return false;
  26.         }
  27.         $h = curl_init($url);
  28.         if ($h === false) {
  29.             error_log("MultiHttpRequest::addGet: failed to call curl_init: $url");
  30.             return false;
  31.         }
  32.         $this->_conn[$id] = $h;
  33.         $options = array(CURLOPT_RETURNTRANSFER => true,
  34.                          CURLOPT_FOLLOWLOCATION => true,
  35.                          CURLOPT_FOLLOWLOCATION => 2,
  36.                          CURLOPT_CONNECTTIMEOUT => 10);
  37.         if ($post) {
  38.             $options[CURLOPT_POST] = true;
  39.         }
  40.         curl_setopt_array($this->_conn[$id], $options);
  41.         curl_multi_add_handle($this->_mh, $this->_conn[$id]);
  42.         return true;
  43.     }
  44.  
  45.     public function add_post($id, $url, $params) {
  46.         if (empty($id)) {
  47.             error_log('MultiHttpRequest::addPost: invalid parameter: $id');
  48.             return false;
  49.         }
  50.         if (empty($url)) {
  51.             error_log('MultiHttpRequest::addPost: invalid parameter: $url');
  52.             return false;
  53.         }
  54.         if (isset($this->_mh[$id])) {
  55.             error_log('MultiHttpRequest::addPost: connection already exists: $id');
  56.             return false;
  57.         }
  58.         $h = curl_init($url);
  59.         if ($h === false) {
  60.             error_log("MultiHttpRequest::addPost: failed to call curl_init: $url");
  61.             return false;
  62.         }
  63.         $this->_conn[$id] = $h;
  64.         $options = array(CURLOPT_RETURNTRANSFER => true,
  65.                          CURLOPT_FOLLOWLOCATION => true,
  66.                          CURLOPT_POST => true,
  67.                          CURLOPT_FOLLOWLOCATION => 2,
  68.                          CURLOPT_CONNECTTIMEOUT => 10,
  69.                          CURLOPT_POSTFIELDS => $params);
  70.         curl_setopt_array($this->_conn[$id], $options);
  71.         curl_multi_add_handle($this->_mh, $this->_conn[$id]);
  72.         return true;
  73.     }
  74.  
  75.     public function exec() {
  76.         if (empty($this->_conn)) {
  77.             error_log("MultiHttpRequest::exec: no target");
  78.             return false;
  79.         }
  80.         $mrc = CURLM_CALL_MULTI_PERFORM;
  81.         $active = false;
  82.         while ($mrc === CURLM_CALL_MULTI_PERFORM) {
  83.             $mrc = curl_multi_exec($this->_mh, $active);
  84.         }
  85.         while ($active && $mrc === CURLM_OK) {
  86.             if (curl_multi_select($this->_mh) != -1) {
  87.                 $mrc = CURLM_CALL_MULTI_PERFORM;
  88.                 while ($mrc === CURLM_CALL_MULTI_PERFORM) {
  89.                     $mrc = curl_multi_exec($this->_mh, $active);
  90.                 }
  91.             }
  92.         }
  93.         if ($mrc != CURLM_OK) {
  94.             error_log("MultiHttpRequest::exec: operation failed");
  95.             return false;
  96.         }
  97.         foreach ($this->_conn as $id => $conn) {
  98.             if (($err = curl_error($conn)) === '') {
  99.                 $this->_contents[$id] = curl_multi_getcontent($conn);
  100.             } else {
  101.                 error_log("MultiHttpRequest::exec: can't retrieve data: $id");
  102.             }
  103.             curl_multi_remove_handle($this->_mh, $conn);
  104.             curl_close($conn);
  105.         }
  106.         return true;
  107.     }
  108.  
  109.     public function get_content($id) {
  110.         if (empty($id)) {
  111.             error_log('MultiHttpRequest::get_content: invalid parameter: $id');
  112.             return false;
  113.         }
  114.         if (!isset($this->_contents[$id])) {
  115.             error_log("MultiHttpRequest::get_content: no content : $id");
  116.             return '';
  117.         } else {
  118.             return $this->_contents[$id];
  119.         }
  120.     }
  121. }
  122.  
  123. ?>

MultiHttpRequest.inc って名前で保存。

ほんで 日本語形態素解析Webサービスこの辺見ながら、アプリケーション ID とか適当にもらってやってみる。

PHP:
  1. <?php                                                                                                                                                             
  2.  
  3. require_once('MultiHttpRequest.inc');
  4.  
  5. $mhr = new MultiHttpRequest;
  6. $url = 'http://api.jlp.yahoo.co.jp/MAService/V1/parse';
  7. // 1 番目のリクエストを追加                                                                                                                                       
  8. $id1 = 'jlp1';
  9. $params1 = array('appid' => 'yourownappid',
  10.                  'sentence' => '安倍政権発足後、初の大型国政選挙となった第21回参院選は29日午前7時から、全国約5万1000カ所の投票所で一斉に投票が始まった。投票は一部地域を除いて午後8時に締め切られた後、順次開票される。30日未明には大勢が判明する見通しだ。',
  11.                  'results' => 'ma', // 形態素解析の結果のみ取得する
  12.                  'filter' => '9', // 名詞のみ取得する                                                                                                             
  13.                  );
  14. if (false === $mhr->add_post($id1, $url, http_build_query($params1))) {
  15.     exit("error");
  16. }
  17. // 2 番目のリクエストを追加                                                                                                                                       
  18. $id2 = 'jlp2';
  19. $params2 = array('appid' => 'yourownappid',
  20.                  'sentence' => '参院選には選挙区で218人、比例代表で159人の計377人が立候補し、121議席を争う。選挙戦では、年金や「政治とカネ」の問題などが争点となった。与党は過半数維持が目標だが、厳しい情勢だ。民主党は選挙区、比例代表とも善戦しており、参院第一党を目指している。',
  21.                  'results' => 'ma', // 形態素解析の結果のみ取得する
  22.                  'filter' => '9', // 名詞のみ取得する                                                                                                             
  23.                  );
  24. if (false === $mhr->add_post($id2, $url, http_build_query($params2))) {
  25.     exit("error");
  26. }
  27. // リクエストを実行                                                                                                                                               
  28. if (false === $mhr->exec()) {
  29.     exit("error");
  30. }
  31. // 1 番目の結果を取得                                                                                                                                             
  32. $content1 = $mhr->get_content($id1);
  33. if ($content1 === false) {
  34.     exit("error");
  35. }
  36. // 2 番目の結果を取得                                                                                                                                             
  37. $content2 = $mhr->get_content($id2);
  38. if ($content2 === false) {
  39.     exit("error");
  40. }
  41. // SimpleXML を使って 1 番目の結果から単語を取り出す                                                                                                               
  42. $elems1 = array();
  43. $xml1 = new SimpleXMLElement($content1);
  44. $word_list1 = $xml1->ma_result->word_list;
  45. foreach ($word_list1->word as $word) {
  46.     $elems1[] = (string)$word->surface;
  47. }
  48. // SimpleXML を使って 2 番目の結果から単語を取り出す                                                                                                               
  49. $elems2 = array();
  50. $xml2 = new SimpleXMLElement($content2);
  51. $word_list2 = $xml2->ma_result->word_list;
  52. foreach ($word_list2->word as $word) {
  53.     $elems2[] = (string)$word->surface;
  54. }
  55. // 結果をマージ                                                                                                                                                   
  56. $result = array_merge($elems1, $elems2);
  57. // 重複する要素を削除                                                                                                                                             
  58. $result = array_unique($result);
  59. print_r($result);
  60.  
  61. ?>

へー。http_build_querySimpleXML は便利ですね。


About this entry