Пайплайн wparc → metawarc: от WP-сайта к индексируемому архиву
Кейс демонстрирует короткий и воспроизводимый сценарий, в котором два инструмента Ruarxive работают последовательно: wparc снимает сайт на WordPress через REST API, а metawarc превращает результат в индексируемый каталог с метаданными, поиском и локальным веб-replay. Итог — архив, в котором можно искать фразу, видеть PDF рядом с HTML-страницей, на которой они лежали, и заходить на сайт «как он был».
Задача
Небольшой муниципальный сайт на WordPress (example.gov.ru):
- 1 200 постов, 180 страниц, 3 400 медиафайлов (в основном PDF-документы и JPEG-фотографии).
- Открытый REST API:
https://example.gov.ru/wp-json/wp/v2/. - Сайт запланировано перевести на новую CMS и через 2 недели вывести из эксплуатации.
Цель: сохранить всё содержимое до переезда и предоставить исследователям и сотрудникам муниципалитета удобный доступ к архиву — с поиском по тексту, метаданными PDF и возможностью открыть любую страницу в браузере.
Почему wparc, а не wget или Browsertrix
Сайт построен на стандартном WordPress и не использует JavaScript-рендеринг контента. Это означает, что:
- wparc отдаст чистые данные без навигации, рекламы и посторонней разметки. Один запрос
/wp/v2/posts?per_page=100заменяет 100 заходовwget'а. - wget/Browsertrix сохранят HTML-страницы, но без метаданных (авторы, теги, даты правок), и придётся потом парсить
meta-теги, чтобы их восстановить. - wget «зацепит» RSS-фид, административную панель, служебные эндпоинты — придётся фильтровать.
- Browsertrix здесь избыточен: нет ленивой загрузки и динамики, ради которой стоит тащить headless Chrome.
Этап 1. Сбор через wparc
# 1.1 Проверяем доступность API
curl -I https://example.gov.ru/wp-json/wp/v2/posts
# → HTTP/2 200 — API открыт
# 1.2 Запускаем архивацию с резюмированием (на случай обрыва)
wparc https://example.gov.ru/ \
--output ./wp-archive \
--resume \
--max-media-size 50M
wparc обходит /posts, /pages, /media, /comments, /users, /categories, /tags, скачивает медиа и сохраняет каждый объект JSON-ом с полными метаданными:
wp-archive/
├── posts/1.json
├── pages/about.json
├── media/45.jpg
├── media/46.pdf
├── comments.jsonl
├── authors.json
├── tags.json
├── categories.json
└── meta.json
Время: ~25 минут. Объём: 1.8 ГБ (1.1 ГБ — медиа, 0.7 ГБ — JSON).
Этап 2. Упаковка в WARC
wparc сохраняет результат как набор JSON-файлов, а не WARC. Чтобы дальше работал metawarc, нужно представить каждый JSON как HTTP-ответ. Используем короткий Python-скрипт — 30 строк:
# warcify.py
import json, pathlib
from warcio.warcwriter import WARCWriter
from io import BytesIO
archive = pathlib.Path("./wp-archive")
out = open("site.warc.gz", "wb")
writer = WARCWriter(out)
for path in sorted(archive.rglob("*.json")):
if path.name in {"authors.json", "tags.json", "categories.json"}:
continue
payload = path.read_bytes()
url = f"https://example.gov.ru/{path.relative_to(archive)}"
record = writer.create_warc_record(
url, "response",
payload=BytesIO(payload),
http_headers=(b"200 OK", [(b"Content-Type", b"application/json")]),
)
writer.write_record(record)
# И отдельно для бинарных медиа
for media in sorted((archive / "media").iterdir()):
payload = media.read_bytes()
mime = "application/pdf" if media.suffix == ".pdf" else "image/jpeg"
url = f"https://example.gov.ru/wp-content/uploads/{media.name}"
record = writer.create_warc_record(
url, "response",
payload=BytesIO(payload),
http_headers=(b"200 OK", [(b"Content-Type", mime.encode())]),
)
writer.write_record(record)
out.close()
pip install warcio
python warcify.py
# → site.warc.gz (1.8 ГБ)
Совет. Можно вместо WARC собрать всё через wpull — он умеет ходить по ссылкам из sitemap.xml и складывать результат сразу в WARC. Для сайта с API wparc быстрее, для «скраулинга по ссылкам» wpull удобнее.