问题描述
工作中需要curl一个链接,需要登录后才能返回关键字段。之前是直接curl,然后用保存后的cookie文件访问,但是每页只返回20条结果,而且太慢,每一次curl大概1s-1.3s,而且如果结果太多(最多50页),curl就会超时。
问题出现的环境背景及自己尝试过哪些方法
后面限制了页数,即如果返回页数大于5页只让其curl 5次,这样虽然不至于太慢了,但是结果也少了。后面了解了curl_multi ,自己也试了,如果不用cookie这个多进程确实快了很多,原来curl 25次 大概28秒,多进程之后大概2秒,但是一旦加上cookie访问,速度变得和普通curl一样了,甚至略慢一点。不知道是不是我哪里写的不对,附上代码
相关代码
// 请把代码文本粘贴到下方(请勿用图片代替代码)
这个是普通curl
if($arr0['pcount']>1){
$arr[0]['total']['pcount']=$arr[0]['total']['pcount']>10?10:$arr[0]['total']['pcount'];
for ($i=2;$i<=$arr[0]['total']['pcount'];$i++){
//带上cookie文件,访问
$send_url='http://******.cn/ashx/GetList.ashx?pageIndex='.$i.'&keys='.htmlspecialchars($tj).'&Lx=3';
$ch = curl_init($send_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
$contents[] = curl_exec($ch);
curl_close($ch);
}
$arr=array();
foreach($contents as $k=>$v){
$arr[$k]=(json_decode($v,true));
}
}
//这个是调用curl_multi的
if($arr[0]['total']['pcount']>1){
$chArr=[];
for($i=2;$i<=$arr[0]['total']['pcount'];$i++){
$chArr[$i] = "http://*****.cn/ashx/GetList.ashx?pageIndex=$i&keys=".htmlspecialchars($tj)."&Lx=3";
}
$result = $this->postMulti($chArr,$cookie);
$arr = array_merge($arr,$result);
}
//这个是curl_multi
public static function postMulti($chArr,$cookie)
{
$max_request = count($chArr);
$ch_list = array();
$multi_ch = curl_multi_init();
for ($i = 2;$i <= $max_request+1;$i++) {
$ch_list[$i] = curl_init($chArr[$i]);
curl_setopt($ch_list[$i], CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch_list[$i], CURLOPT_COOKIE,$cookie) ; //如果注释此行返回结果则很快
curl_setopt($ch_list[$i], CURLOPT_TIMEOUT, 30);
//curl_setopt($ch_list[$i], CURLOPT_COOKIEFILE, $cookie_file);
curl_multi_add_handle($multi_ch, $ch_list[$i]);
}
$active = null;
do {
$mrc = curl_multi_exec($multi_ch, $active); //处理在栈中的每一个句柄。无论该句柄需要读取或写入数据都可调用此方法。
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
//Note:
//该函数仅返回关于整个批处理栈相关的错误。即使返回 CURLM_OK 时单个传输仍可能有问题。
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($multi_ch) != -1) {
//阻塞直到cURL批处理连接中有活动连接。
do {
$mrc = curl_multi_exec($multi_ch, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
//获取http返回的结果
$true_request = 0;
foreach ($ch_list as $k => $ch) {
$result[] = curl_multi_getcontent($ch);
curl_multi_remove_handle($multi_ch,$ch);
curl_close($ch);
if ($result == 1) {
$true_request += 1;
}
}
curl_multi_close($multi_ch);
foreach($result as $k=>$v){
$arr[$k]=(json_decode($v,true));
}
return $arr;
}
开个脑洞: