[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: проблема с потоками curl
EJIqpEP
Добрый день. Когда паршу 50 ссылок из них нормально считывает 9. Остальные получают ошибку 503. Каким образом можно уменьшить скорость обработки ссылок. Или может быть проблема в чем то другом.
В файле pages.txt ссылки такого вида:
http://shkolazhizni.ru/archive/0/n-51320/
Код прилагается:
<?php
ini_set('memory_limit', '20000M');
set_time_limit(0);
error_reporting(E_ALL);
$dir = $_SERVER['DOCUMENT_ROOT']."/ejiqpep/partemp/papka_result/";
$ar = file("pages.txt");

foreach ($ar as $st) {
$urls[] = trim($st);
}
$mh = curl_multi_init();
// массив заданий для мультикурла
$tasks = array();
foreach ($urls as $url) {
// инициализируем отдельное соединение (поток)
$ch = curl_init($url);
// возвращать результат
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// не возвращать http-заголовок
curl_setopt($ch, CURLOPT_HEADER, 0);
// таймаут соединения
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
// таймаут ожидания
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
// добавляем дескриптор потока в массив заданий
$tasks[$url] = $ch;
// добавляем дескриптор потока в мультикурл
curl_multi_add_handle($mh, $ch);
}


// количество активных потоков
$active = null;
while( ($mrc = curl_multi_exec($mh, $running))==CURLM_CALL_MULTI_PERFORM ); //просто запускаем все соединения
while($running && ($mrc == CURLM_OK)){
if($running and curl_multi_select($mh)!=-1 ){
do{
$mrc = curl_multi_exec($mh, $running);
$info=curl_multi_info_read($mh);
// если поток завершился
if( $info and $info['msg'] == CURLMSG_DONE ){
$ch = $info['handle'];
$url = array_search($ch, $tasks);
$status=curl_getinfo($ch,CURLINFO_HTTP_CODE);
$tasks[$url]=curl_multi_getcontent($info['handle']);
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
}
while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
usleep(10000);
}
// закрываем мультикурл
curl_multi_close($mh);
$i = 1;
// print_r($tasks);
foreach($tasks as $key => $task){
$directory = $dir.$i.".html";
$f = fopen($directory,"w+");
if (fwrite($f,$task)) echo $key."<br>";
fclose($f);
$i++;
}
?>

делал по этому мануалу
http://job-interview.ru/articles/post/67



Спустя 39 минут, 26 секунд (4.01.2012 - 11:18) Nikitian написал(а):
Уменьшить количество одновременных попыток изнасилования сервера до эмпирически вычисленного значения стабильной работы.

Спустя 11 минут, 32 секунды (4.01.2012 - 11:29) EJIqpEP написал(а):
в этом куске где количеству ссылок создается нужное кол-во потоков?

foreach ($urls as $url) {
// инициализируем отдельное соединение (поток)
$ch = curl_init($url);
// возвращать результат
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// не возвращать http-заголовок
curl_setopt($ch, CURLOPT_HEADER, 0);
// таймаут соединения
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
// таймаут ожидания
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
// добавляем дескриптор потока в массив заданий
$tasks[$url] = $ch;
// добавляем дескриптор потока в мультикурл
curl_multi_add_handle($mh, $ch);
}

Спустя 35 минут, 53 секунды (4.01.2012 - 12:05) Nikitian написал(а):
Как-то так. Не проверял.

<?php
ini_set('memory_limit', '20000M');
set_time_limit(0);
$maxonce = 5;//Максимум одновременных
error_reporting(E_ALL);
$dir = $_SERVER['DOCUMENT_ROOT']."/ejiqpep/partemp/papka_result/";
$ar = file("pages.txt");

foreach ($ar as $st) {
$urls[] = trim($st);
}
while(sizeof($urls)>0){
$mh = curl_multi_init();
// массив заданий для мультикурла
$tasks = array();
$i=0;
foreach ($urls as $k=>$url) {
$i++;
if($i>$maxonce){
continue;
}
// инициализируем отдельное соединение (поток)
$ch = curl_init($url);
// возвращать результат
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// не возвращать http-заголовок
curl_setopt($ch, CURLOPT_HEADER, 0);
// таймаут соединения
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
// таймаут ожидания
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
// добавляем дескриптор потока в массив заданий
$tasks[$url] = $ch;
// добавляем дескриптор потока в мультикурл
curl_multi_add_handle($mh, $ch);
unset($urls[$k]);
}


// количество активных потоков
$active = null;
while( ($mrc = curl_multi_exec($mh, $running))==CURLM_CALL_MULTI_PERFORM ); //просто запускаем все соединения
while($running && ($mrc == CURLM_OK)){
if($running and curl_multi_select($mh)!=-1 ){
do{
$mrc = curl_multi_exec($mh, $running);
$info=curl_multi_info_read($mh);
// если поток завершился
if( $info and $info['msg'] == CURLMSG_DONE ){
$ch = $info['handle'];
$url = array_search($ch, $tasks);
$status=curl_getinfo($ch,CURLINFO_HTTP_CODE);
$tasks[$url]=curl_multi_getcontent($info['handle']);
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
}
while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
usleep(10000);
}
// закрываем мультикурл
curl_multi_close($mh);
$i = 1;
// print_r($tasks);
foreach($tasks as $key => $task){
$directory = $dir.$i.".html";
$f = fopen($directory,"w+");
if (fwrite($f,$task)) echo $key."<br>";
fclose($f);
$i++;
}
}

?>

Спустя 40 минут, 50 секунд (4.01.2012 - 12:46) EJIqpEP написал(а):
Спасибо огромное за потраченное время, но при тесте на 20 ссылках, когда ставлю 20 2-5 потоков получает только содержимое около 5 ссылок. когда 20 потоков, то получает все ссылки. не могу уловить взаимосвязи как сделать так, чтобы получить контент всех ссылок.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.