php多线程采集网页的解决办法 curl多线程采集

既然为了学习,那么先来了解下PHP curl函数信息:php

PHP cURL全部函数列表:https://secure.php.net/manual/zh/ref.curl.phphtml

如下是PHP中cURL多线程相关函数:

  • curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄
  • curl_multi_close — 关闭一组cURL句柄
  • curl_multi_exec — 运行当前 cURL 句柄的子链接
  • curl_multi_getcontent — 若是设置了CURLOPT_RETURNTRANSFER,则返回获取的输出的文本流
  • curl_multi_info_read — 获取当前解析的cURL的相关传输信息
  • curl_multi_init — 返回一个新cURL批处理句柄
  • curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源
  • curl_multi_select — 等待全部cURL批处理中的活动链接
  • curl_multi_setopt — 为 cURL 并行处理设置一个选项
  • curl_multi_strerror — Return string describing error code

通常来讲,想到要用这些函数时,目的显然应该是要同时请求多个URL,而不是一个一个依次请求,不然不如本身循环去调curl_exec好了。算法

步骤总结以下:

一、调用 curl_multi_init,初始化一个批处理handle数组

二、循环调用 curl_multi_add_handle,往1中的批处理handle 添加curl_init来的子handle多线程

三、持续调用 curl_multi_exec,直到全部子handle执行完毕。curl

四、根据须要循环调用 curl_multi_getcontent 获取结果ide

五、调用 curl_multi_remove_handle,并为每一个字handle调用curl_close函数

六、调用 curl_multi_closepost

好了,直接上函数(输入参数为url数组,返回结果为对应的网页源码数组)学习

function curl_multi($urls) {
        if (!is_array($urls) or count($urls) == 0) {
            return false;
        }
        $num=count($urls);
        $curl = $curl2 = $text = array();
        $handle = curl_multi_init();
        function createCh($url) {
            $ch = curl_init();
            curl_setopt ($ch, CURLOPT_URL, $url);
            curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko');//设置头部
            curl_setopt ($ch, CURLOPT_REFERER, $url); //设置来源
            curl_setopt ($ch, CURLOPT_ENCODING, "gzip"); // 编码压缩
            curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);//是否采集30一、302以后的页面
            curl_setopt ($ch, CURLOPT_MAXREDIRS, 5);//查找次数,防止查找太深
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在
            curl_setopt ($ch, CURLOPT_TIMEOUT, 20);
            curl_setopt ($ch, CURLOPT_HEADER, 0);//输出头部
            return $ch;
        }
        foreach($urls as $k=>$v){
            $url=$urls[$k];
            $curl[$k] = createCh($url);
            curl_multi_add_handle ($handle,$curl[$k]);
        }
        $active = null;
        do {
            $mrc = curl_multi_exec($handle, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
 
        while ($active && $mrc == CURLM_OK) {
            if (curl_multi_select($handle) != -1) {
                usleep(100);
            }
            do {
                $mrc = curl_multi_exec($handle, $active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
 
        foreach ($curl as $k => $v) {
            if (curl_error($curl[$k]) == "") {
                $text[$k] = (string) curl_multi_getcontent($curl[$k]);
            }
            curl_multi_remove_handle($handle, $curl[$k]);
            curl_close($curl[$k]);
        }
        curl_multi_close($handle);
        return $text;
    }

调取测试
 

$urls = [];
for($i=1;$i<=46;$i++){
	$url ="https://www.xx.com/play/61804-1-$i.html";
	$urls[$i]= $url;
}

$res=curl_multi($urls);
print_r($res);

速度提高了很多

相关文章
相关标签/搜索