3. Нам нужен список автомобилей.
Делать будем на PHP
- можно взять справочник и
просто перенабрать :-)
- можно самостоятельно
гуглить и заполнять базу
- можно спарсить откуда то
4. Подготовка. Анализ структуры сайта.
1)Использует ли сайт авторизацию для доступа к контенту (login/pass)?
2)Как строятся урлы на сайте (/?auto=Honda)?
3)Желательно найти карту сайта (sitemap.xml)
4)Использует ли сайт куки или какие-то специфические хэдеры?
5)Есть ли контент подгружаемый асинхронно (есть ajax?)?
6)Анализ структуры страниц (что именно нам нужно)
5. Все готово, начинаем парсить.
file_get_content
(быстро но неудобно)
CURL
(функционально,
много параметров)
guzzle
(аналог CURL)
7. Как выбрать нужное? Вариант 1
feelinglucky/php-readability
Автоматически выбираем только основной контент.
private function parseContent($html)
{
$readability = new Readability($html);
$readabilityData = $readability->getContent();
return $readabilityData['content'];
}
8. Как выбрать нужное? Вариант 2
PHP Simple HTML DOM Parser
Если заранее известна структура страницы
private function parseImages($htmlText)
{
$html = str_get_html($htmlText);
$images = $html->find('img');
foreach ($images as $img) {
saveImg($img->src);
}
}
9. Как выбрать нужное? Вариант 3
RegExp
Если мы не знаем где находится нужный элемент
function parseEmails( $htmlText ) {
preg_match_all( "/[w][w.-]*([+][d])?(@)[w.-
]+(.)[w]+/ui", $htmlText, $matches );
return $matches[0];
}
10. Как то не быстро получается
И так, парсится у нас одна ссылочка за 1 секунду… а нам надо спарсить
100 000 000 ссылок (реальная задача) итого примерно 1157 дней.
Выход - многопоточность
11. Многопоточность для PHP - reactphp/react
$loop = ReactEventLoopFactory::create();
for ($i = 0; $i < $numberOfChildren; $i++) {
$process[$i] = new ReactChildProcessProcess("php web.php $i");
$process[$i]->on('exit', function ($exitCode, $termSignal) {
//do something on exit
});
}
foreach ($process as $pr) {
$pr->start($timer->getLoop());
$pr->stdout->on('data', function ($output) {
//do something on process output
});
}
$loop->run();
16. Но это еще не все проблемы...
1) многоядерный процессор
2) много оперативной памяти
3) быстрый диск для работы базы
4) быстрый интернет
8 - 16 ядра
8 - 16 Гб
SSD или RAID
100 мбит - 1 гбит
Если мы хотим запостить более чем 400 потоков
17. Пример № 2
ТЗ “Хочу найти много сайтов в гугл,
а потом собрать все eMail с этих сайтов”
18. Подготовка
- У всей сайтов разная структура
страниц и ссылок. Нам нужен
краулер.
- Некоторые сайты используют JS
фреймворки (Angular, React). Нам
нужен PhantomJS.