ahref: от парсера ссылок к графу сайта на Rust

Как я переделал ahref в CLI-краулер: sitemap, анкоры, глубина страниц, внутренний PageRank и экспорт графа для анализа перелинковки.

12.09.2026 · 3 мин чтения

Первая версия ahref решала маленькую задачу: извлечь теги ссылок и URL из HTML. Но список ссылок одной страницы не отвечает на вопрос, как устроен сайт целиком. Какие материалы доступны только из sitemap? Через сколько переходов посетитель найдёт статью? Какие страницы получают ссылки из разных частей сайта? Я переделал ahref в Rust CLI-краулер, который строит ориентированный граф.

Узлы графа — нормализованные URL. Рёбра — обнаруженные ссылки a href с текстом анкора и rel. Сохранённый граф можно анализировать повторно без сетевых запросов. Для работы не нужны аккаунт, API-ключ или подключение к LLM.

Установить текущую версию из исходников

git clone https://github.com/tenqz/ahref.git
cd ahref
cargo install --path . --locked
ahref --version

Для сборки нужен Rust 1.90 или новее. Установка из checkout здесь намеренная: старые опубликованные версии ahref были HTML-парсерами, и наличие локальной сборки 1.0.0 само по себе не означает публикации этой версии в registry. Команды CLI описывают новую реализацию.

Обойти сайт и сохранить результат

ahref crawl https://example.com/sitemap.xml --max-pages 1000 --concurrency 3 --output graph.json
ahref analyze graph.json
ahref export graph.json --format graphml --output site.graphml

Входом может быть обычный URL, sitemap, индекс sitemap или сжатая карта .xml.gz. Если начать с sitemap, её URL и главная страница становятся исходными точками обхода. Ссылки в HTML помогают найти дополнительные страницы. Карта не обнаруживается автоматически, поэтому для поиска кандидатов в страницы-сироты лучше передать её явно.

--max-pages ограничивает бюджет запросов страниц, включая редиректы и HTTP-ошибки. --concurrency ограничивает одновременные запросы. Правила robots учитываются по умолчанию. Небольшой параллелизм позволяет начать исследование без лишней нагрузки на собственный сервер.

Какие вопросы можно задать графу

Число входящих соседей показывает, со скольких разных страниц есть ссылки на URL. Повторяющиеся ссылки остаются в графе, но степень узла считает уникальных соседей. Это позволяет отличить десять повторов ссылки на одной странице от десяти самостоятельных источников перехода.

Глубина считается от главной страницы по наблюдаемым переходам. URL, известный только из sitemap, не становится близким к главной автоматически: пока путь не найден, его глубина равна null. Страница из sitemap без входящей ссылки с другого внутреннего URL считается кандидатом в сироты. При ограниченном обходе это гипотеза для проверки, а не окончательный диагноз.

Внутренний PageRank помогает сравнить распределение связей в полученном графе. Он рассчитывается по уникальным внутренним соседям и включает гиперссылки с nofollow. Это метрика данной модели сайта, а не оценка Google и не прогноз позиции в поиске. Её полезно читать вместе с глубиной и назначением страницы.

Ошибки и редиректы не стоит превращать в догадки

Ссылка считается битой по наблюдаемому HTTP-статусу 400 и выше, в том числе через проверенную цепочку редиректов. Тайм-аут, внешняя ссылка и ещё не загруженная страница не объявляются битыми. Редиректы записываются отдельными метаданными и не изображаются выдуманными гиперссылками.

Страница без исходящих внутренних ссылок считается тупиком только после успешной загрузки HTML. Заблокированный или не загруженный URL не подходит под это определение. Такие детали нужны, чтобы технический отчёт не превращал неизвестное состояние в уверенную рекомендацию.

Экспорт и границы обхода

JSON подходит для собственного обработчика, GraphML — для Gephi, DOT — для Graphviz. Команды analyze и export работают с сохранённым файлом без нового обхода. Это удобно, когда хочется пересчитать метрики или получить другую визуализацию того же наблюдения.

ahref не исполняет JavaScript и не проверяет статусы внешних ссылок. www и основной домен не объединяются автоматически. Краулер сохраняет различия HTTP/HTTPS, завершающего слеша и query-параметров. Эти варианты могут обозначать разные ресурсы, и склеивать их без проверки было бы потерей информации.

Граф дополняет поисковые данные

Для меня ahref отвечает на вопрос о структуре сайта. GSC MCP и Webmaster MCP отвечают на вопросы к поисковым системам. Сам ahref не хранит историю, не подключает GSC и не генерирует SEO-рекомендации. Сравнение снимков и поисковой динамики выполняет отдельная система.

Кейс: архитектура ahref · Исходный код · Схема графа

Олег Пацай

Инженерный лидер — AI, архитектура и сложные системы

Проектирую и развиваю сложные программные системы: от архитектуры и инженерных практик до интеграции AI в разработку.

GitHub LinkedIn Telegram Связаться

Давайте делать сложное понятным.

Архитектура, инженерное лидерство и AI в разработке — когда система слишком важна, чтобы её упрощать, и слишком дорогая, чтобы ею не владеть.

LinkedIn Telegram Email