Выгрузка данных из ВК

NB: This is an old article (2021). Everything may have changed since publication.


Решил, что всё-таки нужно удалиться из ВКонтакте. Давно не пользуюсь, но меня расстраивала перспектива потерять список друзей, фотографии, и все те данные, что я отправлял ВК все эти годы.

ВК не так давно добавил возможность выгрузить архив своих данных, его можно запросить на странице /data_protection. В моём случае архив готовился около суток.

К сожалению, архив оказался далеко не полным — в нём нет ни контактов друзей (только имя с ссылкой на профиль ВКонтакте), ни фотографий (вместо них тег img с src, указывающим на сервера ВК), ни файлов, загруженных в раздел «Документы». Аудиофайлов тоже нет — только названия композиций (но хотя бы плейлисты есть). В целом, это набор перелинованных между собой HTML-страниц в кодировке Windows-1251.

И если отсутствие контактов ещё можно понять (это всё-таки данные других людей), то отсутствие фотографий уже не очень.

Сохраняем фотографии

При помощи такого скрипта можно вытащить ссылки на изображения.

find photos/photo-albums -iname '*.html' | xargs -I% perl -lne 'print "$1.jpg", "\t", $2 if /<a href="https:\/\/vk.com\/([^"]+)"><img src="([^"]+)"/' % >names_urls.txt

После этого при помощи wget можно скачать эти файлы по списку. Я уверен, что это можно сделать как-то изящнее (посоветуйте как!).

perl -lne '`wget -O "$1" "$2" &` if /([^\t]+)\t([^\n]+)$/' names_urls.txt

Сохраняем фотографии из сообщений

Дальше я захотел разложить фотографии из сообщений по соответствующим папкам диалогов.

find messages -name '*.html' | xargs -I% perl -lne "print \$ARGV, \"\t\", \$1 if /<a class='attachment__link' href='([^']+)'>/" % >messages_attachments.txt

В эту выборку попадают все ссылки-аттачменты, поэтому я отдельно вытащил ссылки с userapi.com — похоже, что фотографии лежат там.

grep 'userapi.com' messages_attachments.txt >messages_attachments_userapi.txt

Опять-таки, явно можно сделать лучше, но эта ерунда раскладывает фотографии по соответствующим директориям беседы.

cat messages_attachments_userapi.txt | perl -MFile::Basename -alne 'my $localfile = dirname($F[0]) .  "/" . basename(split(/\?/, $F[1])); `wget -O "$localfile" "$F[1]"`'

Вполне вероятно, что сами фотографии будут жить на серверах ВК ещё долго после удаления аккаунта, но приятно иметь локальную копию.

Бонус-раунд: поиск по переписке

По идее, можно было бы просто искать по этим файлам, но они лежат в кодировке cp1251. iconv позволяет перекодировать в единственную нормальную кодировку (UTF-8), а ripgrep умеет запускать скрипт, прежде чем искать внутри файла.

Создал такой примитивный скрипт:

#!/bin/sh

iconv -f cp1251 $1

И можно примитивно искать:

rg --pre ./prescript.sh --pre-glob 'messages/*/*.html' -g 'messages/*/*.html' 'Тим из будущего'

Нашёл такое сообщение:

Ха, с этим будет разбираться Тим из будущего, аее

  • 18 ноября 2016 года

😢

Тим опубликовал