[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Парсинг новостей
Игорь_Vasinsky
Вообщем вместо cUrl я использую file_get_contents

1. Получаю xml
2. Достаю все заголовки
3. Достаю ссылки на полные новости в массив
4. Перебираю через foreach, и там же работаю preg_match_all - чтобы вытащить в цикле все тексты новостей из общего контента.

По отдельности бегает, а вот когда п.4 ес-но
Fatal error: Maximum execution time of 60 seconds exceeded

Вроде логичный алгоритм, но такая беда.

Или есть вариант по оптимальней?



Спустя 25 минут, 52 секунды (20.09.2011 - 18:18) caballero написал(а):
установи тайм аут в php побольше
а что иначче можно посоветовать не видя файла
или покури в сторону xpath может можно выгрести все сразу

Спустя 2 минуты, 52 секунды (20.09.2011 - 18:21) Игорь_Vasinsky написал(а):
да не xml парсится шустро, а вот в цикле по линкам бегать и регуляркой шарить - вот тут таймаут.

Спустя 12 минут, 27 секунд (20.09.2011 - 18:33) Игорь_Vasinsky написал(а):
таймаут не дадут на хосте менять.

Спустя 3 минуты, 15 секунд (20.09.2011 - 18:36) Игорь_Vasinsky написал(а):
так.. а если в буфер получить страницу ?? это повлияет на скорость?

Спустя 6 минут, 41 секунда (20.09.2011 - 18:43) Winston написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 18:36)
так.. а если в буфер получить страницу ?? это повлияет на скорость?

Должно немного быстрее быть. Но лучше покажи код.

Спустя 6 минут, 17 секунд (20.09.2011 - 18:49) Игорь_Vasinsky написал(а):
в коде много всего лишнего, объяснять долго - меня сам алгоритм волнует.

1.foreach
После того как я получаю ссылки на полные новости - я забиваю новый массив (страницами через file_get_contents())

2. foreach
Прохожу по массиву preg_match_all - забиваю новый массив "чистыми новостями"


Так вот 1й foreach - проходит, а дальше не успевает... новостей то шт 30

Думал while, попробую - по статистике foreach вроде быстрее

Так же смотрел - sleep() установить после первого foreach - да чё то не логично - время работы скрипта увеличу только.

С буфером..... сомнительно.

Может кто писал такой граббер?

Спустя 3 минуты, 18 секунд (20.09.2011 - 18:53) Winston написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 18:49)
Так вот 1й foreach - проходит

Можно вместо foreach попробовать сделать array_map + create_function();
Возможно будет какой-то выигрыш.

Спустя 2 минуты, 17 секунд (20.09.2011 - 18:55) neadekvat написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 19:33)
таймаут не дадут на хосте менять.

Ошибка разве не к директиве time_limit (ф-я устаовки set_time_limit) относится? Ставишь в 0 и усе.

Спустя 2 минуты, 31 секунда (20.09.2011 - 18:57) alex12060 написал(а):
neadekvat

На многих хостингах эта функция заблокирована smile.gif

Спустя 6 минут, 53 секунды (20.09.2011 - 19:04) Игорь_Vasinsky написал(а):
Буфер не помог.

php_value set_time_limit 0 в htaccess
biggrin.gif не реагирует



ini_set("max_execution_time", "0"); в начале кода - пока жду... шуршит...



Спустя 6 минут, 38 секунд (20.09.2011 - 19:11) Игорь_Vasinsky написал(а):
ща ещё хочу попробовать разделить парсер xml и дальнейший парсинг ссылок из него на 2 скрипта..

Спустя 1 минута, 31 секунда (20.09.2011 - 19:13) Winston написал(а):
Вверху скрипта напиши
set_time_limit(0);

Спустя 31 секунда (20.09.2011 - 19:13) Игорь_Vasinsky написал(а):
))))) 3 минуты шуршал.... а я забыл вывод включить... и не знаю забился массив или нет biggrin.gif дубль 2

Спустя 8 минут, 38 секунд (20.09.2011 - 19:22) neadekvat написал(а):
Цитата (alex12060 @ 20.09.2011 - 19:57)
На многих хостингах эта функция заблокирована

Порой у меня возникает чувство, что люди выбирают хостинг по списку заблокированных функций (чем больше - тем лучше), а не по количеству разрешенных действий и доступных дополнительных (не php) функций.
Это закрыто, то закрыто... Да найдите один, где все это можно - это _базис_, создаете сами себе проблемы и потом улюлюкаете - ой, а у нас так нельзя, давайте другой вариант мне. Ичо?

PS Алекс, это не к тебе лично. Так. В космос.

Игорь_Vasinsky, перепробовал все варианты, а прочитать то, что я написла в скобках - это уже сложно оказалось?

Спустя 4 минуты, 30 секунд (20.09.2011 - 19:26) Игорь_Vasinsky написал(а):
таймаут я снял, спасиб... я щас пробую найти решение как сократить время работы скрипта.

Спустя 10 минут, 39 секунд (20.09.2011 - 19:37) Winston написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 17:52)
Вообщем вместо cUrl я использую file_get_contents

А вместо file_get_contents попробуй
simplexml_load_file('http://адрес');

Он уж точно быстрее будет чем file_get_contents + preg_match_all

Спустя 13 минут, 14 секунд (20.09.2011 - 19:50) Игорь_Vasinsky написал(а):
XML - я один раз прошу и быстро его получаю, у меня затраты времени на получение страниц с полными новостями в foreach + preg_match_all

Спустя 3 минуты, 37 секунд (20.09.2011 - 19:54) twin написал(а):
sleep() помоему не учитывается во времени на таймоут.

Спустя 43 секунды (20.09.2011 - 19:54) Игорь_Vasinsky написал(а):
Да.. я уже уточнил.

вот другой вопрос:

//$pages - массив с сырым контентом страниц
$content_found = array();
$all = array();

foreach($pages as $page)
{
preg_match_all($pattern, $page, $content_found[], PREG_PATTERN_ORDER);
}


этот пример сделает $page подмассивов $content_found в $all ? т.е. слишком мудрёно вложженые массивы у меня будут?

как обойти этот момент?

Спустя 7 минут, 56 секунд (20.09.2011 - 20:02) twin написал(а):
Я не понял, новости в формате XML? Если так, зачем мудрить, есть же штатные средства для его разбора...

Спустя 6 минут, 35 секунд (20.09.2011 - 20:09) Игорь_Vasinsky написал(а):
в том то и дело в xml - тока ссылки на полные новости, а они в контексте самого сайта.

Спустя 3 минуты, 6 секунд (20.09.2011 - 20:12) Игорь_Vasinsky написал(а):
да блин.. а где мои согруппники то?

Спустя 19 минут, 18 секунд (20.09.2011 - 20:31) Winston написал(а):
Игорь_Vasinsky
Дай адрес XML с ссылками.

Спустя 1 минута, 23 секунды (20.09.2011 - 20:33) Игорь_Vasinsky написал(а):
Вообще я пишу универсальный
но вот хотяб по этой


http://www.liga.net/lenta/export/RSS/all.xml

Спустя 3 минуты, 28 секунд (20.09.2011 - 20:36) Игорь_Vasinsky написал(а):
что то мне кажется что провайдер - по головке не погладит за такой скрипт

30 новостных страниц - 3,5-4 минуты.

Спустя 13 минут, 15 секунд (20.09.2011 - 20:49) Winston написал(а):
Игорь_Vasinsky
Сейчас, пойду перекушу, и попробую оптимизировать, чтобы быстрее работало.. smile.gif

Спустя 1 минута, 1 секунда (20.09.2011 - 20:50) Игорь_Vasinsky написал(а):
ну если время есть - то спасиб, приятного.

Спустя 26 минут, 36 секунд (20.09.2011 - 21:17) killer8080 написал(а):
Игорь_Vasinsky
а как тебе такой вариант, разбиваешь задачу на два скрипта.
script1.php

// парсим xml, получаем все ссылки в массив $links
...
// перебираем ссылки и формируем пост запросы ко второму скрипту.
foreach($links as $link){
$post = 'job='.urlencode($link);
$req = 'POST /script2.php HTTP/1.0'."\r\n".
'Host:'.$_SERVER['HTTP_HOST']."\r\n".
'Content-Length:'.strlen($post)."\r\n".
"\r\n".
$post;
$f = fsockopen('127.0.0.1', 80);
if($f){
fwrite($f, $req);
fclose($f);
}
}

script2.php
// получаем контент одной страницы запрошенной из первого скрипта
$content = file_get_contents($_POST['job']);
preg_match('regexp', $content, $match);
// парсим и сохраняем результат

Таким способом ты не только обойдёшь ограничение по времени, но и ускоришь процесс распараллеливанием, эмуляцией многопоточности.

Спустя 7 минут, 5 секунд (20.09.2011 - 21:24) Игорь_Vasinsky написал(а):
ну я планировал распределить на 2 скрипта, а твой пример вообще не понял
Цитата
foreach($links as $link){
$post = 'job='.urlencode($link);
$req = 'POST /script2.php HTTP/1.0'."\r\n".
        'Host:'.$_SERVER['HTTP_HOST']."\r\n".
    'Content-Length:'.strlen($post)."\r\n".
    "\r\n".
    $post;
$f = fsockopen('127.0.0.1', 80);
if($f){
  fwrite($f, $req);
  fclose($f);
}
}

Спустя 5 минут, 6 секунд (20.09.2011 - 21:29) killer8080 написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 21:24)
ну я планировал распределить на 2 скрипта, а твой пример вообще не понял

В моём примере первый скрипт просто раздаёт задания другим экземплярам script2.php параллельно, не тратя время на ожидание результата их работы. То есть асинхронно.

Спустя 3 минуты, 19 секунд (20.09.2011 - 21:33) killer8080 написал(а):
Возможно в цикле через n-ное число итераций нужно поставить задержку, чтоб не перегружать сервак.

Спустя 40 секунд (20.09.2011 - 21:33) Игорь_Vasinsky написал(а):
я даже и не думал о такой реализации, ща попробую разобраться.

Спустя 1 минута, 27 секунд (20.09.2011 - 21:35) killer8080 написал(а):
в принципе второй скрипт можно было бы запускать не через http, а командной строкой, но не на всех хостингах оно позволено.

Спустя 31 секунда (20.09.2011 - 21:35) Winston написал(а):
Вот мой, так нужно? Посмотри.
Свернутый текст

$start = microtime(true);
$xml = simplexml_load_file('http://www.liga.net/lenta/export/RSS/all.xml');

ob_start();
$links = '';
foreach($xml -> channel -> item AS $item)
$links .= '|' . $item -> link;


$links = array_diff(explode('|', $links), Array(''));
$page = array_map(create_function('$item', 'return file_get_contents($item);'), $links);
$content = array_map(create_function('$item', 'preg_match("#<span class=\"content\">(.*)</span>#isuU", $item, $matches); return $matches[1];'), $page);
$content = array_map(create_function('$item', 'return strip_tags($item);'), $content);

echo '<pre>'.htmlspecialchars(print_r($content, 1)).'</pre>';

$html = ob_get_contents();
ob_end_clean();

$end = microtime(true);
echo $html;

echo '<br/>' . ($end - $start);

PS: исполняется за 12-13 с.



Спустя 6 минут, 29 секунд Winston написал(а):
UDP
Подправил, уже 3-5 с smile.gif

Спустя 11 минут, 14 секунд (20.09.2011 - 21:46) Игорь_Vasinsky написал(а):
Winston
ты где тестил? на денвере нехватка времени.

Спустя 53 секунды (20.09.2011 - 21:47) killer8080 написал(а):
Цитата (Winston @ 20.09.2011 - 21:35)
PS: исполняется за 12-13 с.

у меня он отработал за 52 секунды.
Цитата (Winston @ 20.09.2011 - 21:35)
UDP
Подправил, уже 3-5 с

а это за 41 с
Каков будет результат на хостинге трудно предугадать, к тому же он во многом зависит от сторонних сайтов. smile.gif

Спустя 20 секунд (20.09.2011 - 21:48) Winston написал(а):
Игорь_Vasinsky
Цитата (Игорь_Vasinsky @ 20.09.2011 - 21:46)
ты где тестил? на денвере нехватка времени

Хм... У меня denwer на win7, браузер хром, за 3-5 с отрабатывается....

Спустя 1 минута, 31 секунда (20.09.2011 - 21:49) killer8080 написал(а):
Winston
Думаю от браузера тут мало что зависит smile.gif

Спустя 1 минута, 7 секунд (20.09.2011 - 21:50) Игорь_Vasinsky написал(а):
Winston
аналогичная сборка, прям 1 в 1

результат 104.334271193с

но выдача есть wink.gif

спасиб.

это всё array_map() ?

Спустя 1 минута, 59 секунд (20.09.2011 - 21:52) Winston написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 21:50)
результат 104.334271193с

blink.gif Ого

Спустя 1 минута, 26 секунд (20.09.2011 - 21:54) Игорь_Vasinsky написал(а):
счас 85.3663239479 - это поход от сайта зависит.

Спустя 1 минута, 3 секунды (20.09.2011 - 21:55) Winston написал(а):
Цитата (Игорь_Vasinsky @ 20.09.2011 - 21:54)
это поход от сайта зависит

Мне тоже так кажется, уже у меня 10с huh.gif

Спустя 1 минута, 30 секунд (20.09.2011 - 21:56) Игорь_Vasinsky написал(а):
Лан. огромное спасибо. открыл для себя новую схему. wink.gif

Спустя 39 минут, 45 секунд (20.09.2011 - 22:36) killer8080 написал(а):
Вот рабочий вариант
script1.php
Свернутый текст
$t = microtime(1);
$path = substr(str_replace("\\", '/', dirname(__FILE__)).'/', strlen($_SERVER['DOCUMENT_ROOT']));

$xml = simplexml_load_file('http://www.liga.net/lenta/export/RSS/all.xml');


$links = array();
foreach($xml -> channel -> item AS $item)
$links[] = $item -> link;


$links = array_filter($links);

$i = 0;
foreach($links as $link){
$post = 'job='.urlencode($link).'&n='.++$i;
$req = 'POST '.$path.'script2.php HTTP/1.0'."\r\n".
'Host:'.$_SERVER['HTTP_HOST']."\r\n".
'Content-Length:'.strlen($post)."\r\n".
'Content-Type:application/x-www-form-urlencoded'."\r\n".
"\r\n".
$post;
$f = fsockopen('127.0.0.1', 80);
if($f){
fputs($f, $req, strlen($req));
fclose($f);
}

}

$t = microtime(1) - $t;
echo 'done for '.$t.' seconds <br>with '.$i.' iterations';

script2.php
Свернутый текст
if(empty($_POST['job'])) die();

$content = file_get_contents($_POST['job']);

preg_match("#<span class=\"content\">(.*)</span>#isuU", $content, $matches);

file_put_contents('file'.$_POST['n'].'.html', $content);

там каждая новость сохраняется в отдельный файл, для наглядности (file1.html ... file30.html)

Спустя 3 минуты, 46 секунд (20.09.2011 - 22:40) Игорь_Vasinsky написал(а):
ohmy.gif ни чё себе.

Спустя 3 минуты, 18 секунд (20.09.2011 - 22:43) killer8080 написал(а):
так о тож wink.gif laugh.gif

Спустя 1 минута, 23 секунды (20.09.2011 - 22:44) Игорь_Vasinsky написал(а):
Я без сарказма. Просто я с такими методами не сталкивался.

Спустя 7 секунд (20.09.2011 - 22:45) Winston написал(а):
laugh.gif laugh.gif

Спустя 2 минуты, 26 секунд (20.09.2011 - 22:47) killer8080 написал(а):
я то же smile.gif
просто вспомнился хак с виртуальной многопоточностью в php.

Спустя 2 минуты, 21 секунда (20.09.2011 - 22:49) killer8080 написал(а):
только учти, что если ссылок будет слишком много, можно перегрузить сервак, выйти за лимиты памяти. На этот случай можно ввести слипы в цикл, через пару десятков итераций.

Спустя 2 дня, 23 часа, 24 минуты, 37 секунд (23.09.2011 - 22:14) Хиросим написал(а):
Вклинюсь в тему чтоб клоны не плодить.
У меня задача похожая, но проблема другая.
Я пытаюсь парсить страницу выдачи яндекса с целью определить проиндексированность УРЛа.
(Размещаю СЕО статьи на других сайтах и хочу придумать машинку для определения проиндексированности оных).
Ставлю задержку аж в 10 сек, но яндекс всеравно определяет меня как бота и выдает ругню.
Может ктонибудь знает как правильно задачу решить???
Если нужно, код такой:
//$result['link'] - УРЛ из базы
while ($result = mysql_fetch_assoc($query))
{
if ($result['link'] != '' && $result['link'] !== NULL)
{
$url = 'http://yandex.ru/yandsearch?text='.htmlentities(urlencode($result['link'])).'&lr=213';
if (file_get_contents($url) !== FALSE)
{
$yandex_string = file_get_contents($url);
if (strpos($yandex_string, ' href="'.$result['link'].'" ') !== FALSE)
{
$indexation = '<a href="'.$url.'">ok>></a>';
}
else
{$indexation = 'noInd';}
}

else
{$indexation = 'noUrl';}
sleep(10);
}
else
{$indexation = 'noLink';}
}

Спустя 12 минут, 17 секунд (23.09.2011 - 22:26) Игорь_Vasinsky написал(а):
Сдаётся мне тебе cURL поможет, он тебя замаскирует wink.gif

Спустя 8 минут, 16 секунд (23.09.2011 - 22:34) Хиросим написал(а):
Нуда, я попытался вкурить cURL , но туговато для меня пока...
только что решил... правда через задний проход... вывел последний file_get_contents из цикла в браузер, отобразилась капча, я ее заполнил и яндекс поверил в мои благие намерения...
Прошу прощений за поспешный пост, буду штурмовать CURL

Спустя 16 секунд (23.09.2011 - 22:35) Winston написал(а):
Цитата (Игорь_Vasinsky @ 23.09.2011 - 22:26)
Сдаётся мне тебе cURL поможет

Поможет smile.gif
Цитата (Игорь_Vasinsky @ 23.09.2011 - 22:26)
он тебя замаскирует

Ну если у него динамический IP то поможет, еще можно прокси заюзать через curl wink.gif

Спустя 3 минуты, 39 секунд (23.09.2011 - 22:38) Игорь_Vasinsky написал(а):
А чё лин не выложил??? я знаю - у тя большой сундучёк... wink.gif

Спустя 2 минуты, 38 секунд (23.09.2011 - 22:41) Winston написал(а):
Цитата (Игорь_Vasinsky @ 23.09.2011 - 22:38)
А чё лин не выложил??? я знаю - у тя большой сундучёк

biggrin.gif Ну раз уж вас поисковики забанили, то сочувствую... biggrin.gif
А я с ними дружу, потому можете здесь посмотреть, там все просто описано:)

Спустя 5 дней, 19 часов, 33 минуты, 4 секунды (29.09.2011 - 18:14) Winston написал(а):
Еще актуально или уже нет ?
Решил познакомится с multi-curl. Однако это весчь !!! :)
И немного переписал свой предыдущий пример с помощью multi-curl и добился фантастических результатов (у себя на локалке) 30 страниц обрабатывает за 0.5 - 1.5 сек (!!!!!)
Потому, если кому не впадло, то потестите плиз скрип :rolleyes:
Свернутый текст
<?php
header("Content-Type: text/html; charset=utf-8");
set_time_limit(0);

$start = microtime(true);
$xml = simplexml_load_file('http://www.liga.net/lenta/export/RSS/all.xml'); // Получаем список URL'ов

ob_start();
$links = '';
foreach($xml -> channel -> item AS $item)
$links .= '|' . $item -> link; // Соединяем URL'ы

$links = preg_split('#\|#', $links, null, PREG_SPLIT_NO_EMPTY); // Возвращаем массив URL'ов
$countLinks = sizeof($links); // Количество URL'ов

$cmi = curl_multi_init(); // Инициализация сеанса мультикурл

for($i = 0; $i < $countLinks; $i++)
{
$cis[] = curl_init($links[$i]); // Создаем отдельный сеанс для каждой страницы
curl_setopt($cis[$i], CURLOPT_RETURNTRANSFER, true); // Возвращаем страницу
curl_multi_add_handle($cmi, $cis[$i]); // Добавляем дескрипторы каждой страницы в общую корзину (набор)
}

$run = null;

do
$cme = curl_multi_exec($cmi, $run); // Выполняем запросы пока в наборе есть еще ссылки
while($run > 0);


for($i = 0; $i < $countLinks; $i++)
{
$pages[] = curl_multi_getcontent($cis[$i]); // Получаем страницу в массив
curl_multi_remove_handle($cmi, $cis[$i]); // Удаляем дескриптор для только что выполненого сеанса
}

curl_multi_close($cmi); // Завершаем мультисеанс

// Возвращаем обработанную новость

$content = array_map(function($item) {preg_match("#<span class=\"content\">(.*)</span>#isuU", $item, $matches); return strip_tags($matches[1]);}, $pages);
echo '<pre>'.htmlspecialchars(print_r($content, 1)).'</pre>';

$html = ob_get_contents();
ob_end_clean();

$end = microtime(true);
echo $html;
echo '<br/>TIME: ' . ($end - $start);

Спустя 2 месяца, 21 день, 4 часа, 16 минут, 44 секунды (20.12.2011 - 22:31) NestoR написал(а):
Мне препод скинул класс динамической очереди и пример его применения, сейчас пытаюсь прикрутить к ним класс определения PageRank, прикладываю класс с примером. может кто из прошаренных коддеров разберется, как выполнить с его помощью определенную функию, куда там ее вызов приписать...

Спустя 1 минута, 1 секунда (20.12.2011 - 22:32) NestoR написал(а):
пример использования:

Спустя 3 минуты, 42 секунды (20.12.2011 - 22:36) NestoR написал(а):
упс. пардон, не в ту тему пост


_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Быстрый ответ:

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