Dmitriy Fofanov c8060867f4 Дополнение: добавлен скрипт зеркалирования сайта и утилита для исправления ссылок
- Создан новый файл `.gitignore` для исключения ненужных файлов и каталогов.

- Добавлен файл `LICENSE` с информацией об авторских правах и условиях использования.

- Реализован `crawl.js` для зеркалирования веб-сайта с использованием Playwright, включая функции обработки ссылок и ресурсов.

- Разработан `fix-links.js` для исправления внешних ссылок в HTML-файлах, чтобы они указывали на локальные ресурсы.

- Инициализированы `package.json` и `package-lock.json` с Playwright в качестве зависимости.
2026-02-22 01:32:43 +03:00

DFWebJS_DownLoad

Node.js-проект для зеркалирования сайта в локальную папку mirror/ с помощью Playwright (headless Chromium).

Проект включает два сценария:

  1. crawl.js — обходит страницы сайта, сохраняет HTML и ресурсы (CSS/JS/изображения/шрифты и т.д.).
  2. fix-links.js — пост-обработка уже скачанного зеркала: ищет внешние URL в HTML, догружает недостающие файлы и заменяет ссылки на локальные относительные пути.

Возможности

  • Обход внутренних страниц с очередью URL и ограничением по количеству страниц.
  • Параллельная загрузка (CONCURRENCY) для ускорения зеркалирования.
  • Перехват response в браузере и сохранение ассетов по Content-Type.
  • Автоповторы при ошибках (MAX_RETRIES).
  • Корректное завершение по Ctrl+C (graceful shutdown).
  • Нормализация путей для Windows (замена недопустимых символов).
  • Поддержка query-строк через хеширование имени файла, чтобы избежать перезаписи.
  • Опциональная замена абсолютных ссылок в HTML на относительные (FIX_LINKS).
  • Принудительное сохранение HTML в UTF-8 (<meta charset="utf-8">).

Стек и требования

  • Node.js 18+
  • npm
  • Playwright (playwright)
  • ОС: Windows / Linux / macOS

В package.json проект работает в режиме ES Modules ("type": "module").


Установка

npm install
npx playwright install

Если зависимостей ещё нет, альтернативно:

npm i playwright
npx playwright install

Быстрый старт

1) Скачивание сайта

node crawl.js

2) Дополнительная фиксация ссылок (опционально)

node fix-links.js

Как устроен crawl.js

Основной поток

  1. В очередь добавляется BASE.
  2. URL обрабатываются батчами по CONCURRENCY.
  3. Для каждой страницы:
    • выполняется page.goto(..., waitUntil: "domcontentloaded");
    • даётся дополнительная пауза WAIT_AFTER_LOAD;
    • выполняется попытка дождаться networkidle;
    • через page.on("response") сохраняются ассеты;
    • HTML сохраняется в mirror/;
    • извлекаются новые ссылки и добавляются в очередь.
  4. При ошибках применяются автоповторы до MAX_RETRIES.

Что скачивается

  • HTML-документы.
  • Скрипты, стили, изображения, шрифты.
  • XHR/fetch-ответы (с ограничениями, см. ниже).

Что фильтруется/ограничивается

  • Обход ограничен разрешёнными origin (ALLOWED_ORIGINS).
  • JSON-ответы без расширения .json пропускаются в загрузчике ассетов, чтобы не перезаписывать HTML.
  • URL с неподдерживаемыми схемами (data:, javascript:, mailto:, tel:, blob:) игнорируются.
  • Ассеты (по расширению) не попадают в очередь страниц.

Конфигурация crawl.js

Ключевые параметры находятся вверху файла:

  • BASE — стартовый URL обхода.
  • OUT_DIR — папка вывода (по умолчанию mirror).
  • MAX_PAGES — лимит страниц для обхода.
  • CONCURRENCY — количество одновременно открытых вкладок.
  • WAIT_AFTER_LOAD — задержка после domcontentloaded.
  • MAX_RETRIES — число повторных попыток для страницы.
  • REQUEST_TIMEOUT — таймаут навигации page.goto.
  • USER_AGENT — User-Agent браузера.
  • FIX_LINKS — включить замену ссылок в HTML на относительные в момент сохранения.
  • ALLOWED_ORIGINS — список origin, которые разрешено обходить/скачивать.

Как формируются локальные пути

  • URL-path сохраняется как путь внутри mirror/.
  • Путь, заканчивающийся на /, сохраняется как .../index.html (через index + расширение).
  • Query-строка хешируется (md5, 8 символов) и добавляется к имени файла.
  • Если у URL нет расширения, оно определяется по Content-Type; если определить нельзя — используется .html.
  • Символы, недопустимые в Windows-путях, заменяются на _.

Как устроен fix-links.js

fix-links.js предназначен для пост-обработки уже скачанного зеркала.

Что делает скрипт:

  1. Рекурсивно находит HTML/HTM-файлы в mirror/.
  2. Извлекает URL из src/href/srcset/poster/data-src/url(...).
  3. Для внешних ссылок:
    • проверяет домены по правилам ALLOWED_DOMAINS и SKIP_DOMAINS;
    • скачивает ресурсы в локальную структуру;
    • заменяет абсолютные ссылки на относительные пути.
  4. Ведёт статистику: обработано файлов, исправлено ссылок, скачано/пропущено/ошибки.

Ключевые параметры в fix-links.js:

  • MIRROR_DIR — папка зеркала.
  • DOWNLOAD_TIMEOUT — таймаут загрузки одного ресурса.
  • MAX_RETRIES — число повторов загрузки.
  • ALLOWED_DOMAINS — явно разрешённые домены для скачивания.
  • SKIP_DOMAINS — домены, которые нужно пропускать.

Логи и статус

crawl.js

  • [start] — старт обхода.
  • [config] — активные параметры.
  • [crawled] — страница сохранена.
  • [retry x/y] — повторная попытка.
  • [gave up] — страница не скачана после всех повторов.
  • [done] — итоговая статистика.

fix-links.js

  • 📄 Обрабатываю — файл в обработке.
  • 📥 Скачиваю / ✅ Скачано / Не удалось скачать.
  • Итоговый блок 📊 СТАТИСТИКА.

Ограничения

  • Это не «пиксель-в-пиксель офлайн-клон» сложных SPA/PWA.
  • Контент, подгружаемый только после действий пользователя (скролл/клик/hover), может не попасть в зеркало.
  • Внешние сервисы аналитики/соцсети/CDN могут оставаться внешними ссылками (зависит от доменных правил).
  • API-данные с динамическими эндпоинтами не гарантируется получить полностью.

Рекомендации по эксплуатации

  • Начинайте с меньшего MAX_PAGES и CONCURRENCY, затем увеличивайте.
  • При частых таймаутах увеличьте REQUEST_TIMEOUT и/или WAIT_AFTER_LOAD.
  • Если сервер ограничивает запросы, уменьшите CONCURRENCY.
  • Перед массовым запуском проверьте политики сайта (robots.txt, Terms of Service) и правовые ограничения.

Типичный workflow

  1. Настроить BASE и ALLOWED_ORIGINS в crawl.js.
  2. Запустить node crawl.js.
  3. Проверить структуру mirror/.
  4. При необходимости запустить node fix-links.js.
  5. Открывать локальные HTML из mirror/ для анализа/архивации/офлайн-просмотра.

Структура проекта

.
├─ crawl.js
├─ fix-links.js
├─ package.json
├─ README.md
└─ mirror/              # создаётся после запуска

Лицензия

ISC (см. package.json и LICENSE).

Description
Node.js-проект для зеркалирования сайта в локальную папку mirror/ с помощью Playwright (headless Chromium).
Readme 49 KiB
Languages
JavaScript 100%