Совсем недавно я начал работать над требованием, которое заключается в добавлении компонента поиска на каждый веб-сайт, который клиенты публикуют через наше приложение. Чтобы добавить компонент поиска на веб-сайт, сложной задачей было бы очистить данные веб-сайта и соответствующим образом их проиндексировать. На этом этапе я провел небольшое исследование существующих веб-сканеров, поисковых индексов и, основываясь на результатах, решил использовать StormCrawler, который представляет собой набор ресурсов с открытым исходным кодом, запускаемых на Apache Storm и Elasticsearch для индексации просканированных данных. А теперь поделюсь своим опытом, как я добился желаемых результатов.

В этом руководстве / статье я использовал следующие библиотеки и ресурсы для выполнения задачи и достижения требуемых результатов.

  1. StormCrawler (v1.15)
  2. Elasticsearch (v7.1.0)
  3. Apache Storm (v1.2.3)
  4. Apache Maven (v3.6.2)

P.S: StormCrawler (v1.15) поддерживает последнюю версию Elasticsearch (v7.4.0). Однако я решил использовать Elasticsearch v7.1.0 для этого руководства, потому что на момент написания этого руководства AWS поддерживает только Elasticsearch v7.1.0. (Я использовал AWS SQS для передачи доменов веб-сайтов в StormCrawler, и я поделился своим опытом в этой статье)

О чем пойдет речь в этой статье

  • Настройте проект StormCrawler с конфигурациями Elasticsearch
  • Запуск StormCrawler с Apache Flux в локальном режиме (инжектор и краулер отдельно)

Предварительное условие

  • Apache Storm добавлен как переменная PATH
  • Elasticsearch работает на локальном сервере
  • Apache Maven установлен на вашем компьютере

Настроить StormCrawler

StormCrawler имеет быстрый процесс настройки и может быть настроен с помощью Apache Maven. Следующая команда maven создаст проект maven с базовыми конфигурациями StormCrawler.

mvn archetype:generate -DarchetypeGroupId=com.digitalpebble.stormcrawler -DarchetypeArtifactId=storm-crawler-archetype -DarchetypeVersion=1.15

Вышеупомянутая команда предложит вам ввести groupId, artifcatId, и вы можете пока пропустить остальные. Я указал com.cnf271 и stormcrawlertest как groupId и artifactId соответственно.

Команда выше создаст красивую папку, как показано на рисунке ниже.

Прежде всего,

Для работы с Elasticsearch нам может потребоваться удалить некоторые существующие файлы и заменить их файлами StormCrawler, совместимыми с Elasticsearch. (Обратите внимание, что приведенные выше конфигурации достаточно хороши для правильного сканирования Интернета, и мы отклоняемся от базового StormCrawling, поскольку наша конечная цель - передать просканированные данные в Elasticsearch).

Идите вперед и клонируйте репозиторий StormCrawler GitHub в отдельную папку. Все, что нам нужно, это несколько файлов конфигурации из папки репозитория / external / elasticsearch. Скопируйте следующие файлы из / external / elasticsearch в ранее созданную папку stormcrawlertest.

  • ES_IndexInit.sh
  • es-conf.yaml
  • es-crawler.flux
  • es-injector.flux
  • Кибана (папка)

И удалите следующий файл из папки stormcrawlertest.

  • crawler.flux

Теперь создайте текстовый файл с именем seed внутри каталога stormcrawlertest.

После изменений папка stormcrawlertest должна выглядеть, как показано на изображении ниже.

Краткое объяснение единственной цели каждого файла.

  • ES_IndexInit - скрипт Bash, содержащий информацию об индексах, которые мы собираемся создать в Elasticsearch.
  • es-conf.yaml - содержит информацию о конфигурациях ресурсов Elasticsearch. (На данный момент я буду придерживаться конфигураций по умолчанию)
  • es-injector.flux - содержит информацию о том, как URL-адреса вводятся в индекс search Elasticsearch. Изначально существует один spout (FileSpout - считывает URL-адреса из текстового файла) и один Bolt (StatusUpdaterBolt - обновляет индекс состояния после каждой инъекции в файл потока инжектора.
  • es-crawler.flux - выполняет собственно сканирование. Содержит один носик (AggregationSpout - проверяет и получает URL-адреса с сервера Elasticsearch для сканирования) и несколько болтов (несколько болтов для извлечения URL-адресов, получения данных и индексации содержимого и т. Д.)
  • seed.txt - текстовый файл, содержащий URL-адреса веб-сайта, который мы собираемся сканировать (в этом руководстве мы будем указывать StormCrawler использовать URL-адреса, указанные в seed.txt) Добавьте URL-адрес в текстовый файл. Для начала я добавил http://www.mit.edu/ в файл seed.txt.
  • crawler-conf.yaml - содержит конфигурации по умолчанию для StormCrawler.

Измените настройки по умолчанию для сценария bash ES_IndexInit

По умолчанию сценарий bash ES_IndexInit отключил параметр сохранения содержимого при сохранении данных в индексе Elasticsearch. Кроме того, _source также отключен по умолчанию. Вы можете изменить конфигурации следующим образом, чтобы StormCrawler сохранял данные содержимого и отображал их в результатах запроса.

Добавление зависимости StormCrawler Elasticsearch

Продолжайте и добавьте следующую зависимость в файл pom.xml.

<dependency>
   <groupId>com.digitalpebble.stormcrawler</groupId>
   <artifactId>storm-crawler-elasticsearch</artifactId>
   <version>1.15</version>
</dependency>

Создание релевантных индексов в Elasticsearch

Прежде чем приступить к созданию проекта maven, нам может потребоваться создать несколько индексов в Elasticsearch. Это можно сделать, выполнив сценарий bash ES_IndexInit. Выполнение сценария bash ES_IndexInit помогает нам создавать и удалять существующие индексы, которые мы добавили в Elasticsearch.

Что такое сценарий bash ES_IndexInit и его назначение?

Сценарий bash ES_IndexInit содержит несколько команд curl, которые создают и удаляют (изначально) существующие поисковые индексы. Вы можете изменить их соответствующим образом.

Скрипт Bash создаст следующие индексы в ES,

  • Контент - содержит фактический контент, просканированный StormCrawler, а также его хост, title, url и т. д.
  • Статус - создает индекс в ES, который показывает статус домена веб-сайта, который был внедрен / просканирован в ES. Например: DISCOVERED, FETCHED, REDIRECTION, FETCH_ERROR и ERROR. Подробнее об индексе статуса здесь.
  • Метрики - содержит метрики, предоставленные самим Apache Storm и StormCrawler, такие как идентификатор исполнителя, который использовался для сканирования URL-адреса, хост рабочего и т. д.

Выполните сценарий bash, просто выполнив следующую команду в каталоге проекта.

E:\Stormcrawlertest\stormcrawlertest>ES_IndexInit.sh

После выполнения сценария для проверки состояния указанных выше индексов можно использовать следующие URL-адреса браузера.

http://localhost:9200/status/_search?pretty
http://localhost:9200/content/_search?pretty
http://localhost:9200/metrics/_search?pretty

Сборка проекта Maven

После того, как проект был настроен с необходимыми зависимостями и были созданы поисковые индексы на сервере ES, мы можем создать uberjar, просто выполнив следующую команду в каталоге проекта.

mvn clean package

Теперь, когда артефакт проекта создан, остается внедрить и просканировать веб-сайты, которые мы добавили в файл seed.txt.

Внедрение URL-адресов в Elasticsearch

Что на самом деле означает внедрение URL-адресов в Elasticsearch?

Путем внедрения URL-адресов в Elasticsearch будет использоваться носик для извлечения URL-адресов из определенного источника и отправки их на сервер ES для обнаружения.

В нашем случае мы будем использовать FileSpout, который будет читать URL-адреса из текстового файла и отправлять их на сервер ES. Кроме того, в зависимости от требований для выполнения этой задачи можно использовать несколько других носиков. Например, MemorySpout можно использовать, когда URL-адреса хранятся в памяти.

Мы будем использовать Apache Flux для внедрения наших URL-адресов на сервер Elasticsearch. Apache Flux - это фреймворк, который можно использовать для развертывания нашего приложения с помощью Apache Storm.

Продолжайте и выполните следующую команду в каталоге проекта,

storm jar target/stormcrawlertest-1.0-SNAPSHOT.jar  org.apache.storm.flux.Flux --local es-injector.flux

Поскольку мы запускаем инжектор в локальном режиме, Apache Flux использует значение по умолчанию Time To Live (TTL), равное 60 секундам. Инжектор попытается ввести максимальное количество URL-адресов из seed.txt на ES-сервер в течение этого периода. Однако в нашем случае 60 секунд более чем достаточно для внедрения двух URL-адресов на ES-сервер. В начальном процессе внедрения топология инжектора будет пытаться обнаружить только корневые URL-адреса, которые мы добавили в текстовый файл.

После того, как инжектор был успешно запущен в течение 60 секунд, мы можем проверить индекс состояния на предмет статуса обнаружения URL-адресов.

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 10,
    "successful" : 10,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "status",
        "_type" : "_doc",
        "_id" : "6a5d8441f5fee2387f82ac87499ee8f48876c06b0f1696afb98b643cacd9678e",
        "_score" : 1.0,
        "_routing" : "www.mit.edu",
        "_source" : {
          "url" : "http://www.mit.edu/",
          "status" : "DISCOVERED",
          "metadata" : { },
          "key" : "www.mit.edu",
          "nextFetchDate" : "2019-10-29T11:14:16.000Z"
        }
      }
    ]
  }
}

Сканирование введенных URL

После того, как URL-адреса были введены на ES-сервер, топология сканера может использоваться для сканирования страниц в зависимости от статуса сканирования и nextfetchDate. Носик агрегации в Crawler flux получит URL-адреса из индекса статуса и начнет их сканирование. Как и Инжектор, топология обходчика будет работать только 60 секунд в локальном режиме. Чтобы очистить весь веб-сайт, вам может потребоваться запустить поток поискового робота несколько раз.

Следующая команда запустит поисковый робот в локальном режиме.

storm jar target/stormcrawlertest-1.0-SNAPSHOT.jar  org.apache.storm.flux.Flux --local es-crawler.flux

После успешного запуска вы можете проверить индексы status и content на предмет фактических результатов. Вы можете заметить, что статус URL-адресов, которые были введены ранее, был изменен на статус FETCHED, что означает, что контент в данном URL-адресе был успешно просканирован и проиндексирован на ES-сервер StormCrawler.

Ниже приводится фрагмент указателя content.

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 7,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "content",
        "_type" : "_doc",
        "_id" : "6a5d8441f5fee2387f82ac87499ee8f48876c06b0f1696afb98b643cacd9678e",
        "_score" : 1.0,
        "_source" : {
          "content" : "Spotlight: Oct 29, 2019 MIT chemists have devised a way to synthesize polymers that can break down more readily in the body and in the environment. The materials could be useful for delivering drugs or imaging agents in the body, or as an alternative to some industrial plastics. Full story Oct 29, 2019 Share: Twitter Facebook",
          "url" : "http://www.mit.edu/",
          "domain" : "mit.edu",
          "title" : "MIT - Massachusetts Institute of Technology"
        }
      },
      {
        "_index" : "content",
        "_type" : "_doc",
        "_id" : "ac6f172a5b208139bb56bdc477b021e699a2281105e7ee33d53002875c62e31b",
        "_score" : 1.0,
        "_source" : {
          "content" : "homenewseducationresearchoffices+servicescommunityeventsaboutmap search people directory name/email reverse lookup (7 digits) lastname sounds like about the online people directory how to update | emergency services search format example first name last name william barton rogers last name rogers username wbrogers username with wildcard wbrog*, wbr?gers, wbro[jg]ers seven-digit phone number 253-1000 This directory does not allow searching by first name only. massachusetts institute of technology 77 massachusetts avenue cambridge, ma 02139-4307 TEL 617.253.1000 TDD/TTY, please use TRS (711) about this site contact MIT Google People Offices More Options",
          "url" : "http://web.mit.edu/people.html",
          "domain" : "mit.edu",
          "title" : "MIT - people directory"
        }
      }
...

Как видите, во время первоначального сканирования StormCrawler смог просканировать 7 материалов с веб-сайта http://www.mit.edu/. Если вы снова запустите поисковый робот, вы можете заметить увеличение общего количества совпадений.

Заключение

В этой статье я обсудил, как настроить проект StormCrawler с конфигурациями Elasticsearch. Кроме того, я объяснил, как сценарий bash ES_IndexInit помогает нам в создании соответствующих индексов в Elasticsearch и какие изменения необходимо внести в сценарий, чтобы сохранить контент. Я добавил образец проекта в свой репозиторий GitHub для вашей справки.

В следующей своей статье я рассказал, как мне удалось запустить инжектор и краулер непрерывно в локальном режиме без штормового кластера. Кроме того, я объяснил, как AWS SQS можно использовать для ввода URL-адресов в инжектор.

Ссылки

  1. Http://stormcrawler.net/
  2. Https://www.elastic.co/