- PVSM.RU - https://www.pvsm.ru -
Веб-архив — это система, которая периодически сохраняет сайт (или часть сайта) в его оригинальном виде. Чаще всего это делается для потомков, чтобы они могли «поиграться, покликать и поностальгировать [1]».
Основное требование к веб-архиву звучит просто и всеобъемлюще.
Офлайн-версия сайта должна быть полностью функциональной. В ней должны быть видны все оригинальные изображения, флэш-анимация, встроенное видео, работать скрипты и так далее. В идеале она не должна ничем отличаться от оригинала.
Для нас, разработчиков, выражение «полнофункциональная офлайн-версия» звучит очень, очень подозрительно. Можно даже сказать — крамольно звучит. Ведь современный сайт без скриптов не бывает, а скрипты всегда порождают неопределенность в поведении. Но, как говаривал один персонаж: «Не нужно спешить с выводами, не то выводы на тебя набросятся».
Честно говоря, в открытых источниках информации читать не перечитать. Можно начать со статьи в википедии [2]. К сожалению, о реализации там не очень много, а больше говорится об организационных и юридических проблемах.
Для интересующихся — рекомендую почитать. Для остальных приведу несколько терминов для общего развития.
Веб-архив [3]. Например, самый главный архив интернета — archive.org [4]. Пугает своими объемами [5] и сложностью использования [6].
Веб-краулер [7] — программа, которая умеет перебирать страницы стайта, переходя по ссылкам. В настоящее время их развелось очень много. Пожалуй, самый известный робот, посещения которого так ждут — Google Bot. Для POC мы пользовались ABot [8].
Построение системы целиком требует хранилища, интерфейсов и проч., но, к сожалению, в одну статью все не поместится. Поэтому тут я расскажу только о самой трудной части — алгоритме работы обхода сайта и сохранения данных.
Как решать задачу архивирования, думаю, очевидно. Сайты сделаны для Пользователей. Как поступает Пользователь? Открывает страницу, запоминает нужную информацию, переходит по ссылке на следующую страницу.
Попробуем сделать виртуального пользователя — робота, — и задачу немного автоматизировать.
«История» (привет, эджайл) работы робота выглядит так:
робот переходит со странцы на страницу по ссылкам (как пользователь). После перехода сохраняет страницу. Составляет список ссылок, по которым со страницы можно перейти. Уже пройденные ссылки игнорирует. Непройденные — сохраняет, и так далее.
Выглядит очень кратко, и очень абстракно. Первый шаг в проектировании всегда абстрактный, на то он и первый. Сейчас буду его детализировать.
Для начала нужно определить для себя, что будет базовой «неделимой» сущностью в нашей модели данных. Пусть это будет назваться «Ресурс». Определяю его так:
Ресурс — это любой контент, который мы можем скачать по ссылке.
То есть, основные его свойства — это наличие ссылки (URI) и контента, который возвращает сервер. Для полноты нужно дополнить описание ресурса метаданными (тип, ссылка, времея последнего изменения, и т.д.). Кстати, ресурс может содержать ссылки на другие ресурсы.
Исходя из этого понятия, определяю общий алгоритм работы краулера.
В целом, выглядит логично. Можно детализировать дальше.
Итак, робот нахоится в начале процесса: у него есть только ссылка на точку входа на сайт, так называемая index page. На этом шаге робот создает очередь, и кладет в нее ссылку на точку входа.
Если говорить абстрактно, то очередь представляет собой источник задач для робота. Сейчас очередь со своим единственным элементом выглядит так.

(Примечание: очередь обработки для небольших сайтов можно хранить в памяти, но для больших лучше сохранить в базе. На случай, если процесс прервется где-то посередине).
Выбрать из очереди ресурс для обработки. (На первой итерации это — точка входа). Скачать страницу и выяснить, на какие ресурсы она ссылается (referred resources).

Здесь, в общем, все просто. Страница находится по адресу site [9]. Робот скачивает ее и анализирует html-контент на предмет ссылок. (О типах ссылок см. «Виды ресурсов» ниже). Несколько ссылок указаны в примере: robots.txt (его робот игнорирует:), ссылка «О нас» — about.html, ссылки на CSS и Javascript файлы, ссылка на Youtube видеоролик.
Отфильтровать ненужные ресурсы. Для этого робот должен предоставлять очень гибкий настроечный интерфейс (большинство существующих таки делают). Например, робот должен уметь фильтровать файлы по типу, расшрению, размеру, времени обновления. Для исходящих ссылок также нужно проверять глубину вложенности. Очевидно, что если ресурс по какой-то ссылке уже обработан, то трогать его не стоит.
Для оставшихся, нужных ресурсов — создать структуры описания и поставить в очередь. Важно заметить, что структуры на этом этапе заполнены не полностью: в них указаны только оригинальные (онлайн) ссылки. (То есть, точно также, как и первоначальная точка входа на нулевом шаге).

Важно: на этом этапе контент страницы «Index page» все еще содержит оригинальные ссылки, и значит, не может быть использован как офлайн-версия. Для того, чтобы завершить обработку полностью, нужно заменить ссылки: они должны указывать на сохраненные офлайн-версии ресурсов. С использованием очереди реализовать это нетрудно: нужно задачу на обновление ссылок «Index page» поставить в конец очереди. Таким образом гарантируется, что к началу выполнения этой задачи все referred resources будут обработаны.

В целом, это есть шаг первый, только для каждого referred resources. (То есть в реализации алгоритм будет проще. Здесь шаги цикла развернуты для упрощения картины). На этом шаге робот извлекает очередное задание из очереди (задачи download, добавленные на предыдущем шаге).
Затем выясняет, каким преобразованиям требуется подвергнуть ресурс для использования в офлайне. В указанном примере все ресурсы просто скачиваются, за исключением «встроенного» видео: оно скачивается специальным образом через youtube и сохраняется как avi файл локально.
После этого формируются локальные (офлайн) ссылки для referred resources.

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

(В этом примере CSS файл ссылается на image.png).
Очередным заданием в очереди после удаления оттуда referred resources (и, разумеется, image.png) будет обновление ссылок в index page. Тут, возможно, для html-страниц придется менять и структуру. Например, офлайн-версию видео «встраивать» через какой-то свой проигрыватель.

Перейти на первый шаг и продолжать до тех пор, пока очередь не опустеет.
Алгоритм с использованием очереди страдает одним недостатком: ресурсы обрабатываются последовательно, а значит, не так быстро, как это может быть на современном сервере.
Поэтому стоит предусмотреть вохможность параллельной обработки. Есть два варианта параллелизма:
Микро-уровень вызывает вопросы с блокировками. Если вспомнить, то задача «обновление ссылок» ставится в конец очереди именно для консистентности. Мы ожидаем, что к моменту запуска этой задачи все связанные ресурсы уже получили локальные ссылки и обработаны. При параллельной работе это условие нарушается, и нужно будет вводить точки синхронизации. Например, простой вариант: запускать задачи на скачивание асинхронно. При появлении задачи на обновление ссылок — дождаться завершения активных задач на скачивание (так называемые Barrier). Сложный вариант — вводить зависимости между задачами в явном виде через семафоры. Может быть, есть еще варианты, не анализировал глубоко.
Очевидно, что нельзя предусмотреть все виды ресурсов, с которыми приходится иметь дело такому краулеру. Но мы попробуем, как минимум для того, чтобы знать, с какими трудностями придется столкнуться.
Робот задает мне вопрос: «А все же — что мы решили насчет динамических страниц, скриптов, и проч.»? Отвечаю: на проверку оказывается, что не все страницы одинаково «динамичны». Я определяю следующие уровни «динамичности» страниц:
Чем больше уровень динамичности, тем сложнее сохранить офлайн-контент:

Работает примерно как Firebug, с той разницей, что это из .Net.
Но предложить решение — мой долг. Выполняю. У меня есть даже два варианта.
Вариант с оператором.
Вариант с машинным обучением или скриптом. В целом, похож на первый вариант, но шаги оператора явно или неявно запоминаются для дальнейшего автоматизированного воспроизведения. Можно применить автоматические классификаторы и даже нейросети: для исследователей тут необъятное поле возможностей. К сожалению, мы не исследователи, а разработчики. Трудоемкость, если честно, оценить не возьмусь.
Помимо робота, в системе веб-архива должны присутствовать хранилище, индексация и интерфейс — я их сознательно исключил из рассмотрения. Во-первых, эти компоненты довольно просты и в интеграции и настройке по сравнению с роботом. Во-вторых, чтобы просто не отвлекали.
Систему веб-архивирования можно построить за приемлимое время, но она будет обладать ограничениями из-за динамической природы современных сайтов. Динамические страницы вплоть до третьего уровня поддаются приемлимой архивации. Для четвертого уровня потребуется довольно много усилий.
В целом, существует два пути развития роботов. Первый — с применением искусственного интеллекта. Необходимо развивать краулер так, чтобы он «понимал», что делает. Второй — технологический. Необходимо создать платформу для сайтов, что-то вроде умного CMS. Работающие на ней сайты могли бы выставлять роботам контент в простом для архивации виде.
Автор: nchaly
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/analiz-i-proektirovanie-sistem/38314
Ссылки в тексте:
[1] поностальгировать: http://www.coca-colacompany.com/stories/1s-and-0s-the-history-of-the-coca-cola-companys-website
[2] статьи в википедии: http://en.wikipedia.org/wiki/Web_archiving
[3] Веб-архив: http://www.wikireality.ru/wiki/Веб-архив
[4] archive.org: http://archive.org/index.php
[5] объемами: http://archive.org/web/petabox.php
[6] сложностью использования: http://archive.org/about/using.php
[7] Веб-краулер: http://ru.wikipedia.org/wiki/Поисковый_робот
[8] ABot: http://code.google.com/p/abot/
[9] site: http://site
[10] Источник: http://habrahabr.ru/post/185816/
Нажмите здесь для печати.