zoukankan      html  css  js  c++  java
  • 用php写爬虫去爬数据

    参考文档1
    参考文档2
    这里是我自己写的一个小需求

    <?php
    /**
    采集http://www.959.cn/school,即时更新的最新的文章内容;每分钟采集一次。采集结束后实时入库并展示。
    */
    header("Content-Type: text/html;charset=utf-8");
    date_default_timezone_set('PRC');
    $con = mysqli_connect('127.0.0.1', 'xxxxx', 'xxxxx', 'xxxxx');
    mysqli_set_charset($con,'UTF8');
    
    // 日志位置
    //把当前的最新一条文章的id.shtml的id 存入一个max.log的文件中,实时读取 实时更改
    $log_path = '/home/logs';
    if(!file_exists($log_path)){
            mkdir($log_path,0755,true);
    }
    $max_log = $log_path.'/kecheng_max.log';
    $path = './img/';
    $max = file_get_contents($max_log) ? file_get_contents($max_log) : 4613925; //当前的最新一条文章的id.shtml的id
    
    //记录日志
    $message_log = $log_path.'/kecheng_message.log';
    
    $now_max = 0; //当前网站实际的最新一条的文章的id.shtml的id
    $url = "http://www.959.cn/school/kecheng/";//要爬取的网址
    $res = file_get_contents("compress.zlib://".$url);//curl封装方法
    //var_dump($con);die;
    preg_match_all('/<h3>.*</h3>/',$res,$arr_all);//文章列表内容
    //var_dump($arr_all[0]);
    foreach($arr_all[0] as $k => $v){
    	// 先去匹配a标签 如果不是a标签直接继续下一个
    	preg_match_all('/<a href="(.*)">.*</a>/',$v,$v_all);
    	if (empty($v_all[1])){// 不是a标签
    		continue;
    	}
    	
    	$title =  strip_tags($v_all[0][0]); //文章标题
    	$href = $v_all[1][0];//url
    	
    	// 截取当前url的shtml前面的id
    	$href_one = substr($href, strrpos($href, '/')+1);
    	$href_id = substr($href_one, 0, strpos($href_one, '.'));
    	
    	if ($k === 0) {
            $now_max = $href_id;
        }
    
    	if ($href_id <=  $max){ // 只爬大于保存的最大id的数据
    		$max = file_put_contents($max_log, $now_max, LOCK_EX); // 爬完之后让maxid更新为最新的
    		break;
    	}
    	
    	// 获取标题缩略图
    	preg_match_all('/<img src="(.*)" alt="'.$title.'" />/',$res,$title_img);
    	$title_img_url = $title_img[1][0];
    	if(!file_exists($path)){
    		mkdir($path,0755,true);
    	}
    	$title_img = file_get_contents ("http:{$title_img_url}");
    	$cover_img_name = microtime_float().'.jpg';
    	file_put_contents($path.$cover_img_name, $title_img);
    	$cover_img = '/public/uploads/img/'.date('Y/md',time()).'/'.$cover_img_name; // 标题缩略图位置
    	
    	// 获取文章内容
    	$article_res = file_get_contents("compress.zlib://".$href);
    	//var_dump($article_res);die;
    	$article_res = trimall($article_res);
    	//var_dump($article_res);die;
    	preg_match_all('/<div class="detail">(.*?)</div>/',$article_res,$article_all);//文章详情内容
    	
    	$text = $article_all[1][0]; // 文章内容
    	//var_dump($text);die;
    	
    	//筛选图片 并下载到本地
    	preg_match_all('/<img .*? src="(.*?)" .*? />/',$article_all[1][0],$img_all); //文章详情图片
    	//preg_match_all('/<imgalt="创业项目"src="(.*?)"title="创业项目" />/',$article_all[0][0],$img_all); //文章详情图片
    	//var_dump($img_all[1]);
    	foreach($img_all[1] as $key => $value){
    		$message_img = file_get_contents ("http:{$value}");
    		$message_img_name = microtime_float().'.jpg';
    		file_put_contents($path.$message_img_name, $message_img);
    		
    		$text = str_replace($value,'/public/uploads/img/'.date('Y/md',time()).'/'.$message_img_name,$text);
    	}
    	// 去掉【如果还有什么问题点击留言咨询】 和  >>>>想了解更多创业资讯,点击咨询详情 和 其他的a标签
    	$text = preg_replace("/<a[^>]*>(.*?)</a>/is", "", $text);
    	//var_dump($text);die;
    	
    	// 入库数据
    	$cid = 2;// 1:行业资讯,2:创业故事
    	$source = '88加盟网';
    	$create_time = time();
    	$update_time = time();
    	
    	// 入库前转码
    	$title = mb_convert_encoding($title,'UTF-8');
    	$text = mb_convert_encoding($text,'UTF-8');
    	//var_dump($title, $text);
    	
    	// 插入数据库
    	$sql = "insert into zs_message (cid, title, create_time, update_time, source, cover_img, text) values ($cid, '$title', $create_time, $update_time, '$source', '$cover_img', '$text')";
        $result = mysqli_query($con,$sql);
    	
    	if ($result) {
    		$msg = "当前抓取的页面url为:{$href},入库sql为:{$sql},结果:入库成功";
    	} else {
    		$msg = "当前抓取的页面url为:{$href},入库sql为:{$sql},结果:入库失败";
    	}
    	file_put_contents($message_log, $msg, FILE_APPEND | LOCK_EX);
    	file_put_contents($message_log, "
    
    ", FILE_APPEND | LOCK_EX);
    	
    }
    
    function microtime_float()
    {
        list($usec, $sec) = explode(" ", microtime());
        return $sec.substr($usec,2,6);
    }
    
    
    function trimall($str){
        $qian=array("
    ","
    ");
        return str_replace($qian, '', $str);  
    }
    
    function curl_get_contents($url,$cookie='',$referer='',$timeout=300,$ishead=0) {
      $curl = curl_init();
      curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);
      curl_setopt($curl, CURLOPT_FOLLOWLOCATION,1);
      curl_setopt($curl, CURLOPT_URL,$url);
      curl_setopt($curl, CURLOPT_TIMEOUT,$timeout);
      curl_setopt($curl, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36');
      if($cookie)
      {
        curl_setopt( $curl, CURLOPT_COOKIE,$cookie);
      }
      if($referer)
      {
        curl_setopt ($curl,CURLOPT_REFERER,$referer);
      }
      $ssl = substr($url, 0, 8) == "https://" ? TRUE : FALSE;
      if ($ssl)
      {
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
      }
      $res = curl_exec($curl);
      return $res;
      curl_close($curl);
    }
    
    

    爬虫主要的思路是:用正则去筛选我们爬取我们的页面,然后从列表页获取到的url,再一个个去爬取详情页的内容
    注意事项:

    1. 如果用file_get_contens去获取内容的话,gzip压缩,会出现乱码的情况
    file_get_contents("compress.zlib://".$url);
    

    如是用的curl的话

    function curl_get($url, $gzip=false){
            $curl = curl_init($url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
            if($gzip) curl_setopt($curl, CURLOPT_ENCODING, "gzip"); // 关键在这里
            $content = curl_exec($curl);
            curl_close($curl);
            return $content;
    }
    

    无论页面是否经过gzip压缩,上述代码都可以正常工作!
    参考出处
    2.在获取到页面后,在匹配之前,一定要先把字符串中的 空格换行都去掉,在进行匹配,否则会出现匹配为空的情况

    function trimall($str){
        $qian=array("
    ","
    ");
        return str_replace($qian, '', $str);  
    }
     // 处理页面源码,多行变单行
       $htmlOneLine = preg_replace("/
    |
    |	/","",$html);
    

    3.去掉文章中的超链接或者将锚文本,只保留文字,去掉链接,去掉加粗格式

    $text = preg_replace("/<a[^>]*>(.*?)</a>/is", "", $text);//去掉文章中的超链接
    $str = preg_replace("/<a[^>]*>(.*?)</a>/is", "$1", $str);//只保留文字
    
    

    4.生成图片的路径和文件名(参考)

    $cover_img_name = microtime_float().'.jpg';
    $cover_img = '/public/uploads/img/'.date('Y/md',time()).'/'.$cover_img_name;
    function microtime_float()
    {
        list($usec, $sec) = explode(" ", microtime());
        return $sec.substr($usec,2,6);
    }
    

    5.入库的时候,有可能会出现,存入的数据读出来全是???,或者乱码 要把页面设置为utf8,数据库设置为utf8

    header("Content-Type: text/html;charset=utf-8");
    date_default_timezone_set('PRC');
    $con = mysqli_connect('127.0.0.1', 'xx', 'xx', 'xx');
    mysqli_set_charset($con,'UTF8');
    
    // 入库前转码
    $title = mb_convert_encoding($title,'UTF-8');
    $text = mb_convert_encoding($text,'UTF-8');
    
  • 相关阅读:
    sp2010 升级sp2013 用户无法打开网站
    powerviot install in sharepoint 2013
    can not connect cube in performancce dashboard
    westrac server security configure user info
    添加报表服务在多服务器场
    sharepoint 2013 office web app 2013 文档在线浏览 IE11 浏览器不兼容解决方法
    delete job definition
    目前付款申请单内网打开慢的问题
    item style edit in sharepoint 2013
    Could not load file or assembly '$SharePoint.Project.AssemblyFullName$'
  • 原文地址:https://www.cnblogs.com/djwhome/p/11959408.html
Copyright © 2011-2022 走看看