Как перенести блог с livejournal на WordPress?

Пишу этот пост с целью поделиться опытом. Сразу предупреждаю — этот путь не из простых, есть проще, но так интереснее 🙂

Постановка задачи

Дано: блог в ЖЖ, доступ в админку можно считать утерянным, т.к. владелец блога не позволяет соглашаться с неким дополнительным соглашением ЖЖ. Суть в том, что не ответив на него согласен, доступ в админку закрыт. Замкнутый круг. Стандартными инструментами для извлечения данных (например, формирования xml) не воспользоваться. Придётся парсить html.

Блог довольно старый, записей в нём много: за 4 года около 1500 записей. Есть картинки, комментарии, теги — всё это нужно перенести в блог на WP.

Реализация

Вытягиваем ссылки на все записи.

Для того, чтобы спарсить, для начала необходимо собрать ссылки на все страницы блога. Разумеется, отдельной страницы со ссылками на все записи одного аккаунта  у ЖЖ нет 🙂 Немного покликав по блогу обнаружил рубрику с архивом записей, вроде этой, а вот с неё уже можно перейти на архивы ссылок по месяцам. Отлично! То, что мне нужно. Будем парсить ссылки отсюда. Для этого я написал вот такой скриптик на php. Использована библиотека simple_html_dom.php. Документация: ссылка.

Этот скрипт сохраняет ссылки только на архивы за каждый месяц. Скрипт пришлось запустить несколько раз (по числу годовых архивов, страниц всего несколько — не было смысла автоматизировать). Ссылок на все записи у меня ещё нет. Для их получения я написал ещё один скрипт.

Теперь у меня есть список на все записи этого аккаунта ЖЖ. Каждая ссылка: https://borisakunin.livejournal.com/125938.html

Если бы в блоге было больше записей, например, 10 тысяч и выше, то все записи было бы правильнее перенести себе на хостинг при помощи wget. В этом случае, можно существенно сократить время выполнения скрипта.

Парсим страницы livejournal

Итак, у меня получился файл примерно в 1500 ссылок. Скрипт должен зайти на каждую страницу, вытянуть все необходимые данные и добавить их в БД WordPress. В конечном итоге все записи в новом блоге должны выглядеть так, будто они изначально там и были. Перед работой с WP лучше сделать дамп базы.

Итак, я написал вот такой скрипт (чуть ниже полный листинг). Что делает скрипт? Открывает файл с УРЛами, переходим по ссылке и загружает страницу, выбирает необходимые данные (те, что нужно перенести в блог на wordpress). Картинки из каждой записи, вернее ссылки на картинки я помещаю в 2 файла: file_images.txt — <img src=…> в теле записи и file_bigimages.txt — ссылки на большие картинки (только на те, что были загружены пользователем в ЖЖ).

Для того, чтобы вытянуть из html-страниц нужную информацию, помимо библиотеки simple_html_dom.php я использую регулярные выражения. Графические файлы не обязательно имеют расширение jpeg|jpg, поэтому пришлось поработать над регулярным выражением. В скрипте есть строки, которые можно удалить, в основном это касается элементов вывода информации, я использовал их для отладки и убирать не стал.

Я посчитал, что если копировать сразу 1,5тысячи страниц, то:

  • скрипт может хорошо нагрузить систему
  • будет долго выполняться

Рисковать не стал и принял решение обрабатывать не все страницы сразу, а только по 100 страниц за один запуск. Для этого и создан временный файл file_url3.txt Для его заполнения урлами, перед каждым запуском скрипта, я очищал файл и добавлял по 100 ссылок из основного файла. Делается это достаточно просто:

cat file_url.txt | head -n 200 | tail -n 100 > file_url3.txt

Перед каждым запуском скрипта достаточно добавлять +100 к head

Для тестового запуска лучше создать отдельную категорию в WordPress и создавать записи в ней, также можно убрать post_status=’publish’ и тогда все скопированные страницы будут иметь статус черновика и не будут отображаться на сайте.

Производительность

Скрипт не особенно нагружает систему (запуск производился на недорогом VPS с 512мб ОЗУ). Пиковая нагрузка — 13% использования cpu и пара процентов — озу.

Большую нагрузку показал wget, которым я выкачивал файлы с livejournal. Вот пример запуска wget:

Первый ключ запускает wget в фоновом режиме, -i задаёт путь к файлу где лежат ссылки на изображения. Надо отметить, что с регулярными выражениями я не ошибся, в список ссылок проскочил только один html файл. Блог существовал длительное время и за это время администрация ЖЖ несколько раз изменяла свою систему хранения и именования файлов. Если с ресурсами беда, то можно понизить приоритет wget.

Вот вывод wget:

Собственно всё.

Пути улучшения скрипта

Мой скрипт не добавляет графические файлы в медиа библиотеку WordPress, т.е. они не будут доступны через соответствующий пункт меню в админке. Хотя они отображаются в записях через обычный html код и хранятся в специально созданных директориях. Это можно реализовать при помощи соответствующей API функции WordPress.