Source for file Spider.php
Documentation is available at Spider.php
* <p>指定URLを起点として最初に得られる有意コンテンツを取得する手段を提供する<br/>
* @copyright Copyright (c) 2006-2007, Nihon Unisys, Ltd.
* @license http://www.tyzoh.jp/rinza/licenses/LICENSE-1.0.txt Rinza Public License
* @example examples/sample.php
require_once 'HTTP/Request.php';
require_once 'Rinza/IE/Util.php';
require_once 'Rinza/IE/Scraper.php';
* <p>指定URLを起点として最初に得られる有意コンテンツを取得する手段を提供します。<br/>
* <li>Webサーバにおいて,別のURLにリダイレクトするようにしている</li>
* <li>対応するWebページにおいて,ユーザエージェントの受付言語に応じてURLを切り替えるようにしている</li>
* <li>対応するWebページにおいて,自動的に別のWebページに切り替えるようにしている</li>
* <li>対応するWebページにおいて,フレームで構成するようにしている</li>
* のような場合であっても,それを意識させることなく,意味のある内容を含むWebコンテンツを取得することができます。</p>
* $s = & new Rinza_IE_Spider($url);
* print_r($s->getSignificantContent());
* オブジェクト生成時に指定されたコンテンツ取得先URL
* オブジェクト生成後に最も新しく取得したコンテンツのURL
* オブジェクト生成後に最も新しくコンテンツを取得した際のHTTPレスポンスヘッダ
var $_response_header = array();
* オブジェクト生成後に最も新しくコンテンツを取得した際のクッキー
* オブジェクト生成時に指定された取得希望コンテンツの言語
var $_accept_lang = NULL;
* オブジェクト生成時に指定されたユーザエージェント
* オブジェクト生成時に指定されたキャッシュ指示子の追加可否
* オブジェクト生成後に有意コンテンツを取得するために得られたコンテンツの履歴
* 取得コンテンツ履歴配列(_history)のインデックス
var $_significant = array();
* フレームページURLがCGIである場合の親ページURL
var $_cgi_frame_url = NULL;
* <noscript>...<noscript>内指定リンク情報(href=)で指定されたURL(重複アクセス防止のための確認用)
var $_noscript_href = array();
* <noscript>...<noscript>内指定リンク情報(href=)で指定されたURL格納配列のインデックス
* <noscript>...<noscript>内指定リンク情報(href=)で指定されたコンテンツ処理実行可否フラグ
/** <body onLoad="function" >内指定関数をジャンプ先URL取得対象とするか否かの判定フラグ
* @param string $pURL コンテンツ取得先URL(既定値は空文字列)
* @param array $pArgs HTTP_Request用パラメタ(既定値は空配列・・・HTTP_Requestの既定値に従う)
* @param string $pAlang 取得希望コンテンツの言語(既定値は'ja')
* @param stirng $pUagent コンテンツリクエスト時のユーザエージェント(既定値はNULL・・・HTTP_Requestの既定値に従う)
* @param boolean $pIgnoreNoScript <noscript>...</noscript>内リンク情報を無視する(TRUE)か否(FALSE)か(既定値:FALSE)
* @param boolean $pCacheCtrl キャッシュ指示子("Pragma: no-cache"と"Cache-Control: no-cache")を追加する(TRUE)か否(FALSE)か(既定値:TRUE)
function __construct($pURL = '', $pArgs = array(), $pAlang = 'ja', $pUagent = NULL, $pIgnoreNoScript= FALSE, $pCacheCtrl = TRUE) {
$this->_origin_url = $pURL;
$this->_accept_lang = $pAlang;
$this->_user_agent = $pUagent;
$this->_cache_ctrl = $pCacheCtrl;
parent::HTTP_Request($pURL, $pArgs);
$this->_nh_flg = $pIgnoreNoScript;
* 現在のコンテンツ取得先URLを起点に有意なコンテンツを取得する
* <li>Webサーバによるリダイレクト先コンテンツ</li>
* <li>ユーザエージェント受付言語に則したJavaScriptによる切り替え先コンテンツ<br/>
* navigator.language.indexof(取得希望コンテンツの言語)<br/>
* <li>自動的に切り替えられる先のコンテンツ<br/>
* <meta http-equiv="refresh"></li>
* <li>フレームで構成される場合の各フレームソースのすべてのコンテンツ</li>
* @return array 以下のキーをもつ有意コンテンツ情報配列(有意コンテンツを得られなかった場合は空配列を返す)
* <li>url - 有意コンテンツ取得先URL</li>
* <li>response_header - 有意コンテンツ取得時のHTTPレスポンスヘッダ値の配列
* <li>content - 取得した有意コンテンツ文字列</li>
if (count($this->_significant) > 0) {
return $this->_significant;
$this->_allowRedirects = TRUE; // リダイレクトを受け付ける
$this->addHeader('Accept-Language', $this->_accept_lang); // 受け入れ言語を指定する
if (!is_null($this->_user_agent)) { // 指定ユーザエージェントを設定
$this->addHeader('User-Agent', $this->_user_agent);
if (!is_null($this->_cache_ctrl)) { // キャッシュ指示子の追加
$this->addHeader('Pragma', 'no-cache');
$this->addHeader('Cache-Control', 'no-cache');
if (!PEAR::isError($this->sendRequest())) { // コンテンツ取得リクエスト発行
$code = $this->getResponseCode();
if (399 < $code && $code < 600) { // レスポンスステータス判定
$this->_response_header = $this->getResponseHeader();
$this->_cookies = $this->getResponseCookies();
$body = $this->getResponseBody();
$this->_target_url = $this->_url->url; // _url : parent::_url
$this->_response_header = $this->getResponseHeader();
$body = $scraper->getNormarizedString();
$this->_h_idx = $this->_h_idx + 1;
$this->_history[$this->_h_idx]['url'] = $this->_target_url;
$this->_history[$this->_h_idx]['response_header'] = $this->_response_header;
$this->_history[$this->_h_idx]['content'] = $body;
if (($lang_pos = mb_strpos(strtolower($body), 'navigator.language.indexof(\'' . $this->_accept_lang . '\')', 0, $encoding)) !== FALSE) { // Java Script(Accept-Language)
$block_info = $scraper->getPartialBlock('location.href="', '"', $lang_pos);
$this->setURL($url); // parent::setURL()
} elseif (($refresh_pos = mb_strpos(strtolower($body), 'function refresh()', 0, $encoding)) !== FALSE) { // function refresh()
if (($location_pos = mb_strpos(strtolower($body), 'location.href', $refresh_pos, $encoding)) !== FALSE) {
$block_info = $scraper->getPartialBlock('"', '"', $location_pos);
$this->setURL($url); // parent::setURL()
} elseif ((($refresh_pos = mb_strpos(strtolower($body), 'http-equiv="refresh"', 0, $encoding)) !== FALSE) &&
(($ns_epos = mb_strpos(strtolower($body), '</noscript>', $refresh_pos, $encoding)) === FALSE ||
($ns_epos !== FALSE && ($ns_spos = mb_strpos(strtolower($body), '<noscript>', $refresh_pos, $encoding)) !== FALSE && $ns_spos < $ns_epos))) { // http-equiv="Refresh"
$block_info = $scraper->getPartialBlock('url=', '"', $refresh_pos);
$this->setURL($url); // parent::setURL()
} elseif ((($refresh_pos = mb_strpos(strtolower($body), 'http-equiv=\'refresh\'', 0, $encoding)) !== FALSE) &&
(($ns_epos = mb_strpos(strtolower($body), '</noscript>', $refresh_pos, $encoding)) === FALSE ||
($ns_epos !== FALSE && ($ns_spos = mb_strpos(strtolower($body), '<noscript>', $refresh_pos, $encoding)) !== FALSE && $ns_spos < $ns_epos))) { // http-equiv='Refresh'
$block_info = $scraper->getPartialBlock('URL=', '\'', $refresh_pos);
$this->setURL($url); // parent::setURL()
} elseif (($refresh_pos = mb_strpos(strtolower($body), 'http-equiv=refresh', 0, $encoding)) !== FALSE &&
(($ns_epos = mb_strpos(strtolower($body), '</noscript>', $refresh_pos, $encoding)) === FALSE ||
($ns_epos !== FALSE && ($ns_spos = mb_strpos(strtolower($body), '<noscript>', $refresh_pos, $encoding)) !== FALSE && $ns_spos < $ns_epos))) { // http-equiv=Refresh
$block_info = $scraper->getPartialBlock('URL=', '>', $refresh_pos);
$this->setURL($url); // parent::setURL()
} elseif (!$this->_bo_flg) {
// <body onLoad="location_function">
$body_tag = $scraper->getPartialBlock('<body ', '>', 0);
$scraper->setString($body_tag[0]);
$block_info = $scraper->getPartialBlock('"', '"', $onLoad_pos); // 関数名抽出
$block_info = $scraper->getPartialBlock('\'', '\'', $onLoad_pos); // 関数名抽出
if (($setTimeout_pos = mb_strpos(strtolower($body_tag[0]), 'settimeout(', 0, $encoding)) !== FALSE) {
$block_info = $scraper->getPartialBlock('\'', '\'', $setTimeout_pos);
$scraper->setString($body);
$block_info = $scraper->getPartialBlock('{', '}', $location_func_pos);
if (($location_pos = mb_strpos(strtolower($block_info[0]), 'location.href', 0, $encoding)) !== FALSE) {
$scraper->setString($block_info[0]);
$block_info = $scraper->getPartialBlock('"', '"', $location_pos);
$this->setURL($url); // parent::setURL()
$true_fcontnet = $scraper->getRemoveHTMLComments();
if (!$script_ctrl && ($frame_pos = mb_strpos(strtolower($true_fcontnet), '<frame ', 0, $encoding)) !== FALSE) { // フレーム使用ページ
$copy_target_url = $this->_target_url;
$scraper->setString($true_fcontnet);
$block_info = $scraper->getPartialBlock('<frame ', '>', $offset_pos);
$offset_pos = $block_info[1];
$scraper->setString($block_info[0]);
$block_info = $scraper->getPartialBlock('src="', '"', 0);
$this->_cgi_frame_url = $copy_target_url;
$this->setURL($url); // parent::setURL()
$this->_significant = array();
$scraper->setString($true_fcontnet);
$block_info = $scraper->getPartialBlock('<frame ', '>', $offset_pos);
$offset_pos = $block_info[1];
if (($frame_cnt = count($frame_body)) > 0) {
for ($i = 0; $i < $frame_cnt; $i++ ) {
for ($j = 0; $j < count($frame_body[$i]); $j++ ) {
$bodyArray[$body_idx] = $frame_body[$i][$j];
if (!$script_ctrl && !$frame_ctrl) {
if (is_null($this->_cgi_frame_url)) { // 「フレームページではない」or 「フレームURLがCGI呼び出し以外」の場合
$bodyArray[$body_idx] = array(
'url'=> $this->_target_url,
'response_header'=> $this->_response_header,
} else { // フレームURLがCGI呼び出しの場合
$bodyArray[$body_idx] = array(
'url'=> $this->_cgi_frame_url,
'response_header'=> $this->_response_header,
$this->_cgi_frame_url = NULL;
// <noscript><meta http-eqiuv="refresh" content="n;URL=xxxxx"></noscript> あるいは
// <noscript><xxx href="xxxxxx"></noscript>使用 コンテンツ処理(リンク先URLのコンテンツ追加取得)
$body_idx = count($bodyArray);
for ($i = 0; $i < $body_idx; $i++ ) {
$nsurl = $bodyArray[$i]['url'];
$this->_noscript_href[$this->_nh_idx] = $nsurl;
$nsresponse_header = $bodyArray[$i]['response_header'];
$nscontent = $bodyArray[$i]['content'];
$scraper->setString($nscontent);
$block_info = $scraper->getPartialBlock('<noscript>', '</noscript>', $offset_pos);
$offset_pos = $block_info[1];
$scraper->setString($block_info[0]);
$block_info = $scraper->getPartialBlock('http-equiv=', '>', 0);
$block_info = trim($scraper->getPartialBlock('URL="', NULL, 0),"',\"");
if ($this->_nh_idx < 0) {
$this->_noscript_href[$this->_nh_idx] = $url;
$this->setURL($url); // parent::setURL()
$this->_significant = array();
$ns_body[$ns_idx] = $tmp_body;
$this->_noscript_href[$this->_nh_idx] = $url;
$this->setURL($url); // parent::setURL()
$this->_significant = array();
$ns_body[$ns_idx] = $tmp_body;
$block_info = $scraper->getPartialBlock('href="', '"', 0);
if (strcmp($nsurl, $url) != 0) {
if ($this->_nh_idx < 0) {
$this->_noscript_href[$this->_nh_idx] = $url;
$this->setURL($url); // parent::setURL()
$this->_significant = array();
$ns_body[$ns_idx] = $tmp_body;
$this->_noscript_href[$this->_nh_idx] = $url;
$this->setURL($url); // parent::setURL()
$this->_significant = array();
$ns_body[$ns_idx] = $tmp_body;
$scraper->setString($nscontent);
$block_info = $scraper->getPartialBlock('<noscript>', '</noscript>', $offset_pos);
$offset_pos = $block_info[1];
if (($ns_cnt = count($ns_body)) > 0) {
for ($j = 0; $j < $ns_cnt; $j++ ) {
for ($k = 0; $k < count($ns_body[$j]); $k++ ) {
$bodyArray[$body_idx] = $ns_body[$j][$k];
// <iframe>使用コンテンツ処理(iframリンク先URLのコンテンツ追加取得)
$body_idx = count($bodyArray);
for ($i = 0; $i < $body_idx; $i++ ) {
$iurl = $bodyArray[$i]['url'];
$iresponse_header = $bodyArray[$i]['response_header'];
$icontent = $bodyArray[$i]['content'];
$scraper->setString($icontent);
$true_icontent = $scraper->getRemoveHTMLComments();
if (($iframe_pos = mb_strpos(strtolower($true_icontent), '<iframe ', 0, $encoding)) !== FALSE) {
$scraper->setString($true_icontent);
$block_info = $scraper->getPartialBlock('<iframe ', '>', $offset_pos);
$offset_pos = $block_info[1];
$scraper->setString($block_info[0]);
$block_info = $scraper->getPartialBlock('src="', '"', 0);
$this->setURL($url); // parent::setURL()
$this->_significant = array();
$iframe_body[$iframe_idx] = $tmp_body;
$scraper->setString($true_icontent);
$block_info = $scraper->getPartialBlock('<iframe ', '>', $offset_pos);
$offset_pos = $block_info[1];
if (($iframe_cnt = count($iframe_body)) > 0) {
for ($j = 0; $j < $iframe_cnt; $j++ ) {
for ($k = 0; $k < count($iframe_body[$j]); $k++ ) {
$bodyArray[$body_idx] = $iframe_body[$j][$k];
return $this->_significant = $bodyArray;
* @return string 最も新しく取得したコンテンツのURL
return $this->_target_url;
* @return array 以下のキーをもつ取得コンテンツ履歴配列
* <li>url - コンテンツ取得先URL</li>
* <li>response_header - コンテンツ取得時のHTTPレスポンスヘッダ値の配列</li>
* <li>content - 取得コンテンツ文字列</li>
* This Program is distributed under version 1.0 of the Rinza Public
* License Agreement, that is bundled with this package in the file
* LICENSE, and is available through the website at the following URL:
* http://www.tyzoh.jp/rinza/licenses/LICENSE-1.0.txt.
* This is the Original Program.
* The Initial Developer of the Original Program is Nihon Unisys, Ltd.
* The Original Program is copyrighted (C) 2006-2007 by Nihon Unisys, Ltd. with
* There is NO WARRANTY OF ANY KIND by the Initial Developer of the
|