使用PHP提供的CURL模块采集任意网页 已经封装一个类超级好用

本文介绍了一个功能丰富的PHP CURL类,支持GET、POST等请求方式,并提供了详细的使用示例,包括单个请求、批量请求及文件上传等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<?php  
/** 
 * 类名称:curl 
 * 1.支持单个get,post请求 
 * 2.支持多个目标未登录get请求 
 * 3.支持单个目标并行多个get,post请求 
 * 4.支持ajax请求 
 * 5.支持自定义header请求 
 * 6.支持自定义编码数据请求(该情况比较特殊) 
 * 7.支持代理登陆 
 * 8.支持自定义来路 
 * 9.支持自定义超时 
 * 10.支持文件上传 
 */  
  
/** 
 * demo1 get 请求 
 * curl()->get("http://www.baidu.com")->body(); 
 */  
  
/** 
 * demo2 post请求  
 * curl()->post("http://www.xxx.com/say.php",array( 
 *      'data' => array( 
 *                  'title' => 'test title', 
 *                  'content' => 'test content', 
 *              ), 
 * ))->body(); 
 */  
  
/** 
 * demo3 post请求 ajax请求 并设置cookie 
 * curl()->post("http://www.xxx.com/save.php",array( 
 *      'data' => array( 
 *              'username' => 'test', 
 *              'password' => 'test' 
 *             ), 
 *      'cookie_file' => '/tmp/cookie.txt', 
 *      'ajax' => 1, 
 * ))->body(); 
 */  
  
/*** 
 * demo4 批处理get请求 
 * curl()->get(array( 
 *  'http://www.xxx.com/test1.php?aaa=111', 
 *  'http://www.xxx.com/test2.php?aaa=222', 
 *  'http://www.xxx.com/test3.php?aaa=333', 
 * ))->body(); 
 */  
  
/*** 
 * demo5 批处理post请求 post请求,目前只支持单个网站的批处理post请求 
 * curl()->post(array( 
 *  'http://www.xxx.com/test1.php', 
 *  'http://www.xxx.com/test2.php', 
 *  'http://www.xxx.com/test3.php', 
 * ),array( 
 *   'data' => array( 
 *        array( 
 *              'uid' => 'aabbccdd', 
 *        ), 
 *        array( 
 *              'uid' => 'eeeeeeee', 
 *        ), 
 *        array( 
 *              'uid' => 'ffffffff', 
 *        ), 
 *   ), 
 *   'cookie_file' => '/tmp/cookie.txt' 
 * ))->body(); 
 */  
  
/** 
 * demo6 文件上传 
 * curl()->post('填写url地址',array( 
 *       'files' => array( 
 *          'pic' => '/tmp/a.gif' , 
 *       ), 
 *   ))->body(); 
 */  
  
/** 
 * 其他方法未一一列举,可查看源码进行测试 
 */  
  
class Curl {  
      
    //单例对象  
    private static $ins = null;  
      
    //请求结果  
    private $body = null;  
      
    //cookie文件  
    private $cookieFile = null;  
      
    //支持的请求方法  
    private $method = array('get','post');  
    
    //禁用初始化方法  
    final private function __construct()  
    {          
    }  
      
    /** 
     * 单例化对象 
     */  
    public static function exec()  
    {  
        if (self::$ins) {  
            return self::$ins;  
        }  
        return self::$ins = new self();  
    }  
      
    /** 
     * 禁止克隆对象 
     */  
    public function __clone()  
    {  
        throw new curlException('错误:不能克隆对象');  
    }  
      
    /** 
     * 调用不存在的方法被调用 
     */  
    public function __call($method, $args)  
    {  
        if(!in_array($method,$this->method)) {  
            throw new curlException("错误:不支持{$method}方法,支持的方法有"   
                . join(',',$this->method));  
        }  
        return $this->request($method, $args);  
    }  
      
    /** 
     * 返回执行结果 
     */  
    public function body()   
    {  
        return $this->body;  
    }  
  
    /** 
     * 执行请求 
     * @param type $method 
     * @param type $args 
     * @return 返回对象本身 
     */  
    private function request($method, $args)   
    {  
  
        if (isset($args[1]['multi'])) {  
            $this->body = $this->multiExecCurl($method, $args);  
        } else {  
            $this->body = $this->execCurl($method, $args);  
        }  
        return $this;  
    }  
      
    /** 
     * curl 批处理请求 
     * @param type $method 
     * @param type $args 
     * @return type 
     */  
    public function multiExecCurl($method, $args)  
    {  
        $urls      = isset($args[0])            ? $args[0]            : "";  
        $data      = isset($args[1]['data'])    ? $args[1]['data']    : "";  
        $ajax      = isset($args[1]['ajax'])    ? $args[1]['ajax']    : "";  
        $timeout   = isset($args[1]['timeout']) ? $args[1]['timeout'] : 30;  
        $referer   = isset($args[1]['referer']) ? $args[1]['referer'] : "";  
        $proxy     = isset($args[1]['proxy'])   ? $args[1]['proxy']   : "";  
        $headers   = isset($args[1]['headers']) ? $args[1]['headers'] : "";  
          
        if (!is_array($urls) || (is_array($urls) && empty($urls))) {  
            throw new curlException("错误信息:批处理url必须是数组并且不能为空");  
        }  
          
        //创建批处理cURL句柄   
        $queue   = curl_multi_init();  
          
        //取得cookie文件路径  
        if(!$this->cookieFile) {  
            $this->cookieFile = isset($args[1]['cookie_file'])   
                    ? $args[1]['cookie_file'] : "";  
        }  
          
        //如果未获取到浏览器环境信息,就手动指定一个  
        $userAgent = isset($_SERVER['HTTP_USER_AGENT'])   
                        ? $_SERVER['HTTP_USER_AGENT']   
                            : 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:23.0) '  
                                .'Gecko/20100101 Firefox/23.0';  
  
        //设置CURL OPT选项  
        $options = array(    
                    CURLOPT_TIMEOUT        => $timeout,  //超时  
                    CURLOPT_RETURNTRANSFER => 1,         //输出数据流  
                    CURLOPT_HEADER         => 0,         //禁止头文件数据流输出  
                    CURLOPT_FOLLOWLOCATION => 1,         //自动跳转追踪  
                    CURLOPT_AUTOREFERER    => 1,         //自动设置来路信息  
                    CURLOPT_SSL_VERIFYPEER => 0,         //认证证书检查  
                    CURLOPT_SSL_VERIFYHOST => 0,         //检查SSL加密算法  
                    CURLOPT_HEADER         => 0,         //禁止头文件输出  
                    CURLOPT_NOSIGNAL       => 1,         //忽略php所有的传递信号  
                    CURLOPT_USERAGENT      => $userAgent,//浏览器环境字符串  
                    CURLOPT_IPRESOLVE      => CURL_IPRESOLVE_V4, //ipv4寻址方式  
                    CURLOPT_ENCODING       => 'gzip',    //解析使用gzip压缩的网页   
                   );    
          
         //检测是否存在代理请求  
         if (is_array($proxy) && !empty($proxy)) {  
              
            $options[CURLOPT_PROXY]        = $proxy['host'];  
            $options[CURLOPT_PROXYPORT]    = $proxy['port'];  
              
            $options[CURLOPT_PROXYUSERPWD] =   
                                        $proxy['user'] . ':' . $proxy['pass'];  
        }  
          
        //header选项  
        $headerOptions = array();  
          
        //模拟AJAX请求   
        if ($ajax) {  
            $headerOptions['X-Requested-With']  = 'XMLHttpRequest';  
        }  
          
        if ($this->cookieFile) {  
            $options[CURLOPT_COOKIEFILE] = $this->cookieFile;  
            $options[CURLOPT_COOKIEJAR]  =  $this->cookieFile;  
        }  
  
        if ($referer) {  
            $options[CURLOPT_REFERER] = $referer;  
        }  
          
        if (!empty($headerOptions)) {  
            $options[CURLOPT_HTTPHEADER] = $headerOptions;  
        }  
          
        //循环的进行初始化一个cURL会话  
        foreach ($urls as  $k => $url) {       
            $ch = curl_init();  
            curl_setopt($ch, CURLOPT_URL, $url);            
              
            if ($method == 'post') {  
                //发送一个常规的POST请求,  
                //类型为:application/x-www-form-urlencoded,就像表单提交的一样  
                $options[CURLOPT_POST]       = 1;  
                  
                //使用HTTP协议中的"POST"操作来发送数据,支持键值对数组定义  
                //注意:即使不使用http_build_query也能自动编码  
                $options[CURLOPT_POSTFIELDS] = $data[$k];   
            }  
              
            curl_setopt_array($ch,$options);  
            curl_multi_add_handle($queue, $ch);  
        }  
  
        //初始化变量  
        $responses = array();  
        $active    = null;  
  
        //循环运行当前 cURL 句柄的子连接  
        do {  
            while (($code = curl_multi_exec($queue,   
                    $active)) == CURLM_CALL_MULTI_PERFORM);  
  
            if ($code != CURLM_OK) {   
                break;  
            }  
  
            //循环获取当前解析的cURL的相关传输信息  
            while ($done = curl_multi_info_read($queue)) {  
  
                //获取最后一次传输的相关信息  
                $info = curl_getinfo($done['handle']);  
  
                //从最后一次传输的相关信息中找 http_code 等于200  
                if ($info['http_code'] == 200) {  
                    //如果设置了CURLOPT_RETURNTRANSFER,获取的输出的文本流  
                    $responses[] = curl_multi_getcontent($done['handle']);  
                }  
  
                //移除curl批处理句柄资源中的某个句柄资源  
                curl_multi_remove_handle($queue, $done['handle']);  
  
                //关闭某个批处理句柄会话  
                curl_close($done['handle']);  
            }  
  
            if ($active > 0) {  
                //等待所有cURL批处理中的活动连接  
                curl_multi_select($queue, 0.5);  
            }  
  
        } while ($active);  
  
        //关闭一组cURL句柄  
        curl_multi_close($queue);  
  
        //返回结果  
        return $responses;  
    }  
      
    /** 
     * curl 单句柄请求 
     * @param type $method 
     * @param type $args 
     * @return type 
     */  
    private function execCurl($method, $args)  
    {  
        //解析参数  
        $url       = isset($args[0])            ? $args[0]            : "";  
        $multi     = isset($args[1]['multi'])   ? $args[1]['multi']   : "";  
        $data      = isset($args[1]['data'])    ? $args[1]['data']    : "";  
        $ajax      = isset($args[1]['ajax'])    ? $args[1]['ajax']    : "";  
        $timeout   = isset($args[1]['timeout']) ? $args[1]['timeout'] : 30;  
        $files     = isset($args[1]['files'])   ? $args[1]['files']   : "";  
        $referer   = isset($args[1]['referer']) ? $args[1]['referer'] : "";  
        $proxy     = isset($args[1]['proxy'])   ? $args[1]['proxy']   : "";  
        $headers   = isset($args[1]['headers']) ? $args[1]['headers'] : "";  
          
        //如果环境变量的浏览器信息不存在,就是用手动设置的浏览器信息  
        $userAgent = isset($_SERVER['HTTP_USER_AGENT'])?  
            $_SERVER['HTTP_USER_AGENT']:  
                'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:23.0)   
                    Gecko/20100101 Firefox/23.0';  
          
        //检测url必须参数 不能为空  
        if (!$url) {  
            throw new curlException("错误:curl请求地址不能为空");  
        }  
          
        //设置curl选项  
        $options = array(  
                        CURLOPT_URL            => $url,      //目标url  
                        CURLOPT_TIMEOUT        => $timeout,  //超时  
                        CURLOPT_RETURNTRANSFER => 1,         //输出数据流  
                        CURLOPT_FOLLOWLOCATION => 1,         //自动跳转追踪  
                        CURLOPT_AUTOREFERER    => 1,         //自动设置来路信息  
                        CURLOPT_SSL_VERIFYPEER => 0,         //认证证书检查  
                        CURLOPT_SSL_VERIFYHOST => 0,         //检查SSL加密算法  
                        CURLOPT_HEADER         => 0,         //禁止头文件输出  
                        CURLOPT_NOSIGNAL       => 1,         //忽略所有传递的信号  
                        CURLOPT_USERAGENT      => $userAgent,//浏览器环境字符串  
                        CURLOPT_IPRESOLVE      => CURL_IPRESOLVE_V4, //ipv4寻址方式  
                        CURLOPT_ENCODING       => 'gzip',    //解析使用gzip压缩的网页      
                   );    
          
        //获取cookie文件地址路径  
        if(!$this->cookieFile) {  
            $this->cookieFile = isset($args[1]['cookie_file'])   
                    ? $args[1]['cookie_file'] : "";  
        }  
          
        //设置代理 必须是数组并且非空  
        if (is_array($proxy) && !empty($proxy)) {     
            $options[CURLOPT_PROXY]        = $proxy['host'];  
            $options[CURLOPT_PROXYPORT]    = $proxy['port'];     
            $options[CURLOPT_PROXYUSERPWD] =   
                                        $proxy['user'] . ':' . $proxy['pass'];  
        }  
          
        //检测是否未启用自定义urlencode编码  
        if (!isset($args[1]['build'])) {   
            if ($data && $method == "post" && is_array($data)) {  
                $data = http_build_query($data, '', '&');  
            }  
        }  
          
        //检测是否含有上传文件  
        if ($files && $method == "post" && is_array($files)) {  
            foreach ($files as $k => $v) {  
                $files[$k] = '@' . $v;  
            }  
  
            parse_str($data, $data);  
            $data = $data + $files;  
        }  
          
        //检测判断是否是post请求  
        if ($method == 'post') {  
            //发送一个常规的POST请求  
            $options[CURLOPT_POST]       = 1;   
              
            //使用HTTP协议中的"POST"操作来发送数据,支持键值对数组定义  
            $options[CURLOPT_POSTFIELDS] = $data;   
        }  
          
        //初始化header数组  
        $headerOptions = array();  
          
        //检测是否是ajax提交  
        if ($ajax) {  
            $headerOptions['X-Requested-With']  = 'XMLHttpRequest';  
        }  
          
         
        //设置cookie  
        if ($this->cookieFile) {  
            $options[CURLOPT_COOKIEFILE] = $this->cookieFile;  
            $options[CURLOPT_COOKIEJAR]  = $this->cookieFile;  
        }  
  
        //设置来路  
        if ($referer) {  
            $options[CURLOPT_REFERER] = $referer;  
        }  
          
        //合并header  
        if (!empty($headers) && is_array($headers)) {  
            foreach ($headers as $k => $v) {  
                $headerOptions[$k] = $v;  
            }  
        }  
          
        //转换header选项为浏览器header格式  
        if (!empty($headerOptions) && is_array($headerOptions)) {  
            $array = array();  
              
            foreach($headerOptions as $k => $v) {  
                $array[] = $k . ": " . $v;  
            }  
              
            $options[CURLOPT_HTTPHEADER] = $array;  
        }  
          
        //创建curl句柄  
        $ch = curl_init();  
          
        //设置curl选项  
        curl_setopt_array($ch, $options);  
          
        //获取返回内容  
        $content = curl_exec($ch);  
          
        //关闭curl句柄  
        curl_close($ch);  
          
        //返回内容  
        return $content;  
  
    }  
      
    /** 
     * 对一个对象进行字符串echo输出 
     * 自动调用__toString方法 
     * @return type 
     */  
    public function __toString()  
    {  
        return $this->body();  
    }  
      
}  
  
class curlException extends Exception {}  
  
//curl方法不存在就设置一个curl方法  
if (!function_exists('curl')) {  
    function curl() {  
        return curl::exec();  
    }  
}  

说明:

该类仅仅支持get请求和post请求,已经足够采集使用

支持批量采集!但是请慎用 CURL的批量采集去采集网页,

批量采集比较不稳定容易丢失数据包

批量采集用于处理程序内部接口的并发使用,偶尔代替一下多线程并发处理操作

如果使用请自行测试!

就目前来说,使用该类足以应付大部分的采集工作需求!无需其他工具

采集回来的网页使用正则处理即可


例子以a5站长网为例 抓去目标栏目中的所有列表

分析出a5科技栏目中总所有的文章总数 将文章列表存入到list.txt文件中

如若采集文章,就循环list.txt中的url地址,进行正则匹配采集文章内容


<?php  
//采集演示         
 set_time_limit(0);//永久运行  
        ob_clean();  
        $start = 1;  
        $end = 805;  
        $preg1 = '#<a href="([a-zA-Z0-9\/\:\.]+?)" class="sherry_title">([\S\s]+?)</a>#is';  
        for ($i=$start;$i<=$end;$i++) {  
            $arr = array();  
            $arc_list = $this->curl()->get("http://www.admin5.com/browse/177/list_{$i}.shtml")->body();  
            preg_match_all($preg1,$arc_list,$arr);  
            $text = "";  
            foreach($arr[1] as $k => $v) {  
                 $text .= "{$v}|||{$arr[2][$k]}\r\n";  
            }  
            $fp = fopen("d:/list.txt","a+");//存放到我的电脑d盘下中的list.txt文件 如测试此文件请换成自己的路径  
            fwrite($fp,$text);  
            fclose($fp);  
            ob_flush();  
            echo "第{$i}页列表抓取完成<br />";  
            flush();  
            usleep(500);  
        }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值