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
Ну вот, вроде, и всё.