
Высокая скорость/Низкая стоимость CommonCrawl RegExp в Node.js
Image
WARCannon был создан для упрощения и удешевления процесса «поиска по всему интернету».
С WARCannon вы можете:
WARCannon использует продуманное применение технологий AWS для горизонтального масштабирования до любого размера, минимизации затрат за счёт spot-флотов и передачи данных внутри одного региона, выкачивания данных из S3 с невероятной скоростью (до 100 Гбит/с на узел), параллелизации на сотнях ядер CPU, отправки статуса через DynamoDB и CloudFront, а также хранения результатов через S3.
В целом, WARCannon может обработать несколько шаблонов регулярных выражений по 400 ТБ за несколько часов примерно за 30 долларов.
Самый быстрый и простой способ начать работу — использовать AWS CloudShell. Просто вставьте эту однострочную команду:
source <(curl https://raw.githubusercontent.com/c6fc/warcannon/master/cloudshell/deploy.sh)
Если вы хотите использовать ветку WARCannon, отличную от master, просто введите:
export GIT_BRANCH=branch_name
source <(curl https://raw.githubusercontent.com/c6fc/warcannon/$GIT_BRANCH/cloudshell/deploy.sh)
Примечание: Развёртывание через CloudShell использует эфемерное хранилище, что означает, что пользовательские шаблоны регулярных выражений будут потеряны при выходе из CloudShell. Если вы собираетесь часто использовать WARCannon, рекомендую использовать «Локальную установку» ниже.
WARCannon требует установки следующего:
Совет профессионала: Чтобы не создавать путаницу с другими ресурсами, которые могут быть у вас в AWS, НАСТОЯТЕЛЬНО рекомендуется разворачивать WARCannon в свежем аккаунте. Вы можете легко создать новый аккаунт из консоли «Организации» в AWS. Под «НАСТОЯТЕЛЬНО рекомендуется» я имею в виду «серьёзно, не устанавливайте это рядом с другими вещами».
Сначала клонируйте репозиторий и скопируйте пример настроек.
$ git clone [email protected]:c6fc/warcannon.git
$ cd warcannon
warcannon$ cp settings.json.sample settings.json
Отредактируйте settings.json по своему вкусу:
Обязательные настройки
nodeInstanceType: Массив типов инстансов для параллельной обработки. Типы «c» — лучший выбор для этой цели, можно использовать любой размер. Для настоящих кампаний рекомендуется значение ["c5n.18xlarge"].nodeCapacity: Количество узлов, запрашиваемых при параллельной обработке. Результирующие узлы будут произвольно распределены по указанным nodeInstanceTypes.nodeParallelism: Количество одновременно обрабатываемых WARC-файлов на vCPU. Хорошее значение — 2. Если у узлов недостаточно RAM для работы с таким уровнем параллелизма (что может случиться с инстансами типа «c»), они будут работать с максимально безопасным параллелизмом.nodeMaxDuration: Максимальная продолжительность жизни вычислительных узлов в секундах. Узлы будут автоматически завершены после этого времени, если задача ещё не выполнена. Значение по умолчанию — 24 часа.Опциональные настройки (полностью пропустите, если не используются)
sshKeyName: Имя SSH-ключа EC2, который уже существует в us-east-1.allowSSHFrom: Маска CIDR для разрешения SSH. Обычно это будет <ваш_публичный_ip>/32Для установки выполните:
$ npm install
$ npm link
$ warcannon deploy
Запуск кампании в WARCannon использует простой и понятный рабочий процесс, который лучше всего описать в несколько шагов:
warcannon deploywarcannon testLocal -swarcannon testwarcannon list 2022warcannon populate 2022-21warcannon firewarcannon syncResultsЧитайте далее для более детального понимания каждого шага.
WARCannon питается от Common Crawl через программу AWS Open Data. Common Crawl уникален тем, что данные, собранные их пауками, содержат не только текст веб-сайтов, но и другие текстовые материалы, такие как JavaScript, TypeScript, полный HTML, CSS и т. д. Создавая подходящие регулярные выражения, способные идентифицировать уникальные компоненты, исследователи могут определять веб-сайты по используемым ими технологиям, и делать это, не обращаясь к самому сайту. Проблема в том, что для этого требуется обработать сотни терабайт данных, что является серьёзной задачей независимо от имеющихся ресурсов. К счастью, WARCannon предоставляет несколько инструментов для её решения!
Поиск по всему интернету не для слабонервных, но начать с эффективного фильтра — первый шаг. WARCannon поддерживает это, позволяя локально проверять регулярные выражения на реальных данных Common Crawl. Сначала откройте lambda_functions/warcannon/matches.js и измените объект regex_patterns, включив в него регулярные выражения в формате name: pattern. Вот пример из набора поиска по умолчанию:
exports.regex_patterns = {
"access_key_id": /(\'A|"A)(SIA|KIA|IDA|ROA)[JI][A-Z0-9]{14}[AQ][\'"]/g,
};
Строки, соответствующие этому выражению, будут сохранены под соответствующим ключом в результатах; в данном случае access_key_id. Совет профессионала: Используйте RegExr с форматом «JavaScript» для создания и тестирования регулярных выражений на известных совпадениях.
У вас также есть возможность сохранять результаты только с указанных доменов. Для этого просто заполните массив domains полными доменными именами (FQDN), которые вы хотите включить. Рекомендуется оставить его пустым [], так как это почти никогда не стоит того (экономия вычислительных усилий очень мала), но в некоторых специфических случаях это может быть полезно.
exports.domains = ["example1.com", "example2.com"];
После заполнения matches.js выполните следующую команду:
warcannon$ warcannon testLocal -s
При желании вы можете указать путь к WARC-файлу в бакете commoncrawl S3, но в противном случае будет использоваться жёстко заданное значение по умолчанию.
WARCannon будет обрабатывать WARC-файл в потоковом режиме (или загрузит его полностью, если вы опустите -s) для поиска настроенных совпадений. WARCannon сохранит результаты в папку ~/.warcannon/, когда вы прервёте выполнение с помощью ctrl+c или когда обработка завершится. Это позволяет очень быстро тестировать распространённые совпадения с минимальным использованием пропускной способности.
В дополнение ко всему, WARCannon попытается оценить общую вычислительную стоимость ваших регулярных выражений при локальном запуске. Таким образом, вы сможете узнать, повлияет ли данное регулярное выражение на производительность до выполнения кампании.

Иногда простого шаблона регулярного выражения недостаточно, и вам нужны дополнительные шаги, чтобы убедиться, что вы возвращаете правильную информацию. В этом случае достаточно добавить функцию в объект exports.custom_functions с тем же именем ключа, чтобы выполнить любую дополнительную обработку, какую вы сочтёте нужной.
exports.regex_patterns = {
"access_key_id": /(\'A|"A)(SIA|KIA|IDA|ROA)[JI][A-Z0-9]{14}[AQ][\'"]/g,
};
exports.custom_functions = {
"access_key_id": function(match) {
// Игнорировать совпадения с текстом 'EXAMPLE', так как это распространено в документации.
if (match.text(/EXAMPLE/) != null) {
// Возврат логического значения 'false' отбрасывает совпадение.
return false
}
}
}
Примечание: WARCannon предназначен для молниеносной обработки текста. Хотя, безусловно, можно выполнять любые операции, добавление кастомных функций с высокой задержкой, таких как сетевые вызовы, может значительно увеличить время обработки и затраты. Сетевые вызовы также могут привести к большому количеству обращений к веб-сайту, что может создать проблемы. Будьте разумны в использовании этих функций.
Затраты на AWS могут вызывать тревогу, особенно если вы просто хотите провести небольшое исследование. WARCannon позволяет выполнять как разовые запуски, так и полноценные кампании, чтобы вы могли быть уверены в получаемых результатах. Когда вы будете удовлетворены результатами, полученными с помощью testLocal, вы можете развернуть обновлённые совпадения и запустить облачный тест:
warcannon$ warcannon deploy
warcannon$ warcannon test
Опять же, при желании вы можете указать путь к WARC-файлу, хотя это не обязательно.
Это синхронно выполнит Lambda-функцию с настроенными регулярными выражениями и сразу вернёт результаты. Этот процесс занимает около 2,5 минут, так что не бойтесь подождать, пока магия произойдёт.
Когда вас устраивают результаты, полученные в Lambda, вы готовы к реальному поиску по всему интернету. Сначала мы рассмотрим базовые организационные моменты, а затем запустим кампанию.
WARCannon использует AWS Simple Queue Service для распределения работы по вычислительным узлам. Чтобы ваши результаты не были загрязнены предыдущими запусками, вы можете очистить очередь:
warcannon$ warcannon emptyQueue
[+] Cleared [ 15 ] messages from the queue
Затем вы можете проверить состояние очереди:
warcannon$ warcannon status
Deployed: [ YES ]; SQS Status: [ EMPTY ]
Job Status: [ INACTIVE ]
Active job url: https://d201offlnmhkmd.cloudfront.net
Прежде чем продолжить, убедитесь в следующем:
Чтобы создать сообщения очереди, которые будут потреблять вычислительные узлы, необходимо сначала заполнить SQS данными обхода. WARCannon имеет несколько команд для этого, начиная с возможности отображения доступных сканирований. В этом случае давайте посмотрим на доступные сканирования за 2021 год:
warcannon$ warcannon list 2021
CC-MAIN-2021-04
CC-MAIN-2021-10
У нас есть два сканирования, соответствующих строке «2021», с которыми можно работать. Теперь мы можем дать команду WARCannon заполнить очередь на основе одного из этих сканирований. На этот раз нам нужно указать параметр, который однозначно идентифицирует одно из сканирований. «2021-04» подойдёт. Мы могли бы заполнить только частичное сканирование, также указав количество частей и размер части, но пока пропустим это.
warcannon$ warcannon populate 2021-04
{Created 799 chunks of 100 from 79840 available segments"
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
Во время развёртывания WARCannon автоматически создаёт базу данных (warcannon_commoncrawl) и рабочую группу (warcannon) в Athena, которые можно использовать для быстрого запроса информации из CommonCrawl. Это особенно полезно для заполнения разрежённых кампаний на основе определённых запросов. Например, следующий запрос найдёт WARC-файлы, содержащие ответы от 'example.com'
SELECT
warc_filename,
COUNT(url_path) as num
FROM
warcannon_commoncrawl.ccindex
WHERE
subset = 'warc' AND
url_host_registered_domain IN ('example.com') AND
crawl = 'CC-MAIN-2021-04'
GROUP BY warc_filename
ORDER BY num DESC
Для точной настройки результатов можно использовать консоль Athena, но для заполнения задания запросом необходимо выполнить его из командной строки WARCannon:
warcannon queryAthena "SELECT warc_filename, COUNT(url_path) as num FROM warcannon_commoncrawl.ccindex WHERE subset = 'warc' AND url_host_registered_domain IN ('example.com') AND crawl = 'CC-MAIN-2021-04' GROUP BY warc_filename ORDER BY num DESC"
[+] Query Exec Id: 0319486e-1846-491c-badf-2e23ae213974 .. SUCCEEDED
Затем WARCannon может использовать результаты запроса для заполнения очереди, основываясь на столбце warc_filename из результирующего набора. Поэтому рекомендуется либо group by этот столбец, либо использовать distinct(), чтобы избежать дубликатов. WARCannon выдаст ошибку, если это поле отсутствует. Заполните очередь результатами Athena, передав идентификатор выполнения запроса команде populateAthena.
warcannon populateAthena 0319486e-1846-491c-badf-2e23ae213974
{Created 26 chunks of 10 from 251 available segments"
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
Примечание: Хотя заполнение разрежённого задания для одного домена может показаться хорошей идеей, часто это не так. Ответы от одного домена, как правило, распределены по большому подмножеству WARC-файлов. Это хорошо видно на примере запроса выше: из ~150 000 записей в каждом WARC наибольшее единственное совпадение для сайтов среднего размера может быть однозначным.
После заполнения очереди мы готовы к запуску. WARCannon выполнит несколько проверок работоспособности, чтобы убедиться, что всё в порядке, затем покажет конфигурацию кампании и даст последнюю возможность отменить запуск перед финализацией заказа.
warcannon$ warcannon fire
[!] This will request [ 6 ] spot instances of type [ m5n.24xlarge, m5dn.24xlarge ]
lasting for [ 86400 ] seconds.
To change this, edit your settings in settings.json and run warcannon deploy
--> Ready to fire? [Yes]:
Нажмите на спусковой крючок, ответив «Yes».
--> Ready to fire? [Yes]: Yes
{
"SpotFleetRequestId": "sfr-03dd32b8-51f7-4c8e-802b-a702fc3c8c95"
}
[+] Spot fleet request has been sent, and nodes should start coming online within ~5 minutes.
Monitor node status and progress at https://d201offlnmhkmd.cloudfront.net
Ответ включает ссылку на ваш уникальный URL статуса, где вы можете отслеживать ход кампании и производительность каждого узла.

Результаты WARCannon сохраняются в S3 в формате JSON, разбитые по каждому узлу, ответственному за получение результатов. Результаты Athena сохраняются в том же бакете с префиксом /athena/. Вы можете синхронизировать результаты кампании с папкой ~/.warcannon/ на локальной машине с помощью команды syncResults.
warcannon syncResults
sync: s3://warcannon-results-202...
sync: s3://warcannon-results-202...
sync: s3://warcannon-results-202...
...
Затем вы можете очистить бакет с результатами с помощью clearResults
warcannon clearResults
delete: s3://warcannon-results-202...
delete: s3://warcannon-results-202...
delete: s3://warcannon-results-202...
...
[+] Deleted [ 21 ] files from S3.
Есть вопросы, нужна помощь, хотите внести свой вклад или похвастаться победой? Присоединяйтесь к нам в Discord!