免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5289 | 回复: 6

cnbeta新闻采集器 [复制链接]

论坛徽章:
0
发表于 2010-11-29 21:37 |显示全部楼层
本帖最后由 luojiannx 于 2010-11-29 22:02 编辑

用火车头和狂人总是这里那里的不如意,搞来搞去,一烦躁,觉着还不如自己写个,于是就这么做了。

本采集器功能:采集cnbeta新闻,同时采集图片,发布于discuz!X1.5论坛。

包含的两个文件config.inc.php、db_mysql.class.php是我以前用惯了的phpwind里面的。

用了一些我很早以前写的旧代码,能工作,但目前已知的bug或者缺陷有:

1、偶尔(采集几百帖后)会在保存几十个图片的时候数据连接中断,用了永久链接也没用。
2、贴数的统计要手动在后台更新
3、当日新帖无体现
4、因为用的ngnix,缓存很讨嫌,难以及时输出调试信息,所以加了个什么repeat填充4k的缓存(从而输出),如果你用的是apache可以把倒数第四行去掉,那很占浏览器内存。

这是第一次写面向对象的实际应用程序,因为想来想去,也只有这样写比较简洁,条理清楚。

程序质量虽然不高,但贵在实用,网上同样功能的程序(还没这么好用)有卖到150的。


  1. <?php
  2. define('IN_NXDLJ', 'index');
  3. include 'config.inc.php';
  4. include 'include/db_mysql.class.php';
  5. ob_implicit_flush(true);
  6. global $DEBUG;

  7. $DEBUG=true;

  8. echo "DEBUG=".$DEBUG."</br>";
  9. debug("debug test success</br>");


  10. $db = new dbstuff;
  11. $db->connect($dbhost, $dbuser, $dbpw, 'haixin_portal', $pconnect);
  12. unset($dbhost, $dbuser, $dbpw, $pconnect);

  13. $startid=intval($_GET['startid']);
  14. $endid=intval($_GET['endid']);
  15. if($endid<$startid)
  16. {
  17.         $a=$endid;
  18.         $endid=$startid;
  19.         $startid=$a;
  20. }


  21. debug("start </br>");


  22. for($id=$startid;$id<=$endid;$id++)
  23. {
  24.         $sql="select id from cnbetaid where id=$id";
  25.         $done=intval($db->get_one($sql));
  26.         debug($id.".done=".$done."</br>");

  27.         if(!$done)
  28.         {       
  29.                 $sql = "INSERT INTO cnbetaid (`id`) VALUES (\"$id\");";
  30.                 $db->query($sql);

  31.                 $lj=new cnbeta($id);
  32.                 $subject = $lj->getsubject();
  33.                 $timestamp = strtotime($lj->gettime());
  34.                 $message =$lj->getmessage();

  35.                 if( $timestamp==0 || $message=="" || !$subject)
  36.                 {
  37.                         debug($id. " not found</br>");

  38.                         continue;
  39.                 }
  40.                
  41.                 dopost($subject,$timestamp,$message,$db);
  42.                 debug( $id."done</br>");
  43.         }
  44. }



  45. exit(" All done");

  46. class cnbeta {

  47.         private  $id;                           
  48.     private  $content="";  
  49.         private  $message="";

  50.         function __construct($id)
  51.         {
  52.                 debug("__construct START </br>");
  53.                 $url="http://www.cnbeta.com/articles/".$id.".htm";
  54.                 $ref_url="http://www.cnbeta.com/index.php";
  55.                 $this->id=$id;

  56.                 $out=curl_grab_page($url, $ref_url, " ", "false",  "null", "false");
  57.                 $pattern = "/<div id=\"news_content\"><a href=\"\/topics\/(\d+)\.htm\" ><img src=\"http:\/\/img\.cnbeta\.com\/topics\/(.*)\" alt=\"(.*)\" name=\"sign\"  align=\"right\" id=\"sign\" onload=\"fixPNG\(this\)\"\/><\/a>/";
  58.                 $replacement = "<div id=\"news_content\"><img src=\"/portal/topics/\$2\" alt=\"\$3\" name=\"sign\"  align=\"right\" id=\"sign\" />";
  59.                 $this->content=preg_replace($pattern, $replacement, $out);

  60.                 if($this->content)
  61.                 {
  62.                         debug(  "__construct UPLOAD START </br>");
  63.                         $a="<div id=\"news_content\">";
  64.                         $b="<div class=\"digbox\">";
  65.                         $c=strbetween($this->content,$a,$b);

  66.                         $pattern="/http:\/\/(\w+\.)+([0-9.]+|net|com|cn|org|cc|tv)(\S*\/)(\S)+\.(gif|GIF|jpg|jpeg|JPG|png|PNG|bmp|BMP)/i";
  67.                         preg_match_all($pattern,$c,$url,PREG_PATTERN_ORDER);
  68.                         for($i=0;$i<=count($url[0]);$i++)
  69.                         {
  70.                                 if($url[0][$i]!='')
  71.                                 {
  72.                                         $now=getdate();
  73.                                         $filename=$now[year].$now[mon].$now[mday].$now[hours].$now[minutes].$now[seconds].$i.".".$url[5][$i];

  74.                                         $savetime=SaveHTTPFile($url[0][$i],"/portal/cnbeta/images",$filename);
  75.                                        
  76.                                         $c=str_replace($url[0][$i],"/portal/cnbeta/images/".$filename,$c);
  77.                                        
  78.                                         debug(  "__construct UPLOADING...... </br>");
  79.                                 }
  80.                         }
  81.                         $this->message=$c;
  82.                         debug(  "__construct UPLOAD END </br>");
  83.                 }
  84.         }

  85.         function getmessage()
  86.         {
  87.                 return $this->message;
  88.         }

  89.         function getsubject()
  90.         {
  91.                 $a="<h3 id=\"news_title\">";
  92.                 $b="</h3>";
  93.                 return strbetween($this->content,$a,$b);
  94.         }

  95.         function gettime()
  96.         {
  97.                 $a="发布于 ";
  98.                 $b="|<script src=\"/counter.php?sid=";
  99.                 return strbetween($this->content,$a,$b);
  100.         }

  101. }

  102. function strbetween($content,$a,$b){
  103.         $start=strpos($content,$a)+strlen($a);
  104.         $length=strpos($content,$b)-$start;
  105.         return(substr($content,$start,$length));
  106. }

  107. function curl_grab_page($url,$ref_url,$data,$login,$proxy,$proxystatus){
  108.         debug( "curl_grab_page START...... </br>");
  109.         $user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";

  110.         $cookie_jar = tempnam('./tmp','cookie');

  111.     $ch = curl_init();
  112.     curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_jar);
  113.     curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_jar);
  114.     curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
  115.     curl_setopt($ch, CURLOPT_TIMEOUT, 40);
  116.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  117.     if ($proxystatus == 'true') {
  118.         curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
  119.         curl_setopt($ch, CURLOPT_PROXY, $proxy);
  120.     }
  121.     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  122.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

  123.     curl_setopt($ch, CURLOPT_URL, $url);
  124.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

  125.     curl_setopt($ch, CURLOPT_REFERER, $ref_url);

  126.     curl_setopt($ch, CURLOPT_HEADER, TRUE);
  127.     curl_setopt($ch, CURLOPT_USERAGENT,  $user_agent);
  128.     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
  129.         if($login == 'true'){
  130.                 curl_setopt($ch, CURLOPT_POST, TRUE);
  131.                 curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  132.         }
  133.        
  134.         ob_start();
  135.         $out=curl_exec($ch);
  136.         ob_end_clean();
  137.         curl_close ($ch);
  138.         debug("curl_grab_page END...... </br>");
  139.         return $out;
  140. }

  141. function getmicrotime(){
  142.     list($usec, $sec) = explode(" ",microtime());
  143.     return ((float)$usec + (float)$sec);
  144. }

  145. function SaveHTTPFile($fFileHTTPPath,$fFileSavePath,$fFileSaveName)
  146. {
  147.         //记录程序开始的时间
  148.         $BeginTime=getmicrotime();
  149.        
  150.         //取得文件名
  151.         $fFileSaveName="/var/www/html/".$fFileSavePath."/".$fFileSaveName;

  152.         //取得文件的内容
  153.         ob_flush();
  154.         flush();
  155.         ob_end_clean();
  156.         ob_start();
  157.         readfile($fFileHTTPPath);
  158.         $img = ob_get_contents();
  159.         ob_end_clean();
  160.         //$size = strlen($img);
  161.         //保存到本地
  162.         $fp2=@fopen($fFileSaveName, "a");
  163.         fwrite($fp2,$img);
  164.         fclose($fp2);

  165.         //记录程序运行结束的时间
  166.         $EndTime=getmicrotime();

  167.         //返回运行时间
  168.         return($EndTime-$BeginTime);
  169. }

  170. function dopost($subject,$timestamp,$message,$db)
  171. {
  172.         debug( "dopost START </br>");
  173.         $thread=array(
  174.                 'fid'=>38,
  175.                 'posttableid'=>0,
  176.                 'readperm'=>0,
  177.                 'price'=>0,
  178.                 'typeid'=>0,
  179.                 'sortid'=>0,
  180.                 'author'=>"罗建",
  181.                 'authorid'=>24,
  182.                 'subject'=>$subject,
  183.                 'dateline'=>$timestamp,
  184.                 'lastpost'=>$timestamp,
  185.                 'lastposter'=>"罗建",
  186.                 'displayorder'=>0,
  187.                 'digest'=>0,
  188.                 'special'=>0,
  189.                 'attachment'=>0,
  190.                 'moderated'=>0,
  191.                 'status'=>0,
  192.                 'isgroup'=>0
  193.         );
  194.         $db->update("insert into forum_thread "
  195.                                   . " SET " . pwSqlSingle($thread)
  196.         );

  197.         $tid=$db->insert_id();


  198.         $post = array(
  199.                         'fid' => 38,
  200.                         'tid' => $tid,
  201.                         'first' => '1',
  202.                         'author' => "罗建",
  203.                         'authorid' => 24,
  204.                         'subject' => $subject,
  205.                         'dateline' => $timestamp,
  206.                         'message' => $message,
  207.                         'useip' => '10.232.154.8',
  208.                         'invisible' => 0,
  209.                         'anonymous' => 0,
  210.                         'usesig' => 1,
  211.                         'htmlon' => 1,
  212.                         'bbcodeoff' => 1,
  213.                         'smileyoff' => 1,
  214.                         'parseurloff' => 1,
  215.                         'attachment' => '0',
  216.                         'tags' => ''
  217.                 );
  218.         $db->update("insert into  forum_post "
  219.                                   . " SET " . pwSqlSingle($post)
  220.         );
  221.        
  222.         $db->update("insert into forum_post_tableid"." set ".pwSqlSingle(array('pid'=>$db->insert_id())));
  223.         debug("dopost END </br>");
  224. }

  225. function debug($str)
  226. {
  227.         global $DEBUG;
  228.         if($DEBUG)
  229.         {
  230.                 ob_start();
  231.                 echo $str;
  232.                 echo str_repeat(' ', 1024*4);
  233.                 ob_flush();
  234.                 flush();
  235.                 ob_end_clean();
  236.         }

  237. }
  238. ?>
复制代码
采集效率大概在半个小时800贴左右,要看网速以及文章图片的多少。

论坛徽章:
0
发表于 2010-11-29 22:15 |显示全部楼层
//取得文件的内容
        ob_flush();
        flush();
        ob_end_clean();
        ob_start();
        readfile($fFileHTTPPath);
        $img = ob_get_contents();
        ob_end_clean();
        //$size = strlen($img);
        //保存到本地
        $fp2=@fopen($fFileSaveName, "a");
        fwrite($fp2,$img);
        fclose($fp2);

论坛徽章:
0
发表于 2010-11-29 22:18 |显示全部楼层
本帖最后由 luojiannx 于 2010-11-29 22:21 编辑

这个缓存的事弄得我头晕了,请见谅。

也许有点多余:)

等我把相关文档吃透后,看看能不能写得简洁清晰。

这里只是展示一个论坛采集文章的方法,不一定要花钱买的。

稍微有点耐心就可以了。

论坛徽章:
0
发表于 2010-11-29 22:37 |显示全部楼层
curl_grab_page()用到了curl,在这个不需要登录的环境下是完全没必要的,可以用一行代码就代替了,但是考虑到以后的扩展,所以还是用了curl

论坛徽章:
0
发表于 2011-11-18 14:02 |显示全部楼层
mark

论坛徽章:
0
发表于 2011-11-18 19:30 |显示全部楼层
curl比较好,扩展性强,学习了

论坛徽章:
0
发表于 2011-11-20 12:34 |显示全部楼层
cnbeta的滥新闻也有人采集?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP