Парсинг дроп-доменов из Common Crawl

База данных Common Crawl лежит в Amazon S3. Для работы понадобится аккаунт AWS и настроенный AWS CLI. Я производил настройку на Windows 11 через WSL.

1. Настройка учётки AWS.

Не работайте из под root, создайте IAM-пользователя.

  • Зайди в AWS Console → сервис IAM → Users → Create user.
  • Имя, например cc-lab. Галку «Provide user access to the Console» можно не ставить - нужен только программный доступ.
  • Выбираем Attach policies directly и две управляемые политики: AmazonAthenaFullAccess и AmazonS3FullAccess.
  • Athena-политика тянет за собой нужные права на Glue Data Catalog.
  • Создайте пользователя → откройте его → вкладка Security credentials → Create access key → тип Command Line Interface (CLI).
  • Получаем Access key ID и Secret access key.

Далее открываем cmd в Windows, вводим команду wsl и нажимаем enter. В командной строке вводим:

curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o awscliv2.zip
apt-get update && apt-get install -y unzip    # если unzip не стоит
unzip -q awscliv2.zip
./aws/install
aws --version     # проверка: должно показать aws-cli/2.x

Настраиваем доступ с своими учётными данными:

aws configure

Заполняем учётные данные:

AWS Access Key ID → ваш id
AWS Secret Access Key → ваш ключ
Default region name → us-east-1 (обязательно: данные Common Crawl там, иначе будет оплата за трафик между регионами)
Default output format → json

Финальная проверка работы учётки:

aws sts get-caller-identity

2. Создаём S3-bucket.

Всё еще настраиваем в WSL. Имена бакетов уникальны, поэтому нужно создать свой:

aws s3 mb s3://you-bucket-name-123 --region us-east-1

Далее во всех командах будет фигурировать уникальное имя, которое создано на этом шаге.

3. Быстрая проверка доступности данных Common Crawl.

aws s3 ls s3://commoncrawl/projects/hyperlinkgraph/cc-main-2026-feb-mar-apr/domain/ --region us-east-1

Если после исполнения команды появился список файлов графа, значит учётка AWS настроена и работает.

4. Настройка Query result location для Athena.

AWS Console → Athena → Query editor → вкладка Settings → Manage → в поле Location of query result вписать s3://you-bucket-name-123/athena-results/ → Save.

Без этого первый же запрос выдаст ошибку «No output location provided». Папку Athena создаст сама при первом запросе.

5. Копируем rank-файл за 2026 год из Common Crawl к себе.

Это копия S3 → S3 внутри Amazon:

RELEASE_NEW="cc-main-2026-feb-mar-apr"
aws s3 cp \
  "s3://commoncrawl/projects/hyperlinkgraph/${RELEASE_NEW}/domain/${RELEASE_NEW}-domain-ranks.txt.gz" \
  "s3://you-bucket-name-123/cc-ranks/domain/" --region us-east-1

aws s3 ls s3://you-bucket-name-123/cc-ranks/domain/ --region us-east-1

Важно: у старых релизов (2017 и ранее) формат пути другой - domaingraph/ranks.txt.gz, и его надо проверять через aws s3 ls.

Заархивированный файл в несколько гигабайт должен упасть за несколько минут.

Должна появиться строчка с domain-ranks.txt.gz и размером.

На этом всё. Переходим в браузере в AWS Athena.

6. В Query editor создаём базу данных за 2026 год.

Команда:

CREATE DATABASE IF NOT EXISTS commoncrawl_webgraph;

Создаём таблицу с данными:

CREATE EXTERNAL TABLE IF NOT EXISTS commoncrawl_webgraph.domain_ranks (
  harmonicc_pos bigint,
  harmonicc_val double,
  pr_pos        bigint,
  pr_val        double,
  host_rev      string,
  n_hosts       bigint
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE
LOCATION 's3://you-bucket-name-123/cc-ranks/domain/'
TBLPROPERTIES ('skip.header.line.count'='1');

Смоук-тест:

SELECT * FROM commoncrawl_webgraph.domain_ranks
ORDER BY harmonicc_pos
LIMIT 20;

Если сверху пойдут com.googleapis, com.google, и т.д. - таблица читается правильно.

7. Перегон в Parquet.

Текстовый gzip не сплитуется, каждый запрос читает его одним воркером. Конвертируем один раз, чтобы увеличить скорость обработки данных:

CREATE TABLE commoncrawl_webgraph.domain_ranks_parquet
WITH (
  format='PARQUET',
  write_compression='SNAPPY',
  external_location='s3://you-bucket-name-123/cc-ranks-parquet/domain/'
) AS
SELECT * FROM commoncrawl_webgraph.domain_ranks;

8. Копируем rank-файл за 2017 год из Common Crawl к себе.

Переходим обратно в WSL:

RELEASE_OLD="cc-main-2017-may-jun-jul"
aws s3 cp \
  "s3://commoncrawl/projects/hyperlinkgraph/${RELEASE_OLD}/domaingraph/ranks.txt.gz" \
  "s3://you-bucket-name-123/cc-ranks/domain-2017/" --region us-east-1

aws s3 ls s3://you-bucket-name-123/cc-ranks/domain-2017/ --region us-east-1

9. Создаём таблицу с данными за 2017 год.

CREATE EXTERNAL TABLE IF NOT EXISTS commoncrawl_webgraph.domain_ranks_2017 (
  harmonicc_pos bigint,
  harmonicc_val double,
  pr_pos        bigint,
  pr_val        double,
  host_rev      string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE
LOCATION 's3://you-bucket-name-123/cc-ranks/domain-2017/'
TBLPROPERTIES ('skip.header.line.count'='1');

10. Смоук-тест графа за 2017 год:

SELECT * FROM commoncrawl_webgraph.domain_ranks_2017
ORDER BY harmonicc_pos
LIMIT 20;

11. Перегон в Parquet.

CREATE TABLE commoncrawl_webgraph.domain_ranks_2017_parquet
WITH (
  format='PARQUET',
  write_compression='SNAPPY',
  external_location='s3://you-bucket-name-123/cc-ranks-parquet/domain-2017/'
) AS
SELECT * FROM commoncrawl_webgraph.domain_ranks_2017;

12. Финальная выборка: диф двух графов.

Берём домены из топа авторитетности по Harmonic Centrality в 2017-м, которых уже нет в графе 2026 (IS NULL). Этой метрики нет ни в одном сервисе аналитики сайтов и ни в одном аукционе доменов.

SELECT
  array_join(reverse(split(o.host_rev,'.')), '.') AS domain,
  o.harmonicc_pos AS hc_2017,
  o.pr_pos        AS pr_2017
FROM commoncrawl_webgraph.domain_ranks_2017_parquet o
LEFT JOIN commoncrawl_webgraph.domain_ranks_parquet n
  ON o.host_rev = n.host_rev
WHERE o.harmonicc_pos < 200000   -- калибруем порог HC под себя
  AND n.host_rev IS NULL
ORDER BY o.harmonicc_pos
LIMIT 1000000;

harmonicc_pos — это позиция (ранг) домена по harmonic centrality в графе. Значение, равно 1 - это самый авторитетный домен в мире в 2017 году, чем больше число, тем ниже авторитет. То есть < 200000 означает «оставить только домены, которые в 2017 году входили в топ-200 000 самых авторитетных в мире».

Ниже порог (например, < 50000): сверхмощные домены. Вариантов мало, каждый супер-авторитетный, но почти все заняты: топовые домены 2017-го редко кто бросает, их перекупают и продлевают. Тут можно найти домены на аукционах за десятки тысяч долларов. При покупке такого домена он начнёт очень быстро восстанавливать трафик из Google и появится в ответах ИИ-сервисов. Собственно, на этих доменах обучались (и продолжают обучаться) все LLM.

Выше порог (< 1000000 или < 5000000) — пул в разы больше, есть много свободных доменов. Средняя жирность домена ниже, но тоже ничего. Некоторые домены также могут оказаться на аукционе.

LIMIT 1000000 - сколько доменов попадёт в выгрузку.

Чтобы найти больше доменов можно сравнивать выгрузки по разным годам.

Проверить домены на занятость можно в bulkydomains.com и аналогичных сервисах. Итоговый список прогоняется через чекер с API сервисов по анализу сайтов, итоговый список проверяется вручную и по веб-архиву.