HTTP status checker

Статус
В этой теме нельзя размещать новые ответы.

terkin

Мой дом здесь!
Регистрация
9 Дек 2006
Сообщения
513
Реакции
200
Мультипоточный чекер ссылок на PHP и Curl, вроде как всё правильно сделано, но беспокоит одна вещ, часто где код ответа должен быть 200 мне возвращает 0 или 503, я так понимаю - это из-за того что скрипт шлёт слишком быстро запросы серверу. Но вот в руководстве по курлу я так и не смог найти как выставить задержку при многопоточных запросах, поэтому прошу помощи, кто сможет доделать

PHP:
<?php
 // $ma - массив с нашими урлами с http://
  $mh = curl_multi_init();
  $handles = array();

  for($i=0;$i<count($ma);$i++)
  {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $ma[$i]);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_multi_add_handle($mh,$ch);
    $handles[] = $ch;
  }
  $running=null;
  do
  {
    curl_multi_exec($mh,$running);
  } while ($running > 0);

  for($i=0;$i<count($handles);$i++)
  {
    $output.=$ma[$i].' '.curl_getinfo($handles[$i], CURLINFO_HTTP_CODE).'<br />';
    curl_multi_remove_handle($mh,$handles[$i]);
  }
  echo $output;
  curl_multi_close($mh);


?>
 
В твоем случае использование именно CURL критично? Можно ведь решить проблему н****кирующими сокетами.
 
В моём случае любой способ хорош лижбы работал, ну и в несколько потоков, так как линков чекать нужно много
 
1. н****кирующие сокеты на порядок усложнят задачу. По большому счету придется с нуля тот самый cURL и написать.

2. в сURL нет настроек для задания периода (интервала) отправки запросов при режиме multi-thread

3. Для запроса HEAD оптимальнее использовать самодельный веб-клиент на обычных блокирующих сокетах (fsockopen,...)

4. Распараллелить задачу можно не только через потоки, но и через процессы. А именно: один скрипт берет на вход список урлов, делит их на N порций, раскладывает по файлам или в таблицу с N идентификаторами и запускает N процессов, каждый из которых является однопотоковым веб-клиентом-чекером и проверяет свою порцию урлов. Результаты аналогично складываются в N файлов или в ту же базу, а затем объединяются.

UPD: прошу прощения за вопрос, но почему именно php? :)
 
По поводу сокетов:
PHP:
<?php
function multi_get ($urlArr, $timeout = 5, $sleep = 0) {
	$sockets = Array();
	$urlInfo = Array();
	$retDone = Array();
	$retData = Array();
	$errno = Array();
	$errstr = Array();
	for ($x=0;$x<count($urlArr);$x++) {
		$urlInfo[$x] = parse_url($urlArr[$x]);
		$getstr = ($urlInfo[$x][path] ? $urlInfo[$x][path] : '/').($urlInfo[$x][query] ? '?'.$urlInfo[$x][query] : '');
		do {
        	$sockets[$x] = fsockopen($urlInfo[$x][host], 80, $errno[$x], $errstr[$x], $timeout);
		} while (!$sockets[$x]);
		socket_set_blocking($sockets[$x],FALSE);
        $HEAD = "HEAD ".$urlInfo[$x][path]."$getstr HTTP/1.0\r\n";
    	$HEAD.= "Host: ".$urlInfo[$x][host]."\r\n";
    	$HEAD.= "\r\n";
		fputs($sockets[$x], $HEAD);
        sleep($sleep);
	}
	while (!$done) {
		for ($x=0; $x < count($urlArr);$x++) {
			if (!feof($sockets[$x])) {
				if ($retData[$x]) {
					$retData[$x] .= fread($sockets[$x], 8192);
				} else {
					$retData[$x] = fread($sockets[$x], 8192);
				}
			} else {
				$retDone[$x] = 1;
			}
		}
		$done = (array_sum($retDone) == count($urlArr));
	}
	return $retData;
}

// $url массив с урлами

$retData = multi_get($url);

foreach ($retData as $key => $fe){
    preg_match("/[0-9]{3}/", substr($fe, 0, 20), $pm);
	$output .= $url[$key].' '.$pm[0].'<br>';
}
echo $output
?>

Кстати, как заметил gregzem, запрос HEAD занимает доли секунды. Так что, если не нужен весь ответ сервера, то простой цикл с обычными сокетами и небольшим таймаутом вполне подойдет.
 
друзья - perl + lwp::useragent = очень простая реализация порой сложных задач.
там ещё mech есть, который умеет совсем под браузер косить, но это уже для задач типа сабмита.
(сейчас меня как пнут за perl :nezn: )
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху