ゼロと無限の間に

フリーでオープンソースなJavaScriptとかPHPとか。

ユーザ用ツール

サイト用ツール


php-tool-box:feed-meister

サイト内の新規Webページを調べてRSSで配信するPHP製フィード生成ツール - Feed Meister

サイト内のURLを全て集めるPHP製クローラー - URL Collectorをエンジンとして、サイト内(同一ドメイン内)でリンクされているWebページを全て調べ、そのうち新しく作成されたページをピックアップしてRSS 2.0で配信するツールを作った。

DBからRSSを生成できないような静的なサイトで役に立つかもしれない。でもDBを使えるなら、DBのデータを直接RSSにした方が絶対楽だ。

ライセンス

使用例

<?php
require('htmlsql/snoopy.class.php');
require('htmlsql/htmlsql.class.php');
require('UrlCollector.php');
 
$f = new FeedMeister('feed.xml');
$f->pickOut('http://example.co.jp/index.html', 'タイトルに共通の部分');

ソースコード

<?php
/**
 *  Feed Meister
 *  @see       http://0-oo.net/sbox/php-tool-box/feed-meister
 *  @version   0.1.0
 *  @copyright 2010 dgbadmin@gmail.com
 *  @license   http://0-oo.net/pryn/MIT_license.txt (The MIT license)
 */
class FeedMeister {
    private $_collector;
    private $_feed;
    private $_list;
    private $_count;
 
    /**
     *    コンストラクタ
     *    @param    string    $feedPath    フィードを保存するファイルパス
     *    @param    string    $dataPath    (省略可)データを保存するファイルパス
     *    @param    integer    $count    (省略可)フィードに載せる記事の件数
     *    @param    decimal    $interval    (省略可)次のページをクロールするまでの間隔(秒)
     */
    public function __construct($feedPath, $dataPath = 'urls.txt', $count = 30, $interval = 1) {
        $this->_collector = new UrlCollector($interval);
        $this->_feed = $feedPath;
        $this->_list = $dataPath;
        $this->_count = $count;
    }
    /**
     *    フィードを作成する
     *    @param    string    $topUrl    トップページのURL(この階層以下が蒐集対象になる)
     *    @param    string    $titleTrim    (省略可)タイトルから除外する文字列
     *    @param    string    $encoding    (省略可)サイトの文字コード
     */
    public function pickOut($topUrl, $titleTrim = '', $encoding = 'UTF-8') {
        $newArr = $this->_collector->getUrls($topUrl, $titleTrim, $encoding);
        $timeArr = $this->_update($newArr);
        arsort($timeArr);    //更新日時の新しい順
        $this->_writeFeed($newArr, $timeArr, $topUrl);
    }
 
    private function _update($newArr) {
        if (file_exists($this->_list)) {
            $oldArr = explode("\n", file_get_contents($this->_list));
            $oldCnt = count($oldArr);
        } else {
            $oldCnt = 0;
        }
        $bookmark = 0;
        $now = time();
        $timeArr = array();
        $fp = fopen($this->_list, 'w');
        foreach ($newArr as $url => $title) {
            $timestamp = 0;
            for ($i = $bookmark; $i < $oldCnt; $i++) {
                $old = explode("\t", $oldArr[$i]);
                if ($url > $old[0]) {    //該当のURLを探す
                    continue;
                }
                $bookmark = $i;
                if ($url == $old[0]) {    //既存の場合
                    $bookmark++;
                    $timestamp = $old[2];
                }
                break;
            }
            if (!$timestamp) {
                $timestamp = $now;
            }
            fwrite($fp, $url . "\t" . $title . "\t" . $timestamp . "\n");
            $timeArr[$url] = $timestamp;
        }
        fclose($fp);
 
        return $timeArr;
    }
    /**
     *    RSS2.0のみ
     */
    private function _writeFeed($newArr, $timeArr, $top) {
        $encoding = mb_internal_encoding();
        if ($encoding == 'UTF-8') {
            $encoding = '';
        }
 
        $fp = fopen($this->_feed, 'w');
 
        fwrite($fp, '<?xml version="1.0" encoding="utf-8" ?>' . "\n");
        fwrite($fp, '<rss version="2.0">' . "\n");
        fwrite($fp, "<channel>\n");
 
        $title = $this->_convertTitle($newArr[$top], $encoding);
        fwrite($fp, "<title>$title</title>\n");
        fwrite($fp, '<link>' . htmlspecialchars($top, ENT_QUOTES) . "</link>\n");
        fwrite($fp, "<description>$title</description>\n");
        fwrite($fp, "<language>ja</language>\n");
 
        $i = 0;
        foreach ($timeArr as $url => $timestamp) {
            $title = $this->_convertTitle($newArr[$url], $encoding);
            fwrite($fp, "<item>\n");
            fwrite($fp, "<title>$title</title>\n");
            fwrite($fp, '<link>' . htmlspecialchars($url, ENT_QUOTES) . "</link>\n");
            fwrite($fp, '<pubDate>' . date('r', $timestamp) . "</pubDate>\n");
            fwrite($fp, "</item>\n");
 
            $i++;
            if ($i > $this->_count) {
                break;
            }
        }
 
        fwrite($fp, "</channel>\n");
        fwrite($fp, "</rss>");
 
        fclose($fp);
    }
 
    private function _convertTitle($title, $encoding) {
        if ($encoding) {
            $title = mb_convert_encoding($title, 'UTF-8', $encoding);
        }
        return htmlspecialchars($title, ENT_QUOTES);
    }
}
php-tool-box/feed-meister.txt · 最終更新: 2010/02/07 23:05 by dgbadmin

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki