Этот пакет предоставляет класс для сканирования ссылок на веб-сайте. Под капотом обещания Guzzle используются для одновременного сканирования нескольких URL-адресов.
Поскольку сканер может выполнять JavaScript, он может сканировать сайты, отображаемые на JavaScript. Под капотом этой функции используются Chrome и Puppeteer.
Мы вкладываем много ресурсов в создание лучших в своем классе пакетов с открытым исходным кодом. Вы можете поддержать нас, купив один из наших платных продуктов.
Мы очень признательны вам за отправку нам открытки из вашего родного города с указанием того, какой из наших пакетов вы используете. Наш адрес вы найдете на странице контактов. Все полученные открытки мы публикуем на нашей виртуальной стене открыток.
Этот пакет можно установить через Composer:
композитору требуется спати/краулер
Сканер может быть создан следующим образом
используйте SpatieCrawlerCrawler; Краулер::create() ->setCrawlObserver(<класс, расширяющий SpatieCrawlerCrawlObserversCrawlObserver>) ->startCrawling($url);
Аргумент, передаваемый в setCrawlObserver
должен быть объектом, расширяющим абстрактный класс SpatieCrawlerCrawlObserversCrawlObserver
:
пространство имен SpatieCrawlerCrawlObservers; используйте GuzzleHttpExceptionRequestException; используйте PsrHttpMessageResponseInterface; используйте PsrHttpMessageUriInterface; абстрактный класс CrawlObserver {/* * Вызывается, когда сканер сканирует URL. */public function willCrawl(UriInterface $url, ?string $linkText): void{ }/* * Вызывается, когда сканер успешно просканировал данный URL-адрес. */абстрактная публичная функция просканирована(UriInterface $url,ResponseInterface $response, ?UriInterface $foundOnUrl = ноль, ?строка $linkText, ): void;/* * Вызывается, когда у сканера возникают проблемы при сканировании данного URL-адреса. */абстрактная публичная функция scanFailed(UriInterface $url,RequestException $requestException, ?UriInterface $foundOnUrl = ноль, ?строка $linkText = ноль, ): void;/** * Вызывается после завершения сканирования. */публичная функция законченаCrawling(): void{ } }
Вы можете установить несколько наблюдателей с помощью setCrawlObservers
:
Краулер::create() ->setCrawlObservers([ <класс, расширяющий SpatieCrawlerCrawlObserversCrawlObserver>, <класс, расширяющий SpatieCrawlerCrawlObserversCrawlObserver>, ... ]) ->startCrawling($url);
В качестве альтернативы вы можете установить несколько наблюдателей один за другим с помощью addCrawlObserver
:
Краулер::create() ->addCrawlObserver(<класс, расширяющий SpatieCrawlerCrawlObserversCrawlObserver>) ->addCrawlObserver(<класс, расширяющий SpatieCrawlerCrawlObserversCrawlObserver>) ->addCrawlObserver(<класс, расширяющий SpatieCrawlerCrawlObserversCrawlObserver>) ->startCrawling($url);
По умолчанию сканер не выполняет JavaScript. Вот как вы можете включить выполнение JavaScript:
Краулер::create() -> выполнитьJavaScript() ...
Чтобы можно было получить HTML-код тела после выполнения javascript, этот пакет зависит от нашего пакета Browsershot. Этот пакет использует Puppeteer под капотом. Вот несколько советов о том, как установить его в вашей системе.
Browsershot сделает обоснованное предположение о том, где в вашей системе установлены его зависимости. По умолчанию сканер создаст новый экземпляр Browsershot. Возможно, вам понадобится установить созданный пользователем экземпляр с помощью метода setBrowsershot(Browsershot $browsershot)
.
Краулер::create() ->setBrowsershot($browsershot) -> выполнитьJavaScript() ...
Обратите внимание, что сканер будет продолжать работать, даже если у вас нет системных зависимостей, необходимых для Browsershot. Эти системные зависимости необходимы только в том случае, если вы вызываете executeJavaScript()
.
Вы можете указать сканеру не посещать определенные URL-адреса, используя функцию setCrawlProfile
. Эта функция ожидает объект, расширяющий SpatieCrawlerCrawlProfilesCrawlProfile
:
/* * Определяем, следует ли сканировать данный URL-адрес. */публичная функция mustCrawl(UriInterface $url): bool;
В комплект поставки этого пакета входят три CrawlProfiles
:
CrawlAllUrls
: этот профиль будет сканировать все URL-адреса на всех страницах, включая URL-адреса внешнего сайта.
CrawlInternalUrls
: этот профиль будет сканировать только внутренние URL-адреса страниц хоста.
CrawlSubdomains
: этот профиль будет сканировать только внутренние URL-адреса и их поддомены на страницах хоста.
Вы можете настроить способ извлечения ссылок со страницы, передав сканеру пользовательский UrlParser
.
Краулер::create() ->setUrlParserClass(<класс, реализующий SpatieCrawlerUrlParsersUrlParser>::класс) ...
По умолчанию используется LinkUrlParser
. Этот парсер извлечет все ссылки из атрибута href
a
.
Существует также встроенный SitemapUrlParser
, который будет извлекать и сканировать все ссылки из карты сайта. Он поддерживает индексные файлы карты сайта.
Краулер::create() ->setUrlParserClass(SitemapUrlParser::class) ...
По умолчанию сканер будет учитывать данные роботов. Эти проверки можно отключить следующим образом:
Краулер::create() ->игнорировать роботов() ...
Данные роботов могут поступать из файла robots.txt
, метатегов или заголовков ответов. Более подробную информацию о спецификации можно найти здесь: http://www.robotstxt.org/.
Анализ данных роботов осуществляется с помощью нашего пакета spatie/robots-txt.
По умолчанию сканер отклоняет все ссылки, содержащие атрибут rel="nofollow". Эти проверки можно отключить следующим образом:
Краулер::create() ->acceptNofollowLinks() ...
Чтобы соблюдать правила robots.txt для пользовательского агента пользователя, вы можете указать свой собственный пользовательский агент.
Краулер::create() ->setUserAgent('мой-агент')
Вы можете добавить свою конкретную группу правил сканирования для «мой-агент» в robots.txt. В этом примере запрещается сканирование всего сайта для сканеров, идентифицированных как «мой-агент».
// Запретить сканирование для моего агента Пользовательский агент: мой-агент Запретить: /
Чтобы повысить скорость сканирования, пакет по умолчанию одновременно сканирует 10 URL-адресов. Если вы хотите изменить это число, вы можете использовать метод setConcurrency
.
Краулер::create() ->setConcurrency(1) // теперь все URL-адреса будут сканироваться один за другим
По умолчанию сканер продолжает работу до тех пор, пока не просканирует каждую найденную страницу. Такое поведение может вызвать проблемы, если вы работаете в среде с ограничениями, например в бессерверной среде.
Поведением сканирования можно управлять с помощью следующих двух опций:
Общий лимит сканирования ( setTotalCrawlLimit
): этот лимит определяет максимальное количество URL-адресов для сканирования.
Текущий лимит сканирования ( setCurrentCrawlLimit
): определяет, сколько URL-адресов обрабатывается во время текущего сканирования.
Давайте рассмотрим несколько примеров, чтобы прояснить разницу между этими двумя методами.
Метод setTotalCrawlLimit
позволяет ограничить общее количество URL-адресов для сканирования независимо от того, как часто вы вызываете сканер.
$queue = <ваш выбор/реализация очереди>;// Сканирует 5 URL-адресов и завершает работу.Crawler::create() ->setCrawlQueue($queue) ->setTotalCrawlLimit(5) ->startCrawling($url);// Не сканируем дальше по мере достижения общего лимита.Crawler::create() ->setCrawlQueue($queue) ->setTotalCrawlLimit(5) ->startCrawling($url);
setCurrentCrawlLimit
устанавливает ограничение на количество URL-адресов, которые будут сканироваться за одно выполнение. Этот фрагмент кода будет обрабатывать 5 страниц при каждом выполнении без общего ограничения на количество страниц для сканирования.
$queue = <ваш выбор/реализация очереди>;// Сканирует 5 URL-адресов и завершает работу.Crawler::create() ->setCrawlQueue($queue) ->setCurrentCrawlLimit(5) ->startCrawling($url);// Сканирует следующие 5 URL и завершает работу.Crawler::create() ->setCrawlQueue($queue) ->setCurrentCrawlLimit(5) ->startCrawling($url);
Оба ограничения можно комбинировать для управления сканером:
$queue = <ваш выбор/реализация очереди>;// Сканирует 5 URL-адресов и завершает работу.Crawler::create() ->setCrawlQueue($queue) ->setTotalCrawlLimit(10) ->setCurrentCrawlLimit(5) ->startCrawling($url);// Сканирует следующие 5 URL и завершает работу.Crawler::create() ->setCrawlQueue($queue) ->setTotalCrawlLimit(10) ->setCurrentCrawlLimit(5) ->startCrawling($url);// Не сканируем дальше по мере достижения общего лимита.Crawler::create() ->setCrawlQueue($queue) ->setTotalCrawlLimit(10) ->setCurrentCrawlLimit(5) ->startCrawling($url);
Вы можете использовать setCurrentCrawlLimit
, чтобы прервать длительное сканирование. Следующий пример демонстрирует (упрощенный) подход. Он состоит из первоначального запроса и любого количества последующих запросов, продолжающих сканирование.
Чтобы начать сканирование различных запросов, вам нужно будет создать новую очередь выбранного вами драйвера очереди. Начните с передачи экземпляра очереди сканеру. Сканер начнет заполнять очередь по мере обработки страниц и обнаружения новых URL-адресов. Сериализуйте и сохраните ссылку на очередь после завершения работы искателя (с использованием текущего ограничения сканирования).
// Создаем очередь, используя ваш драйвер очереди.$queue = <ваш выбор/реализация очереди>;// Сканируем первый набор URLsCrawler::create() ->setCrawlQueue($queue) ->setCurrentCrawlLimit(10) ->startCrawling($url);// Сериализовать и сохранить очередь$serializedQueue = сериализовать($queue);
Для любых следующих запросов вам потребуется десериализовать исходную очередь и передать ее сканеру:
// Десериализация очереди$queue = unserialize($serializedQueue);// Сканирует следующий набор URLsCrawler::create() ->setCrawlQueue($queue) ->setCurrentCrawlLimit(10) ->startCrawling($url);// Сериализовать и сохранить очередь$serialized_queue = сериализовать($queue);
Поведение основано на информации в очереди. Только если в поведении передается тот же экземпляр очереди, поведение работает так, как описано. Когда передается совершенно новая очередь, ограничения предыдущего сканирования (даже для того же веб-сайта) не применяются.
Пример с более подробной информацией можно найти здесь.
По умолчанию сканер продолжает работу до тех пор, пока не просканирует каждую страницу предоставленного URL-адреса. Если вы хотите ограничить глубину сканера, вы можете использовать метод setMaximumDepth
.
Краулер::create() ->setMaximumDepth(2)
Большинство HTML-страниц довольно маленькие. Но сканер может случайно обнаружить большие файлы, такие как PDF и MP3. Чтобы в таких случаях использовать память на низком уровне, сканер будет использовать только ответы размером менее 2 МБ. Если при потоковой передаче ответа он станет больше 2 МБ, сканер прекратит потоковую передачу ответа. Предполагается пустое тело ответа.
Вы можете изменить максимальный размер ответа.
// давайте использовать максимум 3 МБ.Crawler::create() ->setMaximumResponseSize(1024 * 1024 * 3)
В некоторых случаях скорость сканирования может быть ограничена при слишком агрессивном сканировании. Чтобы обойти это, вы можете использовать метод setDelayBetweenRequests()
, чтобы добавлять паузу между каждым запросом. Это значение выражается в миллисекундах.
Краулер::create() ->setDelayBetweenRequests(150) // После сканирования каждой страницы сканер будет ждать 150 мс
По умолчанию каждая найденная страница будет загружена (размером до setMaximumResponseSize()
) и проанализирована на наличие дополнительных ссылок. Вы можете ограничить, какие типы контента следует загружать и анализировать, установив в setParseableMimeTypes()
массив разрешенных типов.
Краулер::create() ->setParseableMimeTypes(['text/html', 'text/plain'])
Это предотвратит загрузку тела страниц с разными типами MIME, таких как двоичные файлы, аудио/видео и т. д., в которые вряд ли будут встроены ссылки. Эта функция в основном экономит полосу пропускания.
При сканировании сайта сканер помещает URL-адреса для сканирования в очередь. По умолчанию эта очередь хранится в памяти с помощью встроенного ArrayCrawlQueue
.
Если сайт очень большой, вам может потребоваться сохранить эту очередь в другом месте, например в базе данных. В таких случаях вы можете написать собственную очередь сканирования.
Допустимой очередью сканирования является любой класс, реализующий интерфейс SpatieCrawlerCrawlQueuesCrawlQueue
. Вы можете передать свою собственную очередь сканирования с помощью метода setCrawlQueue
сканера.
Краулер::create() ->setCrawlQueue(<реализация SpatieCrawlerCrawlQueuesCrawlQueue>)
Здесь
МассивСканироватьОчередь
RedisCrawlQueue (сторонний пакет)
CacheCrawlQueue для Laravel (сторонний пакет)
Модель Laravel как очередь (пример стороннего приложения)
По умолчанию сканер установит базовую схему URL-адреса на http
если ее нет. У вас есть возможность изменить это с помощью setDefaultScheme
.
Краулер::create() ->setDefaultScheme('https')
Пожалуйста, посетите CHANGELOG для получения дополнительной информации о том, что изменилось за последнее время.
Пожалуйста, смотрите ВКЛАД для получения подробной информации.
Сначала установите зависимость Puppeteer, иначе ваши тесты не пройдут.
npm install puppeteer
Чтобы запустить тесты, вам необходимо сначала запустить включенный сервер на базе узла в отдельном окне терминала.
CD-тесты/сервер установка npm узел server.js
Когда сервер запущен, вы можете начать тестирование.
композиторский тест
Если вы обнаружили ошибку, связанную с безопасностью, отправьте электронное письмо по адресу [email protected] вместо использования системы отслеживания проблем.
Вы можете свободно использовать этот пакет, но если он попадет в вашу производственную среду, мы будем очень признательны, если вы отправите нам открытку из вашего родного города с указанием того, какой из наших пакетов вы используете.
Наш адрес: Spatie, Kruikstraat 22, 2018, Антверпен, Бельгия.
Все полученные открытки мы публикуем на сайте нашей компании.
Фрик Ван дер Хертен
Все участники
Лицензия MIT (MIT). Пожалуйста, смотрите файл лицензии для получения дополнительной информации.