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');
    
  • 相关阅读:
    android flash air 打包工具
    MyEclipse 7.0快捷键大全
    android mp4 videoView
    位图处理
    myeclise10.0下载
    dropdown.js
    back track
    ANE 跨平台 as3 转 objectc android desktop
    jquery 例子
    android 屏蔽 home 2
  • 原文地址:https://www.cnblogs.com/djwhome/p/11959408.html
Copyright © 2011-2022 走看看