采集程序最简单的思路就是:获取页面代码——分析代码——获取需要的部分——写入数据库。
当然,在获取页面代码之前我们首先要获得被采集页面的url,这里我们从百度新闻获取某关键词最新新闻列表。
function get_baidu_news_url($str){ if(!$str) return; $str = gbk($str); //使用正则匹配出列表中的新闻URL $html = utf8(file_get_contents('http://news.baidu.com/ns?tn=newstitle&cl=2&rn=20&word=' . urlencode($str))); preg_match_all("/<a href=http:\/\/(.+?) mon=(.+?)>(.+?)<\/a>/is",$html,$match); $urlarr = $match[1]; if($urlarr){ //URL前面补上http:// array_walk($new_urlarr, create_function('&$v', '$v = "http://".$v ;')); cache_write($cachename, $new_urlarr, CACHE_PATH); } return $new_urlarr; }
拿到新闻页面的URL之后,下一步就是采集页面上的新闻,当然这一步要针对各个网站定制不同的匹配规则,这里以新浪为例。新浪新闻以“<!– 正文内容 begin –>”开始,“<!– 正文内容 end –>”结束,所以匹配正文的正则为
preg_match_all("/<!-- 正文内容 begin -->([\s|\S]*?)<!-- 正文内容 end -->/is",$html,$match);
同理,匹配标题的正则为
preg_match_all("/<h1 id=\"artibodyTitle\"(.*?)>(.+?)<\/h1>/is",$html,$title_match);
函数完整代码:
function news_content_sina($url){ if(!$url) return; $html = utf8(file_get_contents($url)); preg_match_all("/<!-- 正文内容 begin -->([\s|\S]*?)<!-- 正文内容 end -->/is",$html,$match); preg_match_all("/<h1 id=\"artibodyTitle\"(.*?)>(.+?)<\/h1>/is",$html,$title_match); $title = $title_match[2][0]; $content = news_content_format($match[1][0]); if($title && $content) return compact('url','title','content'); }
上面方法中用到了 news_content_format(),这个方法是用来格式化采集到的正文,去掉js、css、iframe、注释以及站内链接,下面代码中可以看到,我们去除了站内链接但保留了其他的<a>标签链接,这样就可以避免某些重要外链丢失影响新闻完整性,比如某考试报名地址链接。
function news_content_format($content){ $search = array ("'<script[^>]*?>.*?</script>'si", // 去掉 javascript "'<style[^>]*?>.*?</style>'si", // 去掉 css "'<iframe[^>]*?>.*?</iframe>'si", // 去掉 iframe "'<!--[/!]*?[^<>]*?>'si", // 去掉 注释 标记 "'<a(.*?) href=(.*?)(sina.com|weibo.com)(.*?)>(.*?)<\/a>'si", // 去掉 内部 链接 ); $replace = array ("","","","","","\${5}"); $content = preg_replace($search, $replace, $content); $content = strip_tags($content, '<p> <br> <img> <table> <tr> <td> <strong> <a>'); return $content; }
到这里,采集的功能基本上就完成了,但是还有一点要注意,就是新闻中的图片如果也需要采集到本地的话,就要用到下面这个方法。
function getimage($body){ global $img_dir,$img_webhost;//本站图片目录、主机 if(!empty($body)){ $body = stripslashes($body); $img_array = array(); //匹配出采集内容中的图片地址 preg_match_all("/(src|SRC)=[\"|'|]{0,}(http:\/\/(.*)\.(gif|jpg|jpeg|bmp|png))/isU",$body,$img_array); $img_array = array_unique($img_array[2]); set_time_limit(0); //定义图片名,创建目录 $imgPath = $img_dir."/".strftime("%Y%m%d",time()); $imgUrl = "http://".$img_webhost."/".$imgPath; $milliSecond = strftime("%H%M%S",time()); if(!is_dir($imgPath)) @mkdir($imgPath,0777); foreach($img_array as $key =>$value) { $value = trim($value); //抓取图片并保存 $get_file = @file_get_contents($value); $rndFileName = $imgPath."/".$milliSecond.$key.".".substr($value,-3,3); $fileurl = $imgUrl."/".$milliSecond.$key.".".substr($value,-3,3); if($get_file) { $fp = @fopen($rndFileName,"w"); @fwrite($fp,$get_file); @fclose($fp); } $body = ereg_replace($value,$fileurl,$body); } return $body; }
写入数据库等常规的操作在这里就不再赘述。