rss-phpでも、301リダイレクトのフィードからRSSを取得できるか?

composerでrss-phpを入れます。

[vagrant@localhost app]$ curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...

Composer (version 1.6.5) successfully installed to: /home/vagrant/app/composer.phar
Use it: php composer.phar

[vagrant@localhost app]$ php composer.phar require dg/rss-php
Using version ^1.2 for dg/rss-php
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing dg/rss-php (v1.2): Loading from cache
Writing lock file
Generating autoload files
[vagrant@localhost app]$ ls
composer.json  composer.lock  composer.phar  index.php  vendor

rss-phpでfetchします。

require_once 'vendor/dg/rss-php/src/Feed.php';
$rss = Feed::loadRss('http://hpscript.com/rss/rss.xml');

foreach($rss->item as $item){
	echo $item->title ."<br>";
}

301リダイレクトを設定しているURLをfetchします。

require_once 'vendor/dg/rss-php/src/Feed.php';
$rss = Feed::loadRss('http://phone-search.online/test/index.php');

foreach($rss->item as $item){
	echo $item->title ."<br>";
}

OK つまり、301リダイレクトで、フィードのURLが変わっても、旧URLに301リダイレクトをかけている間は、新URLのフィードを取得できる。

rssフィードのurlが移転したときに、301リダイレクトで取得

xmlファイルをつくります。

<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
<channel>
<title>HPScript</title>
<link>http://hpscript.com/rss/test.xml</link>
<description>hpscriptのRSSです</description>
<language>ja-JP</language>
<item>
<guid isPermaLink="false"></guid>
<link>
SCSK
</link> <title>scsk</title> <description/> </item> <item> <guid isPermaLink="false"></guid> <link>
JBS
</link> <title>jbs</title> <description/> </item> </channel> </rss>

vagrantでphpファイルをつくって取得する。

$rss = simplexml_load_file('http://hpscript.com/rss/rss.xml');

foreach($rss->channel->item as $item){
	echo $item->title ."<br>";
}

モチ、ここまではOK

hpscript.com/rss/のディレクトリに.htaccessで301リダイレクトを書きます。

RewriteEngine on
RewriteRule ^index.php$ http://hpscript.com/rss/rss.xml [R=301,L]

http://hpscript.com/rss/index.php をたたくと、http://hpscript.com/rss/rss.xmlに301リダイレクトします。

では、vagrant側で、index.phpをfetchした場合。

$rss = simplexml_load_file('http://hpscript.com/rss/index.php');

foreach($rss->channel->item as $item){
	echo $item->title ."<br>";
}

取れてます!

では、下層ディレクトリから301リダイレクトをした場合。corpというディレクトリをつくり、301リダイレクトの設定をします。
下層ディレクトリでも全く同じで、301リダイレクトをすれば、取得できました。

RewriteEngine on
RewriteRule ^old.php$ http://hpscript.com/rss/rss.xml [R=301,L]

では、異なるドメインから301リダイレクトをした場合を考えたい。
http://phone-search.online/ というurl(電話のサービスづくりで取得したドメイン)にtestというディレクトリをつくり、同じように、301ディダイレクト設定を行う。

RewriteEngine on
RewriteRule ^old.php$ http://hpscript.com/rss/rss.xml [R=301,L]

phone-search.online/test/index.phpからfetchすると、

$rss = simplexml_load_file('http://phone-search.online/test/index.php');

foreach($rss->channel->item as $item){
	echo $item->title ."<br>";
}

ドメインが変わっても、301リダイレクトで取れている。
つまり、RSSのドメインが変わっても、旧URLに301リダイレクトが設定できれば、新しいURLのRSS取得はできる。

simplexml_load_file以外でもいけるか試したい。

simplexml_load_stringの使い方 2

<h3>xml</h3>
<?php

$axmlData = array();
$axmlData&#91;0&#93; = array 
		(
			"name"=> "楽天日本株4.3倍ブル",
			"rate" => "123.54",
			"asset" => "27625"
		);
$axmlData[1] = array
		(
			"name" => "小型株ファンド",
			"rate" => "107.11",
			"asset" => "24381"
		);
$sStringXML = '<?xml version="1.0" encoding="UTF-8"?>'."\n";
echo $axmlData[0][rate];
$sStringXML .= "<list>"."\n";
foreach($axmlData as $value){
	$sStringXML .= "<item>";
	$sStringXML.= "<return>".$value['rate']."</return>";
	$sStringXML .= "<toshin>".$value['name']."</toshin>";

	$sStringXML .= "<shisan>".$value['asset']."</shisan>";
	$sStringXML .= "</item>"."\n";
}
$sStringXML .= "</list>"."\n";
echo '[PHP ruler="true" toolbar="true"]'.htmlentities($sStringXML, ENT_QUOTES, 'UTF-8').'<\/pre>';
echo "<br>";
$xml = simplexml_load_string($sStringXML);

foreach($xml->item as $value){
	$name = $value->toshin;
	$return = $value->return;
	$asset = $value->shisan;

	echo 'name:'.$name.'<br/>';
	echo 'return:'.$return.'<br/>';
	echo 'asset:'.$asset.'<br>';
}
?>

name:楽天日本株4.3倍ブル
return:123.54
asset:27625
name:小型株ファンド
return:107.11
asset:24381

つまり、下記のxml:return, toshin, shisanを切り取ってくれるということですね。

<?xml version="1.0" encoding="UTF-8"?> <list> <item><return>123.54</return><toshin>楽天日本株4.3倍ブル</toshin><shisan>27625</shisan></item> <item><return>107.11</return><toshin>小型株ファンド</toshin><shisan>24381</shisan></item> </list>

Extracting xml Data

import xml.etree.ElementTree as ET

article_file = "exampleResearchArticle.xml"

def get_root(fname)
	tree = ET.parse(fname)
	return tree.getroot()

def get_authors(root):
	authors = []
	for author in root.findall('./fm/bibl/aug/au'):
		data = {
			"fnm": None,
			"snm": None,
			"email": None
		}
		data["fnm"] = author.find('./fnm').text
		data["snm"] = author.find('./snm').text
		data["email"] = author.find('./email').text

		authors.append(data)

	return authors

def test():
	solution = [{'fnm': 'Omer', 'snm': 'Mei-Dan', 'email': 'omer@extremegate.com'}, {'fnm': 'Mike', 'snm': 'Carmont', 'email': 'mcarmont@hotmail.com'}, {'fnm': 'Lior', 'snm': 'Laver', 'email': 'laver17@gmail.com'}, {'fnm': 'Meir', 'snm': 'Nyska', 'email': 'nyska@internet-zahav.net'}, {'fnm': 'Hagay', 'snm': 'Kammar', 'email': 'kammarh@gmail.com'}, {'fnm': 'Gideon', 'snm': 'Mann', 'email': 'gideon.mann.md@gmail.com'}, {'fnm': 'Barnaby', 'snm': 'Clarck', 'email': 'barns.nz@gmail.com'}, {'fnm': 'Eugene', 'snm': 'Kots', 'email': 'eukots@gmail.com'}]

	root = get_root(article_file)
	data = get_authors(root)

	assert data[0] == solution[0]
	assert data[1]["fnm"] == solution[1]["fnm"]

simplexml_load_file

simplexml_load_file:Interprets an XML file into an object

<?php

$rssList = array(
  "http://news.finance.yahoo.co.jp/rss/cp/fisf.xml",
  "http://news.finance.yahoo.co.jp/rss/cp/toyo.xml",
  "http://news.finance.yahoo.co.jp/rss/cp/mosf.xml",
  "http://news.finance.yahoo.co.jp/rss/cp/shikiho.xml"
);

for($n=0;$n<3;$n++){
    //URL設定
    $rssdata = simplexml_load_file("$rssList&#91;$n&#93;");

    // 件数設定
    $num_of_data = 3;

    //初期化
    $outdata = "";
    for ($i=0; $i<$num_of_data; $i++){

        $myEntry = $rssdata->channel->item[$i];
        $rssDate = $myEntry->pubDate;
        date_default_timezone_set('Asia/Tokyo');
        $myDateGNU = strtotime($rssDate);
        $myDate = date('Y/m/d',$myDateGNU);
        $myTitle = $myEntry->title; //タイトル取得
        $myLink = $myEntry->link; //リンクURL取得

        //出力内容(CSSOK)
        $outdata .=  '<p class=""><div style="float:left;width:80px;margin:0px 0px 0px 5px;font-size:12px">'.$myDate.'</div><a href="' . $myLink . '">' . $myTitle . '</a></p>';
    }
    echo $outdata; //全部出力する
}
?>

rssの種類
タグ RSS1.0 RSS2.0 Atom
要素 item channel entry
タイトル title title title
リンク link  link link
説明 description description description
日付 dc:date  pubDate issued

rssで取得したデータをmysqlに保存

a

$dbh = new PDO で接続、stmt->executeでsql文を実行
$stmt = $dbh->prepare(“insert into rss (title,link,site_title,site_link,date) values(?,?,?,?,?)”);
$stmt->execute(array($title,$link,$site_title,$site_link,$date));

reference
FETCH_ASSOC:Fetch a result row as an associative array

create table rss(
	id int not null auto_increment primary key,
	title varchar(255),
	link varchar(255),
	site_title varchar(64),
	site_link varchar(64),
	date datetime
);
<?php

try {
  $dbh = new PDO('mysql:host=localhost;dbname=test','dbuser','xxxx');
} catch(PDOException $e){
  var_dump($e->getMessage());
  exit;
}
$num = 5;//RSS取得件数

$rssUrl=array(
  'http://x6xo.hatenablog.com/rss',//サイトURL
);

//magpierss
require_once('./magpierss-master/rss_fetch.inc');
define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');//encode
define('MAGPIE_CACHE_AGE','30');//cache

foreach($rssUrl as $no => $rss_url){
  if($rss_url != ''){
    //urlからRSSを取得
    $rss = @fetch_rss($rss_url);
      if($rss != NULL){
        for ($i=0; $i<count($rss->items); $i++){
          $rss->items[$i]["site_title"] = $rss->channel["title"];
          $rss->items[$i]["site_link"] = $rss->channel["link"];
        }
        // itemsを格納
        $rssItemsArray[] = $rss->items;
      }
  }
}

$concatArray = array();
if (is_array($rssItemsArray)) {
    for($i=0;$i<count($rssItemsArray);$i++){
    $concatArray = array_merge($concatArray,$rssItemsArray&#91;$i&#93;);//配列を統合する
  }

    foreach ($concatArray as $no => $values) {

        //RSSの種類によって日付を取得
        if($values['published']){$date = $values['published'];}
        elseif($values['created']){$date = $values['created'];}
        elseif($values['pubdate']){$date = $values['pubdate'];}
        elseif($values['dc']['date']){$date = $values['dc']['date'];}
        $date=date("Y-m-d H:i:s",strtotime($date));

        //Filter
        $nowtime = date("Y-m-d H:i:s",strtotime( "now" ));//現在時刻の取得
        if($date > $nowtime){//未来記事の排除
        }elseif(preg_match("/AD/", $values["title"])){//広告記事の排除
        }elseif(preg_match("/PR/", $values["title"])){
        }else{

            //値の定義
            $title=$values["title"];
            $link=$values["link"];
            $site_title=$values["site_title"];
            $site_link=$values["site_link"];

            //記事ごとに必要な項目を抽出
            $rssArray[]=array($date, $title, $link, $site_title, $site_link);
        }//
    }//

    //ソート
    function cmp($a, $b) {
        if ($a[0] == $b[0]) return 0;
        return ($a[0] > $b[0]) ? -1 : 1;
    }
    if($rssArray) { usort($rssArray, 'cmp'); }
    if(count($rssArray) > $num){$count=$num;}
    else{$count=count($rssArray);}

    for ($i=0; $i<$count; $i++) {
        $date=date("Y-m-d H:i:s",strtotime($rssArray&#91;$i&#93;&#91;0&#93;));
        $title=$rssArray&#91;$i&#93;&#91;1&#93;;
        $link=$rssArray&#91;$i&#93;&#91;2&#93;;
        $site_title=$rssArray&#91;$i&#93;&#91;3&#93;;
        $site_link=$rssArray&#91;$i&#93;&#91;4&#93;;
        $datelink = "<div>$date";
      $titlelink = "<a href='$link'>$title</a>";
      $site_titlelink = "<a href='$site_link'>[$site_title]</a></div>";
      echo "$datelink$titlelink$site_titlelink</div>";//(確認用)

      $stmt = $dbh->prepare("insert into rss (title,link,site_title,site_link,date) values(?,?,?,?,?)");
      $stmt->execute(array($title,$link,$site_title,$site_link,$date));
    }
}
?>

$stmt->fetchAll(PDO::FETCH_ASSOC) as $dataで、mysqlのデータを表示

<?php
// 接続
try {
  $dbh = new PDO('mysql:host=localhost;dbname=test','dbuser','xxxx');
} catch(PDOException $e){
  var_dump($e->getMessage());
  exit;
}
?>
<html>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>rss</title>
<body>
<?php

  date_default_timezone_set('Asia/Tokyo');

  $sql = "select * from rss order by date desc limit 10";
  echo '<table>';
  $stmt = $dbh->query($sql);
  foreach($stmt->fetchAll(PDO::FETCH_ASSOC) as $data){
    $date = date("m/d H:i",strtotime($data['date']));
    $title = ($data['title']);
    $link = ($data['link']);
    $site_link = ($data['site_link']);
    $site_title = ($data['site_title']);
    echo "<tr><td>$date</td><td><a href='$link'>$title</a></td><td><a href='$site_link'>[$site_title]</a></td></tr>";
  }

echo "</table>";

// 切断
$dbh = null;
?>

rss from fnn news

%e7%84%a1%e9%a1%8c

<?php
$xml = simplexml_load_file('http://rss.fnn-news.com/fnn_news.xml');
echo "<ul>";
foreach($xml->channel->item as $entry){
  $entrydate = date ("Y.m.d",strtotime ($entry->pubDate));
  echo "<li>$entrydate<a href='$entry->link'>$entry->title</a></li>";
}
echo "</ul>";
?>

画像付き
reference:preg_match
Perform a regular expression match

<?php
$xml = simplexml_load_file('http://rss.fnn-news.com/fnn_news.xml');

foreach($xml->channel->item as $entry){
echo "<article>";

// sitelink
$site_title = $xml->channel->title;
$site_link = $xml->channel->link;
$site_titlelink = "<a href='$site_link'>$site_title</a>";
echo $site_titlelink;

// date
$date = date ("Y.m.d",strtotime($entry->pubDate));
echo $date;

//article link
$titlelink = "<a href='$entry->link'>$entry->title</a>";
echo $titlelink;

// picture
preg_match('/<img.*>/i', $entry->description, $entryimg);
echo $entryimg[0];

echo "</article>";
}
?>

make a xml file2

<?php

  /* rss用フィードを作成するcgiファイル
  * index.html, atom.xml, index.rdf
  */

  $RSS_FEED_NUM = 10; // RSSのフィード数

  //1 . RSSヘッダー作成
  $rss = '';
  $rss = $rss . '<?xml version="1.0" encoding="utf-8" ?>';
  $rss = $rss . '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" '
              . 'xmlns:content="http://purl.org/rss/1.0/modules/content/" xml:lang="ja">';
  $rss = $rss . '<channel>';
  $rss = $rss . '<title>YoheiM.NET - 世の中をさらに便利に面白く</title>';
  $rss = $rss . '<link>http://www.yoheim.net/</link>';
  $rss = $rss . '<description>YoheiM.NET - 世の中をさらに便利に、面白く</description>';
  $rss = $rss . '<dc:creator>yoheiM</dc:creator>';

  //2. RSSのデータ部分を好きな数だけ作成する。今回は10個。

  // フィードに出力するファイルパスの配列を取得
  $file_list = getFeedList();

  // FEED数分作成する
  for ($i = 0; $i < $RSS_FEED_NUM; $i++){

    // ブログタイトルを取得
    $fPath = $file_list&#91;$i&#93;;
    $f = fopen($fPath, "rb");
    $title = fgets($f);
    fclose($f);
    $title = getTitle($fPath);

    // blog urlを取得
    $blogURL = getURL($fPath);

    // ブログの中身を取得する
    $content = '';
    $fPath = $file_list&#91;$i&#93;;
    $fp = fopen($fPath, "rb");
    while (!feof($fp)){
      $buf = fgets($fp);
      $content = $content . $buf;
    }
    fclose($fp);

    // 作成日時を作成
    // ファイルの更新日時を使う
    date_default_timezone_set('Asia/Tokyo');
    $pubDate = date("D, d M Y H:i:s", filetime($fPath));

    // Feed作成
    $item = '';
    $item = $item . '<item>';
    $item = $item . '<title>' . $title . '</title>';
    $item = $item . '<link>' . $blogURL . '</link>';
    $item = $item . '<description><!&#91;CDATA&#91;';
    $item = $item . $content;
    $item = $item . '&#93;&#93;></description>';
    $item = $item . '<dc:creator>yoheiM</dc:creator>';
    $item = $item . '<pubDate>'. $pubDate . '</pubDate>';
    $item = $item . '</item>';

    $rss = $rss . $item;
  }

  // 3, RSSの絞めタグなどを作成
  $rss = $rss . '</channel>';
  $rss = $rss . '</rss>';

  // 4, RSSファイルとして認識されうるファイルを3個くらい出力
  $f = fopen("index.xml", "wb");
  fwrite($f, $rss);
  fclose($f);

  $f = fopen("atom.xml", "wb");
  fwrite($f, $rss);
  fclose($f);

  $f = fopen("index.rdf", "wd");
  fwrite($f, $rss);
  fclose($f);

  // end
  echo "OK\n";
?>