aboutsummaryrefslogtreecommitdiff

vk-messages-post-archive

Дисклеймер: информация актуальна на осень 2020 года. Может, во ВКонтакте уже всё поменялось и скрипт более не нужен, а может, поменялся формат отдаваемого архива и скрипт не сработает. Смотрите сами.

Во ВКонтакте существует функция выгрузки информации в ZIP-архиве, в т.ч. всех сообщений. Сделана она как попало: история сообщений, полученная таким образом, содержит только текст самих сообщений (там даже нет пересланных! сложно было положить, что ли?), ссылки на фото и нерабочие (!) ссылки на документы. Но лучше так, чем никак.

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

Это проще, чем выкачивать всё через API с нуля. Пусть ВКонтактик соберёт нам свой архив, там уже есть более-менее нормальная навигация и оформление, а мы потом просто скачаем все, чего не хватает. Все-таки простых текстовых сообщений без вложений должно быть на порядок больше.

Системные требования

  • bash
  • PHP >= 7.1
    • composer
    • php-iconv
    • php-curl
    • наверное, неплохой идеей будет включить opcache для cli в php.ini (путь которого можно узнать через php --ini): opcache.enable=1 opcache.enable_cli=1 opcache.file_cache=/tmp/php-opcache
  • iconv
  • wget
  • sqlite3
  • стандартные утилиты типа cat, find, grep, xargs и т.д.

"Поехали", как говорил Юра

Скачиваем фоточки

Склонили репозиторий, устанавливаем зависимости:

git clone https://github.com/gch1p/vk-messages-post-archive
cd vk-messages-post-archive
composer install

Перейти в папку с распакованным архивом от ВК:

cd path/to/Archive

Запускаем нехитрый парсер:

for f in $(find messages -type f -name "*.html"); do
    cat "$f" | iconv -f windows-1251 | php path/to/get-attaches.php >> to-download.txt
done

В файле to-download.txt будут ID сообщений с аттачами вперемешку со ссылками на фотки.

Выкачиваем фотки. -P8 означает, что будет параллельно запущено 8 процессов wget. Можете написать другое число.

cat to-download.txt | grep https | xargs -P8 wget -x -i

Заменяем ссылки (<a>) на изображения (<img>). Тут в -P разумно передать количество ядер.

find messages -type f -name "*.html" | xargs -I{} -P4 php path/to/replace-photos.php "{}"

Достаём остальную информацию из API

Теперь давайте залезем в API. ВК недавно отключил сторонним приложениям доступ к сообщениям, но кого это остановит? Скачайте десктопный мессенджер, авторизуйтесь в нём, потом закройте и зайдите в папку, где он хранит конфиг (~/.config/VK на Linux, ~/Library/Application Support/VK на маке, на винде по логике должно быть %APPDATA%\Roaming\VK), там будет sqlite3 база vk.db. Зайдём в неё:

sqlite3 vk.db

Осмотримся.

sqlite> .tables
auth             debug_api_fails  recents          users          
communities      friends          settings

Хм, табличка auth выглядит многообещающе. Посмотрим структуру:

sqlite> .schema auth
CREATE TABLE auth (
  id INTEGER PRIMARY KEY,
  user_id INTEGER,
  ts INTEGER,
  access_token TEXT
, is_encrypted INTEGER);

О! То, что нужно. Нам нужен access_token.

sqlite>  SELECT access_token FROM auth;

Скопируйте токен и можно выходить (Ctrl+D) отсюда.

Теперь откройте скрипт common.php и пропишите этот токен в константу ACCESS_TOKEN, а так же путь к папке Archive в константу ARCHIVE_DIR.

После этого можно запустить скрипт fetch-messages.php для слива объектов сообщений. Они будут сохраняться в папку api с именами {dir}/{id}.txt, где {id} – это ID сообщения, а {dir} – это остаток от деления ID сообщения на 100.

Метод messages.getById вконтактовского API может вернуть до 100 сообщений за 1 запрос, плюс нужно учитывать стандартное ограничение на 3 запроса в секунду, иначе нам прилетит капча. xargs поможет запустить не более 3-х инстансов скрипта за раз и передать не более 100 идентификаторов в каждый, а sleep(1) сделает сам скрипт в конце.

cat to-download.txt | grep -v https | xargs -n100 -P3 php path/to/fetch-messages.php

Теперь добавим возможность просмотра этих объектов на страничках истории.

find messages -type f -name "*.html" | xargs -I{} -P4 php path/to/insert-api-objects.php "{}"

Скачиваем документы

php fetch-documents.php

Ну вот, вроде, и всё.