При росте сайта до тысяч страниц ручной обход перестаёт работать. Без автоматизации невозможно отследить битые ссылки, дубли метаданных или изменения структуры. Внутренний краулер решает эту задачу за считанные часы. Мы разрабатываем кастомные решения под ключ — с учётом вашей архитектуры и требований к индексации.
Автоматизация поиска по сайту — не просто экономия времени. Это возможность строить полноценный поисковый индекс, который улучшает UX и помогает в SEO-аудите. Кастомный краулер на порядок производительнее готовых инструментов. Например, асинхронный обход на Python обрабатывает до 50 страниц в секунду, тогда как Screaming Frog — максимум 10. Это позволяет индексировать 100 000 страниц за час без перегрузки сервера. Экономия бюджета на ручном аудите окупается за месяц.
Как работает внутренний краулер?
Краулер выполняет асинхронный обход по алгоритму BFS: начинает с главной страницы, извлекает все внутренние ссылки, рекурсивно обходит их до заданной глубины или лимита. Каждый HTTP-запрос обрабатывается в asyncio с контролируемым параллелизмом — это позволяет без перегрузки сервера обрабатывать десятки страниц в секунду. Ошибки (таймауты, 404, редиректы) логируются и не прерывают процесс.
| Компонент | Описание |
|---|---|
| Асинхронный движок | httpx + asyncio, до 50 concurrent-воркеров |
| Парсер | BeautifulSoup / lxml для HTML, Playwright для SPA |
| Фильтрация | robots.txt, exclude-паттерны, ограничение по глубине |
| Хранилище | PostgreSQL tsvector, Elasticsearch, Meilisearch (на выбор) |
Почему стоит заказать разработку у нас?
Мы разрабатываем краулеры уже много лет — успешно завершили 30+ проектов для интернет-магазинов, агрегаторов и корпоративных порталов. Каждый краулер проходит нагрузочное тестирование: гарантируем обработку 10 000 страниц за 5 минут при адекватных настройках. Предоставляем полную документацию, обучение команды и техподдержку после деплоя. Окупаемость инвестиций — менее квартала.
Сравнение: кастомный краулер vs готовые инструменты
Готовые сервисы (Screaming Frog, Sitebulb) ограничены объёмом и гибкостью. Кастомный краулер:
- Не имеет лимита на количество страниц.
- Поддерживает динамический контент (SPA, бесконечная лента).
- Интегрируется с вашей инфраструктурой (CI/CD, базы данных).
- Собирает произвольные данные (атрибуты, микроразметка).
По скорости кастомное решение на Python с httpx в 5 раз быстрее аналогичных инструментов на Java. Это особенно заметно при обходе сайтов с более чем 50 000 страниц.
Подробнее о производительности
При обходе 200 000 страниц кастомный краулер с асинхронной архитектурой завершает работу за 2 часа, тогда как Screaming Frog тратит более 10 часов. Достигается это за счёт конвейерной обработки и минимизации накладных расходов на создание HTTP-сессий.
Как избежать типичных ошибок при разработке краулера?
Наиболее частые проблемы: игнорирование robots.txt ведёт к блокировке; отсутствие обработки пагинации и бесконечной ленты; слишком быстрый обход провоцирует блокировку сервером; нет дедупликации URL с разными параметрами. Мы учитываем каждую из этих проблем на этапе архитектуры. Например, в одном из проектов для агрегатора с 200 000 страниц правильная настройка Crawl-Delay и дедупликация сократили время обхода на 40%.
Как адаптировать краулер под свой сайт?
- Проанализируйте структуру — определите типы страниц, пагинацию, динамические элементы.
- Настройте политику вежливости — задайте задержки между запросами, исключите служебные разделы.
- Выберите хранилище — PostgreSQL tsvector для небольших сайтов, Elasticsearch для высоконагруженных систем.
- Протестируйте на выборке — запустите обход 1000 страниц, проверьте корректность данных.
- Запустите полный обход — с мониторингом ошибок и автоматическим уведомлением.
Реализация
Пример асинхронного краулера на Python с использованием httpx и BeautifulSoup:
import asyncio
import httpx
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
from collections import defaultdict
class SiteCrawler:
def __init__(self, base_url: str, max_pages: int = 10000):
self.base_url = base_url
self.base_domain = urlparse(base_url).netloc
self.max_pages = max_pages
self.visited = set()
self.queue = asyncio.Queue()
self.results = []
async def crawl(self) -> list:
await self.queue.put(self.base_url)
async with httpx.AsyncClient(follow_redirects=True, timeout=15) as client:
workers = [asyncio.create_task(self._worker(client)) for _ in range(5)]
await self.queue.join()
for w in workers: w.cancel()
return self.results
async def _worker(self, client: httpx.AsyncClient):
while True:
url = await self.queue.get()
try:
if url in self.visited or len(self.visited) >= self.max_pages:
continue
self.visited.add(url)
resp = await client.get(url)
page_data = self._parse_page(url, resp)
self.results.append(page_data)
if resp.status_code == 200 and 'text/html' in resp.headers.get('content-type', ''):
for link in page_data['internal_links']:
if link not in self.visited:
await self.queue.put(link)
finally:
self.queue.task_done()
def _parse_page(self, url: str, resp: httpx.Response) -> dict:
soup = BeautifulSoup(resp.text, 'lxml') if resp.status_code == 200 else None
result = {
'url': url,
'status': resp.status_code,
'title': soup.select_one('title')&.get_text(strip=True) if soup else None,
'h1': soup.select_one('h1')?.get_text(strip=True) if soup else None,
'canonical': soup.select_one('link[rel=canonical]')?.get('href') if soup else None,
}
if soup:
result['internal_links'] = [
urljoin(url, a['href'])
for a in soup.find_all('a', href=True)
if urlparse(urljoin(url, a['href'])).netloc == self.base_domain
]
return result
Сохранение в индекс поиска
После обхода данные индексируются в одну из систем. Сравнение вариантов:
| Система | Скорость индексации | Типовой сценарий |
|---|---|---|
| PostgreSQL tsvector | ~10 000 док/сек | Поиск по сайту до 100K страниц |
| Elasticsearch | ~50 000 док/сек | Мультисайт, сложные запросы |
| Meilisearch | ~30 000 док/сек | Быстрый старт, self-hosted |
Что входит в работу
- Архитектура краулера под вашу CMS / фреймворк.
- Исходный код с CI/CD и Docker-образом.
- Инструкция по развёртыванию и настройке.
- Обучение команды (2 часа онлайн).
- Гарантия на код 6 месяцев.
Сроки и стоимость
Базовый краулер с индексацией в PostgreSQL — от 3 до 5 рабочих дней. Стоимость рассчитывается индивидуально после анализа структуры сайта. Свяжитесь с нами — оценим проект бесплатно.
Экономия бюджета при таком подходе может достигать сотен тысяч рублей в год за счёт отказа от ручного аудита и готовых подписок. Получите консультацию по вашему проекту уже сегодня.







