免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7079 | 回复: 6
打印 上一主题 下一主题

[RSS解析 原创]RSS文档解析类 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-09-27 15:35 |只看该作者 |倒序浏览
  1. <?PHP
  2.         /*****************************
  3.         *        RSS文档解析类-(lovered.GV)
  4.         ******************************/
  5.         class RssParse
  6.         {
  7.                 var $url;                        //rss文件的地址
  8.                 var $data;                        //rss文件的内容
  9.                 var $version;                //rss文件的版本号
  10.                 var $channel;                //rss文件中的频道信息
  11.                 var $items;
  12.        
  13.                 //与XML解析有关的属性####################
  14.                 var $xml_parser;        //xml解析器句柄
  15.                 var $depth;                        //XML当前解析深度
  16.                 var $tag;                        //当前正在解析的XML元素
  17.                 var $prev_tag;                //当前正在解析的上一个元素
  18.                 var $marker;                //用来标记制定的深度
  19.                 var $event;                        //实践名称:CHANNEL and ITEM
  20.                 var $item_index;        //item元素索引

  21.                 //初始化#################################
  22.                 function RssParse($rss_url)
  23.                 {
  24.                         $h=fopen($rss_url,"r");
  25.                         if($h)
  26.                         {
  27.                                 $this->;url=$rss_url;

  28.                                 while(!feof($h))
  29.                                         $this->;data.=fgets($h,4096);
  30.                                 fclose($h);

  31.                                 //初始化xml解析器
  32.                                 $this->;xml_parser = xml_parser_create("UTF-8");
  33.                                 xml_set_object($this->;xml_parser, &$this);
  34.                                 xml_parser_set_option($this->;xml_parser, XML_OPTION_CASE_FOLDING, 1);
  35.                                 xml_set_element_handler($this->;xml_parser, "startElement", "endElement");
  36.                                 xml_set_character_data_handler($this->;xml_parser, "characterData");
  37.                                 //开始解析数据
  38.                                 if (!xml_parse($this->;xml_parser, $this->;data))
  39.                                         trigger_error("XML error: ".xml_error_string(xml_get_error_code($this->;xml_parser))." at line ".xml_get_current_line_number($this->;xml_parser),E_USER_ERROR);
  40.                         }
  41.                         else
  42.                                 trigger_error("无法初始化RSS对象,{$rss_url}无法访问或者不存在",E_USER_ERROR);
  43.                 }

  44.                 //返回所有ITEM信息#######################
  45.                 function GetItems()
  46.                 {
  47.                         return $this->;items;
  48.                 }

  49.                 //返回频道信息###########################
  50.                 function GetChannel()
  51.                 {
  52.                         return $this->;channel;
  53.                 }

  54.                 //返回RSS文件的版本信息##################
  55.                 function GetVersion()
  56.                 {
  57.                         return $this->;version;
  58.                 }

  59.                 //开始解析XML元素########################
  60.                 function startElement($parser, $name, $attribs)
  61.                 {
  62.                         $this->;depth++;
  63.                         $this->;tag=$name;

  64.                         switch($name)
  65.                         {
  66.                                 case "RSS":
  67.                                         $this->;event=$name;
  68.                                         $this->;version=$attribs["VERSION"];
  69.                                         break;
  70.                                 case "CHANNEL":
  71.                                         $this->;event=$name;
  72.                                         $this->;marker=$this->;depth+1;
  73.                                         break;
  74.                                 case "ITEM":
  75.                                         $this->;item_index++;
  76.                                         $this->;event=$name;
  77.                                         $this->;marker=$this->;depth+1;
  78.                                         break;
  79.                                 default:
  80.                                         return NULL;
  81.                         }
  82.                 }

  83.                 //结束某个元素解析时#####################
  84.                 function endElement($parser, $name)
  85.                 {
  86.                         $this->;depth--;
  87.                         return;
  88.                 }

  89.                 //处理数据###############################
  90.                 function characterData($parser, $data)
  91.                 {
  92.                         $data=iconv("utf-8","gb2312",trim($data));


  93.                         //当数据为chanel下的数据时执行
  94.                         if( $this->;event=="CHANNEL" && $this->;marker==$this->;depth )
  95.                         {
  96.                                 $this->;channel[$this->;tag]=$data;
  97.                         }

  98.                         //当数据为item下的数据时执行
  99.                         if( $this->;event=="ITEM" && $this->;marker==$this->;depth )
  100.                         {
  101.                                 if($this->;prev_tag==$this->;tag)
  102.                                         $this->;items[$this->;item_index][$this->;tag].=$data;
  103.                                 else
  104.                                         $this->;items[$this->;item_index][$this->;tag]=$data;
  105.                         }

  106.                         $this->;prev_tag=$this->;tag;
  107.                 }

  108.                 //是否是一个有效的RSS地址################
  109.                 function IsRss($rss_url)
  110.                 {
  111.                         $rss_url=trim($rss_url);

  112.                         if($rss_url=="")
  113.                                 return false;

  114.                         if($h=@fopen($rss_url,"r"))
  115.                         {
  116.                                 $text=@fread($h,512);
  117.                                 @fclose($h);

  118.                                 if(eregi("<RSS",$text))
  119.                                         return true;
  120.                                 else
  121.                                         return false;
  122.                         }
  123.                         else
  124.                                 return false;
  125.                 }
  126.         }
  127. ?>;
复制代码

论坛徽章:
0
2 [报告]
发表于 2005-09-27 15:45 |只看该作者

[RSS解析 原创]RSS文档解析类

调用方法
if(RssParse::IsRss($rss_url))
    $rss=new RssParse($rss_url);

论坛徽章:
0
3 [报告]
发表于 2005-12-24 08:39 |只看该作者
请教楼主一个问题,如果有新数据的话,是把整个RSS文件重新生成一下吗?还是只更新某个节点?
如果方便的话能否给出一个简单的小程序为例?呵呵,谢了~~

论坛徽章:
0
4 [报告]
发表于 2005-12-24 09:32 |只看该作者
请教lz $this->;url =类似这样的 为什么要这样写 有什么好处?

论坛徽章:
0
5 [报告]
发表于 2005-12-24 14:42 |只看该作者
原帖由 kapil 于 2005-12-24 08:39 发表
请教楼主一个问题,如果有新数据的话,是把整个RSS文件重新生成一下吗?还是只更新某个节点?
如果方便的话能否给出一个简单的小程序为例?呵呵,谢了~~

关于更新的问题我也很苦脑.需要重新读取文件.不生成新文件.目前我解决更新的办法是通过报存到数据库中来判断.效率不高,也在找解决办法.
例子创建实例后 print_r看一下酒知道了.

论坛徽章:
0
6 [报告]
发表于 2005-12-24 14:44 |只看该作者
原帖由 ydlhero 于 2005-12-24 09:32 发表
请教lz $this->;url =类似这样的 为什么要这样写 有什么好处?

答,粘贴上来就变成这样了,我没有注意.

论坛徽章:
0
7 [报告]
发表于 2005-12-24 15:40 |只看该作者
贡献一个目前自己正在用的RSS Reader类,下载地址http://lastrss.webdot.cz/,感觉还可以,更新上似乎用的是在磁盘上建Cache文件的办法。判断和转换字符编码上好像也更灵活些。
  1. <?php
  2. class lastRSS {
  3.         // -------------------------------------------------------------------
  4.         // Public properties
  5.         // -------------------------------------------------------------------
  6.         var $default_cp = 'UTF-8';
  7.         var $CDATA = 'nochange';
  8.         var $cp = 'gb2312';//默认值为本人所加
  9.         var $items_limit = 0;
  10.         var $stripHTML = False;
  11.         var $date_format = '';

  12.         // -------------------------------------------------------------------
  13.         // Private variables
  14.         // -------------------------------------------------------------------
  15.         var $channeltags = array ('title', 'link', 'description', 'language', 'copyright', 'managingEditor', 'webMaster', 'lastBuildDate', 'rating', 'docs');
  16.         var $itemtags = array('title', 'link', 'description', 'author', 'category', 'comments', 'enclosure', 'guid', 'pubDate', 'source');
  17.         var $imagetags = array('title', 'url', 'link', 'width', 'height');
  18.         var $textinputtags = array('title', 'description', 'name', 'link');

  19.         // -------------------------------------------------------------------
  20.         // Parse RSS file and returns associative array.
  21.         // -------------------------------------------------------------------
  22.         function Get ($rss_url) {
  23.                 // If CACHE ENABLED
  24.                 if ($this->cache_dir != '') {
  25.                         $cache_file = $this->cache_dir . '/rsscache_' . md5($rss_url);
  26.                         $timedif = @(time() - filemtime($cache_file));
  27.                         if ($timedif < $this->cache_time) {
  28.                                 // cached file is fresh enough, return cached array
  29.                                 $result = unserialize(join('', file($cache_file)));
  30.                                 // set 'cached' to 1 only if cached file is correct
  31.                                 if ($result) $result['cached'] = 1;
  32.                         } else {
  33.                                 // cached file is too old, create new
  34.                                 $result = $this->Parse($rss_url);
  35.                                 $serialized = serialize($result);
  36.                                 if ($f = @fopen($cache_file, 'w')) {
  37.                                         fwrite ($f, $serialized, strlen($serialized));
  38.                                         fclose($f);
  39.                                 }
  40.                                 if ($result) $result['cached'] = 0;
  41.                         }
  42.                 }
  43.                 // If CACHE DISABLED >> load and parse the file directly
  44.                 else {
  45.                         $result = $this->Parse($rss_url);
  46.                         if ($result) $result['cached'] = 0;
  47.                 }
  48.                 // return result
  49.                 return $result;
  50.         }
  51.        
  52.         // -------------------------------------------------------------------
  53.         // Modification of preg_match(); return trimed field with index 1
  54.         // from 'classic' preg_match() array output
  55.         // -------------------------------------------------------------------
  56.         function my_preg_match ($pattern, $subject) {
  57.                 // start regullar expression
  58.                 preg_match($pattern, $subject, $out);

  59.                 // if there is some result... process it and return it
  60.                 if(isset($out[1])) {
  61.                         // Process CDATA (if present)
  62.                         if ($this->CDATA == 'content') { // Get CDATA content (without CDATA tag)
  63.                                 $out[1] = strtr($out[1], array('<![CDATA['=>'', ']]>'=>''));
  64.                         } elseif ($this->CDATA == 'strip') { // Strip CDATA
  65.                                 $out[1] = strtr($out[1], array('<![CDATA['=>'', ']]>'=>''));
  66.                         }

  67.                         // If code page is set convert character encoding to required
  68.                         if ($this->cp != '')
  69.                                 //$out[1] = $this->MyConvertEncoding($this->rsscp, $this->cp, $out[1]);
  70.                                 $out[1] = iconv($this->rsscp, $this->cp.'//TRANSLIT', $out[1]);
  71.                         // Return result
  72.                         return trim($out[1]);
  73.                 } else {
  74.                 // if there is NO result, return empty string
  75.                         return '';
  76.                 }
  77.         }

  78.         // -------------------------------------------------------------------
  79.         // Replace HTML entities &something; by real characters
  80.         // -------------------------------------------------------------------
  81.         function unhtmlentities ($string) {
  82.                 // Get HTML entities table
  83.                 $trans_tbl = get_html_translation_table (HTML_ENTITIES, ENT_QUOTES);
  84.                 // Flip keys<==>values
  85.                 $trans_tbl = array_flip ($trans_tbl);
  86.                 // Add support for ' entity (missing in HTML_ENTITIES)
  87.                 $trans_tbl += array(''' => "'");
  88.                 // Replace entities by values
  89.                 return strtr ($string, $trans_tbl);
  90.         }

  91.         // -------------------------------------------------------------------
  92.         // Parse() is private method used by Get() to load and parse RSS file.
  93.         // Don't use Parse() in your scripts - use Get($rss_file) instead.
  94.         // -------------------------------------------------------------------
  95.         function Parse ($rss_url) {
  96.                 // Open and load RSS file
  97.                 if ($f = @fopen($rss_url, 'r')) {
  98.                         $rss_content = '';
  99.                         while (!feof($f)) {
  100.                                 $rss_content .= fgets($f, 4096);
  101.                         }
  102.                         fclose($f);

  103.                         // Parse document encoding
  104.                         $result['encoding'] = $this->my_preg_match("'encoding=[\'\"](.*?)[\'\"]'si", $rss_content);
  105.                         // if document codepage is specified, use it
  106.                         if ($result['encoding'] != '')
  107.                                 { $this->rsscp = $result['encoding']; } // This is used in my_preg_match()
  108.                         // otherwise use the default codepage
  109.                         else
  110.                                 { $this->rsscp = $this->default_cp; } // This is used in my_preg_match()

  111.                         // Parse CHANNEL info
  112.                         preg_match("'<channel.*?>(.*?)</channel>'si", $rss_content, $out_channel);
  113.                         foreach($this->channeltags as $channeltag)
  114.                         {
  115.                                 $temp = $this->my_preg_match("'<$channeltag.*?>(.*?)</$channeltag>'si", $out_channel[1]);
  116.                                 if ($temp != '') $result[$channeltag] = $temp; // Set only if not empty
  117.                         }
  118.                         // If date_format is specified and lastBuildDate is valid
  119.                         if ($this->date_format != '' && ($timestamp = strtotime($result['lastBuildDate'])) !==-1) {
  120.                                                 // convert lastBuildDate to specified date format
  121.                                                 $result['lastBuildDate'] = date($this->date_format, $timestamp);
  122.                         }

  123.                         // Parse TEXTINPUT info
  124.                         preg_match("'<textinput(|[^>]*[^/])>(.*?)</textinput>'si", $rss_content, $out_textinfo);
  125.                                 // This a little strange regexp means:
  126.                                 // Look for tag <textinput> with or without any attributes, but skip truncated version <textinput /> (it's not beggining tag)
  127.                         if (isset($out_textinfo[2])) {
  128.                                 foreach($this->textinputtags as $textinputtag) {
  129.                                         $temp = $this->my_preg_match("'<$textinputtag.*?>(.*?)</$textinputtag>'si", $out_textinfo[2]);
  130.                                         if ($temp != '') $result['textinput_'.$textinputtag] = $temp; // Set only if not empty
  131.                                 }
  132.                         }
  133.                         // Parse IMAGE info
  134.                         preg_match("'<image.*?>(.*?)</image>'si", $rss_content, $out_imageinfo);
  135.                         if (isset($out_imageinfo[1])) {
  136.                                 foreach($this->imagetags as $imagetag) {
  137.                                         $temp = $this->my_preg_match("'<$imagetag.*?>(.*?)</$imagetag>'si", $out_imageinfo[1]);
  138.                                         if ($temp != '') $result['image_'.$imagetag] = $temp; // Set only if not empty
  139.                                 }
  140.                         }
  141.                         // Parse ITEMS
  142.                         preg_match_all("'<item(| .*?)>(.*?)</item>'si", $rss_content, $items);
  143.                         $rss_items = $items[2];
  144.                         $i = 0;
  145.                         $result['items'] = array(); // create array even if there are no items
  146.                         foreach($rss_items as $rss_item) {
  147.                                 // If number of items is lower then limit: Parse one item
  148.                                 if ($i < $this->items_limit || $this->items_limit == 0) {
  149.                                         foreach($this->itemtags as $itemtag) {
  150.                                                 $temp = $this->my_preg_match("'<$itemtag.*?>(.*?)</$itemtag>'si", $rss_item);
  151.                                                 if ($temp != '') $result['items'][$i][$itemtag] = $temp; // Set only if not empty
  152.                                         }
  153.                                         // Strip HTML tags and other bullshit from DESCRIPTION
  154.                                         if ($this->stripHTML && $result['items'][$i]['description'])
  155.                                                 $result['items'][$i]['description'] = strip_tags($this->unhtmlentities(strip_tags($result['items'][$i]['description'])));
  156.                                         // Strip HTML tags and other bullshit from TITLE
  157.                                         if ($this->stripHTML && $result['items'][$i]['title'])
  158.                                                 $result['items'][$i]['title'] = strip_tags($this->unhtmlentities(strip_tags($result['items'][$i]['title'])));
  159.                                         // If date_format is specified and pubDate is valid
  160.                                         if ($this->date_format != '' && ($timestamp = strtotime($result['items'][$i]['pubDate'])) !==-1) {
  161.                                                 // convert pubDate to specified date format
  162.                                                 $result['items'][$i]['pubDate'] = date($this->date_format, $timestamp);
  163.                                         }
  164.                                         // Item counter
  165.                                         $i++;
  166.                                 }
  167.                         }

  168.                         $result['items_count'] = $i;
  169.                         return $result;
  170.                 }
  171.                 else // Error in opening return False
  172.                 {
  173.                         return False;
  174.                 }
  175.         }
  176. }
  177. ?>
复制代码

[ 本帖最后由 gaoyikun 于 2005-12-24 15:42 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP