Как спарсить быстро много страниц в 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 минут так и не дождался результата.
Как это сделать правильно, и чтобы вышло побыстрее?
  • Вопрос задан
  • 2459 просмотров
Решения вопроса 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, например, чтобы параллельно выполнять множество операций.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
18 апр. 2024, в 21:56
2000 руб./за проект
18 апр. 2024, в 21:00
150 руб./за проект