Как спарсить быстро много страниц в PHP?

Есть один сайт, на котором есть много страниц, с которых мне надо взять 1 лишь блок с информацией. Таких страниц примерно под 10 000. Анкеты они идут упорядоченно, не в разброс.

Мой алгоритм таков: обращаемся через CURL к каждой странице в цикле, дальше через библиотеку phpQuery ищем класс, в котором находится нужная инфа нам, и выводим всё это на страницу. Вот код, как это сейчас выглядит:

<?php
require_once 'phpquery/phpQuery/phpQuery.php';
ini_set('max_execution_time', 0);
for($i = 1; $i <= 600; $i++) { // обработаем 600 анкет
$url = 'https://тут_адрес_сайта/anketa/' . $i; // выходит что будет обрабатываться каждая анкета начиная с 1 до 600
$val = curlIt($url);
$html = phpQuery::newDocument($val);
$pq = pq($html);
$elem = $pq->find('.distance'); // получаем содержимое внутри класса distance
if(!$elem) continue; // если такого блока нет пропускаем
echo $elem; // Выводим то содержимое класса .distance

}

function curlIt($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

$res = curl_exec($ch);
curl_close($ch);
return $res;
}


Это всё срабатывает, но когда выводим 50 результатов, и при этом всё равно ждать приходится несколько минут. Попробовал вывести 500 результатов, по истечению 10 минут так и не дождался результата.
Как это сделать правильно, и чтобы вышло побыстрее?
  • Вопрос задан
  • 2455 просмотров
Решения вопроса 1
Sanasol
@Sanasol Куратор тега PHP
нельзя просто так взять и загуглить ошибку
Ну во-первых, multi curl в гугл.
Во-вторых, если composer это не страшное слово, то сюда.
В-третьих, скорее всего большую часть времени отжирает не сам запрос, а разбор DOM через phpquery. Лучше таки использовать что-то посовременнее и скорее всего побыстрее.
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
webinar
@webinar Куратор тега PHP
Учим yii: https://youtu.be/-WRMlGHLgRg
А зачем скорость? Нужно терпение. Запускайте процесс и пусть себе парсит. Я для таких целей использую ПО contentDownloader там быстрее все настроить и запустить. Пускаете в 10 потоков и идете пить чай. 50000 страниц не особо много, 1-2часа и все будет готово. Вот был опыт с 5 000 000 страниц и сложной выборкой данных. 3 дня. Но если оно само парсит, то все равно не проблема.
Ну или кроном дергать скрипт раз в минуту и писать в базу результаты. Можно за раз по несколько дергать. И через n времени, где n явно меньше 10 часов, будет все готово.
Оптимизация больше времени займет. Если речь о ежедневном парсинге 1M страниц, тогда надо думать. Смотреть где больше потеря времени, при загрузке страницы или при работе скрипта, подбирать библиотеки. А для одноразовой задачи на 50k страниц, много чести, оптимизировать что-либо.
Ответ написан
Комментировать
Driver86
@Driver86
Немодератор toster.ru
Тут скорость ограничена каналом сайта и защитой от частых обращений, если таковая имеется
Ответ написан
Комментировать
@nirvimel
Тут поможет кеширование промежуточных результатов (после phpQuery) в БД. Если нужно выдавать всегда актуальные данные, при том что исходные данные постоянно меняются, то у каждой записи в кеше должна быть отметка времени записи, и если с того момента прошло больше N секунд/дней, то делается повторный запрос к исходной странице.

Ну и выборка 500 страниц синхронно в одном потоке... если бы я увидел такой код в проекте, то подумал бы, что это сделано специально, чтобы разгрузить сервер для других задач или дать пользователю время сходить покурить.
Ответ написан
Комментировать
lxfr
@lxfr
Вас, помимо скорости, должен еще волновать вопрос "а как скоро меня забанят по IP". Сейчас половина сайтов это умеют делать автоматически когда идет много странных запросов.
Ответ написан
Комментировать
@entermix
Используйте multi curl, или gearman, например, чтобы параллельно выполнять множество операций.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы