Darkweider
19.09.2007, 19:18
Вообщем столкнулся с такой проблемой, хочу быстрый парсер страниц написать. Как парсить страницы понял и разобрался... Проблема в том что через file_get_contents() все тормозно получается, слышал что можно параллельно информацию получать через сокеты, т.е. выполнять сразу несколько запросов в нескольким сайтам... Даже пример нашел, но не могу понять как переделать его=\ под парсер... Пожалуйста помогите разобраться уже который день думаю как переделать... Как работают незаблокориванные соксы не могу понять че-то... Пример, очень распространенный...
<?
// путь, где расположены скрипты
$path = "http://domain.com/path/";
// число потоков
$max_threads = 20;
// инициализация
$sockets = array();
$done = false;
// будем работать, к примеру с набором
// ключевых слов
$keywords = fopen("keywords.txt", 'r');
// приступаем к многопоточной работе
while (!$done)
{
// если обнаружен файл,
// то прекращаем выполнение скрипта
if (file_exists('stop-file'))
die;
// если число запущенных потоков меньше
// разрешенного максимума
// то запускаем потоки еще
if ($max_threads > count($sockets))
{
if (!feof($keywords))
{
$buffer = array();
// читаем ключевое слово
// в реальности в этот массив можно
// положить очень много всего
// а не только одно ключевое слово…
$buffer[] = trim(fgets($keywords));
// задаем данные для запуска сокета
// request.php - это тот файл,
// которые делает “дело”
$query_url = $path . 'request.php';
$url_info = parse_url($query_url);
$url_info[port] = ($url_info[port]) ? $url_info[port] : 80;
$url_info[path] = ($url_info[path]) ? $url_info[path] : “/”;
$url_info[query] = ($url_info[query]) ? “?” . $url_info[query] : “”;
// пакуем данные для передачи
// в генерирующий скрипт
// использование serialize очень удобно,
// так как позволяет
// залить в request.php мегабайты данных
$request = serialize($buffer);
// формируем запрос для передачи по сокету
$query = “POST ” . $url_info[path] . ” HTTP/1.1\r\n”;
$query = $query . “Content-Type: text/xml\r\n”;
$query = $query . “Host: ” . $url_info[host] . “\r\n”;
$query = $query . “Content-length: ” . (strlen($request)) . “\r\n\r\n”;
$query = $query . $request;
// создаем сокет, переводим его
// в неблокирующий режим и запускаем
// обработчик запросов
$errno = 0;
$error = “”;
$socket = fsockopen($url_info[host], $url_info[port], $errno, $error, 30);
stream_set_blocking($socket, 0);
stream_set_timeout($socket, 3600);
fputs($socket, $query);
// запоминаем запущенный сокет
$sockets[md5(time())] = $socket;
}
}
// читаем данные из сокета. формально они нам
// не нужны, но это позволяет
// отработать обработчкику запросов
reset($sockets);
while ($socket = current($sockets))
{
if (feof($socket))
{
// убиваем сокет, который отработал
unset($sockets[key($sockets)]);
}
else
{
// читаем данные из сокета
$temp = fgets($socket, 1000);
}
// обрабатываем следующий сокет
next($sockets);
}
// делаем небольщую задержку,
// иначе загруженность сервера
// приближается к 100 процентам
sleep(1);
// если нет активных сокетов, то можно выходить
if (count($sockets) == 0)
$done = true;
}
fclose($keywords);
die;?>
<?
// путь, где расположены скрипты
$path = "http://domain.com/path/";
// число потоков
$max_threads = 20;
// инициализация
$sockets = array();
$done = false;
// будем работать, к примеру с набором
// ключевых слов
$keywords = fopen("keywords.txt", 'r');
// приступаем к многопоточной работе
while (!$done)
{
// если обнаружен файл,
// то прекращаем выполнение скрипта
if (file_exists('stop-file'))
die;
// если число запущенных потоков меньше
// разрешенного максимума
// то запускаем потоки еще
if ($max_threads > count($sockets))
{
if (!feof($keywords))
{
$buffer = array();
// читаем ключевое слово
// в реальности в этот массив можно
// положить очень много всего
// а не только одно ключевое слово…
$buffer[] = trim(fgets($keywords));
// задаем данные для запуска сокета
// request.php - это тот файл,
// которые делает “дело”
$query_url = $path . 'request.php';
$url_info = parse_url($query_url);
$url_info[port] = ($url_info[port]) ? $url_info[port] : 80;
$url_info[path] = ($url_info[path]) ? $url_info[path] : “/”;
$url_info[query] = ($url_info[query]) ? “?” . $url_info[query] : “”;
// пакуем данные для передачи
// в генерирующий скрипт
// использование serialize очень удобно,
// так как позволяет
// залить в request.php мегабайты данных
$request = serialize($buffer);
// формируем запрос для передачи по сокету
$query = “POST ” . $url_info[path] . ” HTTP/1.1\r\n”;
$query = $query . “Content-Type: text/xml\r\n”;
$query = $query . “Host: ” . $url_info[host] . “\r\n”;
$query = $query . “Content-length: ” . (strlen($request)) . “\r\n\r\n”;
$query = $query . $request;
// создаем сокет, переводим его
// в неблокирующий режим и запускаем
// обработчик запросов
$errno = 0;
$error = “”;
$socket = fsockopen($url_info[host], $url_info[port], $errno, $error, 30);
stream_set_blocking($socket, 0);
stream_set_timeout($socket, 3600);
fputs($socket, $query);
// запоминаем запущенный сокет
$sockets[md5(time())] = $socket;
}
}
// читаем данные из сокета. формально они нам
// не нужны, но это позволяет
// отработать обработчкику запросов
reset($sockets);
while ($socket = current($sockets))
{
if (feof($socket))
{
// убиваем сокет, который отработал
unset($sockets[key($sockets)]);
}
else
{
// читаем данные из сокета
$temp = fgets($socket, 1000);
}
// обрабатываем следующий сокет
next($sockets);
}
// делаем небольщую задержку,
// иначе загруженность сервера
// приближается к 100 процентам
sleep(1);
// если нет активных сокетов, то можно выходить
if (count($sockets) == 0)
$done = true;
}
fclose($keywords);
die;?>