$mh = curl_multi_init(); // 开启多线程 $i = 0;
foreach($url_array as $url) {
$ch = curl_init();
if (IS_PROXY) {
curl_setopt ($ch, CURLOPT_PROXY,'67.215.228.129:8089' );//60.12.226.18
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don't print
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置超时时间
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
curl_setopt($ch, CURLOPT_MAXREDIRS, 7); //HTTp定向级别
curl_multi_add_handle($mh, $ch); // 把 curl resource 放进 multi curl handler 里
$handle[$i++] = $ch;
}代码如上,开启多线程抓取数据;假如我一次加入10个url,返回给我的是一个有10个结果的数组。我不能判断这些数据分别是来自哪个url的。
请问有什么办法,还是其他哪种语言能实现,多线程抓取的数据还知道来自哪个url的。
foreach($url_array as $url) {
$ch = curl_init();
if (IS_PROXY) {
curl_setopt ($ch, CURLOPT_PROXY,'67.215.228.129:8089' );//60.12.226.18
}
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don't print
curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置超时时间
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
curl_setopt($ch, CURLOPT_MAXREDIRS, 7); //HTTp定向级别
curl_multi_add_handle($mh, $ch); // 把 curl resource 放进 multi curl handler 里
$handle[$i++] = $ch;
}代码如上,开启多线程抓取数据;假如我一次加入10个url,返回给我的是一个有10个结果的数组。我不能判断这些数据分别是来自哪个url的。
请问有什么办法,还是其他哪种语言能实现,多线程抓取的数据还知道来自哪个url的。
大致是这样的一些(你也可以只读取你感兴趣的部分) [url] => http://blog.51edm.org/content/uploadfile/201303/dc7f1364286796.zip
[content_type] => application/zip
[http_code] => 206
[header_size] => 313
[request_size] => 221
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.047
[namelookup_time] => 0
[connect_time] => 0.047
[pretransfer_time] => 0.047
[size_upload] => 0
[size_download] => 201
[speed_download] => 0
[speed_upload] => 0
[download_content_length] => 201
[upload_content_length] => 0
[starttransfer_time] => 0.078
[redirect_time] => 0
[certinfo] => Array
(
) [primary_ip] => 119.37.197.49
[primary_port] => 80
[local_ip] => 114.106.252.117
[local_port] => 2128
[redirect_url] =>
你还可以用 CURLOPT_FILE 设置每个 curl 的输出文件,让其自动写盘,而无需让读取的数据占用 php 的内存(虽然是短时的)
// 死链么?
if (!$chinfo['http_code']) {
$handle = fopen(LOGDEAD.date('ymdHi').'_dead_urls.txt', 'a');
fwrite($handle, $chinfo['url']."\r\n");
fclose($handle);
echo 'dead';
// 404了?
} else if ($chinfo['http_code'] == 404) {
$handle1 = fopen(LOG404.date('ymdHi').'_404_urls.txt', 'a');
fwrite($handle1, $chinfo['url']."\r\n");
fclose($handle1);
echo '404';
} else if ($chinfo['http_code'] == 500) {
$handle2 = fopen(LOG500.date('ymdHi').'_500_urls.txt', 'a');
fwrite($handle2, $chinfo['url']."\r\n");
fclose($handle2);
echo '404';
// 还能用
} else {
$suc_urls []= $chinfo['url'];
//echo $chinfo['url']; //将sucurl存入表
}我使用了您说这部分,但要求是将url与返回来的数据一一对应,
要实现:
第一次取回信息,分析页面流,再提取里面一个参数,比如total,将这个参数带入刚才那个url再取数据,才是最终要的。
感觉在PHP的多线程里几乎没有办法实现,所以来寻求新出路,万一不行,就只能使用单线程了。
你不是有 $handle[$i++] = $ch; 吗?
那 $handle 中的每一个成员不都对应一个 curl 实例吗?
你没给其他的代码,也不知你写的对不对。给个示例代码供参考$connomains = array(
"http://www.cnn.com/",
"http://www.canada.com/",
"http://www.yahoo.com/"
);
$mh = curl_multi_init();//初始各个 curl
foreach ($connomains as $i => $url) {
$conn[$i]=curl_init($url);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);
curl_multi_add_handle ($mh,$conn[$i]);
}
//等待全部完成
do { $n=curl_multi_exec($mh,$active); } while ($active);
//逐一取回数据
foreach ($connomains as $i => $url) {
$res[$i]=curl_multi_getcontent($conn[$i]);
curl_close($conn[$i]);
}
print_r($res); //看一下结果
<?php$connomains = array();for( $i = 0; $i < 1000; $i++ ) {
$connomains[] = "http://www.baidu.com/";
}$st = microtime( true ); /*
$mh = curl_multi_init();//初始各个 curl
foreach ($connomains as $i => $url) {
$conn[$i]=curl_init($url);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);
curl_multi_add_handle ($mh,$conn[$i]);
}
//等待全部完成
do {
$n=curl_multi_exec($mh,$active);
} while ($active);
//逐一取回数据
foreach ($connomains as $i => $url) {
// $res[$i]=curl_multi_getcontent($conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
// print_r($res); //看一下结果
*/foreach( $connomains as $url ) {
$data = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,Chrome/21.0.1180.79 Safari/537.1",
);
curl_get_contents($data);
}$ed = microtime( true );
echo $ed - $st;
function curl_get_contents($s){
$ci = curl_init();
curl_setopt_array($ci,$s);
$r = curl_exec($ci);
curl_close($ci);
return $r;
};
exit();
?>感觉多线程比单线程没想象中快很多,但是cpu使用率高了很多倍。不知有没有什么地方可以优化的?