PHP抓取RSS实例代码
源代码:
1 主程序get_notes.php:
<?php
/*
RSS抓取示例程序
*/
define( ’LOCATION_IP’, ’192.168.8.114’ );//192.168.8.114改为本机的ip的地址
define( ’REQUEST_PATH’,’/’ );//根据实际存放目录进行修改
//getFriendRss RSS聚合函数
//参数1 要读取的朋友rss相关数组,参数2 返回的最新日记数目,参数3 设定返回的时间
function &getFriendRss($rss_url_array,$number=10,$limit_time=1)
{
while ( $rss = each( $rss_url_array ) )
{
//echo $rss[1][’url’];
$file_name_array[] = $user_id = $rss[1][’user_id’];
$name = base64_encode( $rss[1][’name’] );
$url = base64_encode( $rss[1][’url’] );
$fp = fsockopen( LOCATION_IP, 80, $errno, $errmsg);
if(!$fp)
{
//echo 1;
Return flase;
}
fputs($fp, “GET ” . REQUEST_PATH . “getRss/get_rss.php?user_id=$user_id&url=$url&name=$name HTTP/1.0\nHost: ” . LOCATION_IP . “\n\n”);
fclose($fp);
}
//print_r( $file_name_array );
sleep( $limit_time );//暂停 $limit_time 秒,此时为RSS抓取时间
$rss_array = 0;
foreach ( $file_name_array as $key => $value )
{
$rss_file = ’./cache/’.$value;
if ( file_exists( $rss_file ) )//因为有的RSS读取会失败,不会建立文件
{
if ( is_readable( $rss_file ) )//避免访问无效文件
{
$rss_array_tmp = unserialize(join(’’, file($rss_file)));
if ( is_array( $rss_array_tmp ) )//防止读到未成功进行xml解析的数据
{
if ( empty( $rss_array ) )
{
$rss_array = $rss_array_tmp;
}else
{
$rss_array = array_merge( $rss_array , $rss_array_tmp );//数组合成
}
}
unset( $rss_array_tmp );
}
}
/*
//加快读取,但这样的话获得并非所有记录中的最新的日记
if ( count( $rss_array )>=$number )
{
array_splice( $rss_array,$number );
return $rss_array;
}
*/
}
//排序
foreach ( $rss_array as $key => $value )
{
$unixtime[$key]=$value[’unixtime’];
}
array_multisort( $unixtime,SORT_NUMERIC, SORT_DESC,$rss_array );
if ( count( $rss_array )>=$number )//截取最新的前 $number 骗日记
array_splice( $rss_array,$number );
return $rss_array;
}
################ 示例 #############################
$rss_url_array = array(
array(’user_id’ =>1,’name’ => ’放弃思考’,’url’ => ’http://blog.chinaunix.net/u/rss.php?id=12569’),
array(’user_id’ =>2,’name’ =>’陈好’,’url’ => ’http://blog.sina.com.cn/myblog/index_rss.php?uid=1195017937’),
array(’user_id’ =>3,’name’ =>’方兴东’,’url’ =>’http://fangxd.blogchina.com/rss2.xml’),
array(’user_id’ =>4,’name’ =>’加油金顺’, ’url’ => ’http://blog.donews.com/jiayoujinshun/Rss.aspx’),
array(’user_id’ =>5,’name’ =>’和讯博客’, ’url’ => ’http://yonnie.blog.hexun.com/rss2.aspx’),
array(’user_id’ =>6,’name’ => ’MSN博客’,’url’ => ’http://blog.csdn.net/haohappy2004/rss.aspx’),
array(’user_id’ =>7,’name’ => ’博易AnyP’, ’url’ => ’http://4734160.anyp.cn/blog/rss.aspx’),
array(’user_id’ =>8,’name’ => ’歪酷网’,’url’ => ’http://cambriantear.yculblog.com/rss.xml’),
array(’user_id’ =>9, ’name’=>’SOHU博客’,’url’=>’http://blog.sohu.com/members/aduo/rss’),
array(’user_id’ =>10,’name’ =>’天涯blog’, ’url’=>’http://www1.tianyablog.com/blogger/rss.asp?BlogID=14858’),
array(’user_id’ =>11,’name’ =>’博客动力’,’url’=>’http://bunny.blogdriver.com/bunny/rss2.xml’)
);
$notes = getFriendRss($rss_url_array,20,1);//读取最新的20篇日记,时间限制1秒
//显示部分
header(“Content-type: text/html; charset=utf8″);
echo ’最新日记列表<br>’;
foreach ( $notes as $key => $value )
{
echo ($key+1).” “.$value[’name’].”日记:<a href=’”.$value[’link’].”’ target=’_blank’>”.$value[’title’].”</a> 时间:”.date(“Y-m-d h:i:s A”,$value[’unixtime’]).”<br>”;
}
#################################################
?>
2 “RSS抓取”进程:get_rss.php
<?php
/*
RSS抓取示例程序
*/
//本页面为“RSS读取进程”,可设置缓存
define( ’RSS_SAVE_PATH’ , ’./cache/’);
define( ’IS_CACHE’,TRUE );//是否开启缓存
define( ’CACHE_TIME’ , 3600 );//缓存时间
define( ’MAX_EXECTION_TIME’,10 );
set_time_limit( MAX_EXECTION_TIME );//设定时间,防止占用太多服务器资源
if ( isSet( $_GET[’url’] ) )
{
$rss_url = base64_decode($_GET[’url’]);
$user_id = $_GET[’user_id’];
$name = base64_decode( $_GET[’name’] );
}else
exit;
if ( IS_CACHE )//是否启用缓存
{
$cache_file = RSS_SAVE_PATH . $user_id;
$time_dif = @(time() – filemtime($cache_file));
if ($time_dif < CACHE_TIME )
exit;//如果缓存文件还出于有效期的话,直接退出,不用再远程读取
}
$cache_file = RSS_SAVE_PATH . $user_id;
$is_inside_item = false;
function startElement($parser, $tagName, $attrs)
{
global $is_inside_item, $tag;
if ($is_inside_item)
{
$tag = $tagName;
}elseif ($tagName == “ITEM”)
{
$is_inside_item = true;
}
}
function endElement($parser, $tagName)
{
global $is_inside_item, $tag, $title, $link,$pubDate,$rss_array,$name;
if ($tagName == “ITEM”)
{
$rss_array[] = array(
’title’ => $title,
’link’ => $link,
’pubdate’ => $pubDate,
’unixtime’ => strtotime( $pubDate ),
’name’ =>$name ,
);
$title = $link = $pubDate = $is_inside_item = false;
}
}
function characterData($parser, $data)
{
global $is_inside_item, $tag, $title, $link,$pubDate;
if ($is_inside_item)
{
switch ($tag)
{
case “TITLE”:
$title .= $data;
break;
case “LINK”:
$link .= $data;
break;
case “PUBDATE”;
$pubDate .= $data;
}
}
}
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, “startElement”, “endElement”);
xml_set_character_data_handler($xml_parser, “characterData”);
$fp = @fopen($rss_url, r);
while ($data = @fread($fp, 4096)) {
xml_parse($xml_parser, $data, feof($fp))
or die(
sprintf(“XML error: %s at line %d”,xml_error_string(xml_get_error_code($xml_parser)),xml_get_current_line_number($xml_parser))
);
}
@fclose($fp);
//print_r( $rss_array );
$serialized = serialize($rss_array);
if ($f = @fopen($cache_file, ’w’))
{
fwrite ($f, $serialized, strlen($serialized));
fclose($f);
}
xml_parser_free($xml_parser);//释放XML解析器
?>
程序下载后,依据您的ip及文件存放路径,修改get_notes.php中的:
define( ’LOCATION_IP’, ’192.168.8.114’ );//192.168.8.114改为本机的ip的地址
define( ’REQUEST_PATH’,’/’ );//根据实际存放目录进行修改
即可运行。
最后谈点RSS抓取实用化的改进方向:
1 完善上述的XML解析,上面只是考虑了最常用的几个标签。
2 定时去抓取,设定一小时或者每天什么时候定时执行。
3 将抓取结果保存于数据库,RSS有更新再写入新的数据。