Dump VK
Статья для участия в конкурсе Конкурс 2018 года - авторская статья по любой тематике нашего форума!
Всем привет, в этой статье я вас научу делать дамп данных из вк, а вернее напишем инструмент на python для автоматизации данного процесса.
"Из коробки" доступен дамп:
Приступим к созданию проекта. Этапы:
Часть 1 - Разберем на пальцах
Часть 1. Разберем на пальцах
Можем приступать к коддингу. Создайте файл run.py и откройте его. Для начала задайте структуру модуля:
Теперь заполняем функцию main - в ней разберемся с основным механизмом нашего будущего инструмента.
Авторизация в приложении.
В структуре указаны: имя, фамилия, адрес страницы (короткая ссылка, id), пол, дата рождения, страна, город, статус, телефон.
Для входа по логину-паролю замените строчку "vk_session = ..." на:
Соберем авторизацию вк в одну функцию и добавим обработку 2FA и CAPTCHA:
Получение данных
Для понимания механизмов получения альбомов и документов введем две функции:
Как видим, у данного пользователя 3 альбома, в каждом по size фотографий (всего 24 шт.)
В поле count - количество всех документов(элементов 'items') у текущего пользователя, а в поле items - список самих документов(id, кто выложил, когда, с каким именем, размером, расширением)
Для доступа к фотографиям в альбоме, введем в main новую переменную vk_tools:
Преобразим функцию получения альбомов:
Также как и с альбомами, оставим только нужные нам данные для документов:
Теперь разберем функции получения диалогов и сообщений. Этот метод сложнее предыдущих и значительно объемнее по коду (ввиду обработки только нужных полей и аттачментов).
В простейшей реализации, все сообщения можно собрать таким способом:
Метод собирает все сообщения, однако, в этой структуре много лишней информации. Если выделить только id, имя диалога, сообщения и вложения нужных типов, то метод сбора разрастется до подобного кода:
На этом все нужные данные собраны, теперь научимся скачивать файлы.
Скачивание файлов.
В простом представлении фукнкция выглядит так:
На самом деле, если совсем минимизировать(исключительно для понимания механизма), то получится такая функция:
В первом варианте, учитывается отказ от повторного скачивания файла и обработка ошибочного запроса (не вылетает из программы при ошибке).
По поводу повторного скачивания: если файл с таким именем существует, значит не скачиваем заново. Для данного проекта актуально, так как мы формируем уникальное имя файла по id. Для других проектов, эта "проверка на повторное скачивание" не является достоверной.
Теперь адаптируем скачивание под наши цели + добавим многопоточность:
Теперь мы можем скачивать любые файл из наших структур. Вот пример как это делать:
Конец первой части. Полученный код можете посмотреть в прикрепленных файлах - sandbox.py
Часть 2 - Наведение красоты
Теперь соберем все наработки в обособленные классы. Выделим следующие классы:
Провел рефакторинг и добавив некоторые функции:
Подробнее про дамп-менеджер:
Best-way эксплуатация:
На последок создадим exe версию приложения для Windows:
Находясь в виртуальном окружении установите модуль:
Для автоматизации процесса рекомендую использовать bat файл следующего вида:
Этот батник соберет весь код vk.py в один файл vk_dump.exe, с иконкой vk.ico
Приложенные архивы:
Статья для участия в конкурсе Конкурс 2018 года - авторская статья по любой тематике нашего форума!
Всем привет, в этой статье я вас научу делать дамп данных из вк, а вернее напишем инструмент на python для автоматизации данного процесса.
"Из коробки" доступен дамп:
- Фото (из всех альбомов в том числе личных)
- Документы
- Диалоги
- сообщения {'from', 'text', 'date'}
- вложения (photo, docs, audio_message)
Приступим к созданию проекта. Этапы:
Часть 1 - Разберем на пальцах
- Подготовка
- Создание приложения Вконтакте
- Настройка виртуального окружения
- Авторизация в приложении
- Получение данных
- Выкачивание данных
- Упаковка наработок в классы
- + Читаемый размер документов(КБ, МБ, ГБ)
- + json-коллекции
- Добавление дамп-менеджера
- Сбор данных
- Скачивание данных
- Обработка ошибок
Часть 1. Разберем на пальцах
Для работы vk_api требуется APP_ID. Вы можете использовать мое приложение, доступ к вашим данным я не получу. Но кратко расскажу, как создать свое приложение вконтакте:
Перейдите по ссылке
Перейдите по ссылке:
Разрешив доступ к аккаунту, откроется страница OAuth Blank, в адресе которой будет ваш token (access_token=*** до &expires).
Перейдите по ссылке
https://vk.com/apps?act=manage
и нажмите на "Создать приложение". Укажите название (любое) и тип standalone. Подтвердите создание с помощью sms. Подтвердив, откроется страница с приложением, нам интересен его id. Копируем id и вставляем в ссылку ниже (на место client_id). Сейчас там ссылка на оф. приложение android.Перейдите по ссылке:
https://oauth.vk.com/authorize?client_id=2890984&scope=notify,photos,friends,audio,video,notes,pages,docs,status,questions,offers,wall,groups,messages,notifications,stats,ads,offline&redirect_uri=http://api.vk.com/blank.html&display=page&response_type=token
Разрешив доступ к аккаунту, откроется страница OAuth Blank, в адресе которой будет ваш token (access_token=*** до &expires).
Для удобной организации модулей, создадим виртуальное окружение python:
В директории с проектом(пока пустым) в терминале/командной строке введите:
В директории с проектом(пока пустым) в терминале/командной строке введите:
python -m venv env
call env\scripts\activate (windows)
source env\bin\activate (linux)
pip install vk-api requests
Можем приступать к коддингу. Создайте файл run.py и откройте его. Для начала задайте структуру модуля:
Python:
# импорт модуля вк
import vk_api
def main():
pass
# точка входа в приложение
if __name__ == '__main__':
main()
Теперь заполняем функцию main - в ней разберемся с основным механизмом нашего будущего инструмента.
Авторизация в приложении.
Python:
def main():
# версия api и id приложения
API_VERSION = '5.92'
APP_ID = 6781880
# вводим токен от аккаунта вк
token = ''
# создаем сессию по токену
vk_session = vk_api.VkApi(token=token, app_id=APP_ID, api_version=API_VERSION)
# получаем доступ к апи сессии
vk = vk_session.get_api()
# для проверки подключения запоминаем данные профиля
account = vk.account.getProfileInfo()
# и выводим данные на экран
print(account)
JSON:
{'first_name': '', 'last_name': '', 'screen_name': '', 'sex': , 'relation': 0, 'bdate': '', 'bdate_visibility': 1,
'home_town': '', 'country': {'id': 1, 'title': 'Россия'}, 'city': {'id': 1, 'title': ''}, 'status': '', 'phone': ''}
Для входа по логину-паролю замените строчку "vk_session = ..." на:
Python:
vk_session = vk_api.VkApi(login, password, app_id=APP_ID, api_version=API_VERSION)
vk_session.auth(token_only=True, reauth=True)
Соберем авторизацию вк в одну функцию и добавим обработку 2FA и CAPTCHA:
Python:
import vk_api
API_VERSION = '5.92'
APP_ID = 6781880
# 2FA обработчик
def auth_handler():
key = input('Введите код двухфакторной аутентификации: ')
remember_device = True
return key, remember_device
# captcha обработчик
def captcha_handler(captcha):
key = input(f"Введите капчу ({captcha.get_url()}): ").strip()
return captcha.try_again(key)
# авторизация по токену или логин-паролю
def login_vk(token=None, login=None, password=None):
try:
# если токен введен
if token:
# то создаем сессию с ним
vk_session = vk_api.VkApi(token=token, app_id=APP_ID, auth_handler=auth_handler, api_version=API_VERSION)
# иначе если введены login password
elif login and password:
# то создаем сессию с этими данными
vk_session = vk_api.VkApi(login, password, captcha_handler=captcha_handler, app_id=APP_ID,
api_version=API_VERSION, auth_handler=auth_handler)
# авторизуемся (использовать для пароля-логина)
vk_session.auth(token_only=True, reauth=True)
# иначе, если данных недостаточно, то бросаем исключение
else:
raise KeyError('Не введен токен или пара логин-пароль')
# возвращаем апи к сессии
return vk_session.get_api()
# в случае ошибки, выводим сообщение на экран
except Exception as e:
print(e)
def main():
# вводим токен
token = ''
# логинимся по токену
vk = login_vk(token)
# получаем инфо профиля
account = vk.account.getProfileInfo()
# выводим на экран профиль
print(account)
if __name__ == '__main__':
main()
Получение данных
Для понимания механизмов получения альбомов и документов введем две функции:
Python:
def get_albums(vk):
albums = vk.photos.getAlbums(need_system=1)['items']
print(albums)
def get_docs(vk):
docs = vk.docs.get()
print(docs)
JSON:
[
{'id': -6,'thumb_id': num,'owner_id': num,'title': 'Фотографии с моей страницы','size': 3},
{'id': -7,'thumb_id': num,'owner_id': num,'title': 'Фотографии на моей стене','size': 19},
{'id': -15,'thumb_id': num,'owner_id': num,'title': 'Сохранённые фотографии','size': 2}
]
JSON:
{
'count': 344,
'items': [{'id': num, 'owner_id': num, 'title': 'VK.zip', 'size': 4093,'ext': 'zip',
'url': '<url>', 'date': 1540842757, 'type': 2}]
}
Для доступа к фотографиям в альбоме, введем в main новую переменную vk_tools:
vk_tools = vk_api.VkTools(vk)
Преобразим функцию получения альбомов:
Python:
def get_albums(vk, vk_tools):
# результирующий список альбомов
albums = []
# обрабатываем каждый альбом
for album in vk.photos.getAlbums(need_system=1)['items']:
# получаем список фотографий из альбома
photos = vk_tools.get_all(values={'album_id': album['id'], 'photo_sizes': 1}, method='photos.get', max_count=1000)
# добавляем название альбома и ссылки на каждую фотографию
albums.append({'name': album['title'], 'photos': [p['sizes'][-1]['url'] for p in photos['items']]})
print(albums)
JSON:
[
{ 'name': 'Фотографии с моей страницы', 'photos': ['https://pp.userapi.com/<path>/<filename>.jpg', '...']},
{ 'name': 'Фотографии на моей стене', 'photos': ['https://pp.userapi.com/<path>/<filename>.jpg', '...']},
{ 'name': 'Сохранённые фотографии', 'photos': ['https://pp.userapi.com/<path>/<filename>.jpg', '...']}
]
Также как и с альбомами, оставим только нужные нам данные для документов:
Python:
def get_docs(vk):
# получаем список документов
doc_list = vk.docs.get()
# задаем новую структуру с количеством документов, общим размером(пока в байтах) и списком документов
docs = {'count': doc_list['count'], 'size': 0, 'docs': []}
# для каждого документа
for doc in doc_list['items']:
# добавим в список документов url, имя и расширение текущего документа
docs['docs'].append({'url': doc['url'], 'name': f"{doc['title']}_{doc['id']}", 'ext': doc['ext']})
# и добавим размер текущего документа к общему
docs['size'] += doc['size']
print(docs)
{'count': 344, 'size': 1062120373, 'docs': [{'url': "vk.com/<url>", 'name': 'VK.zip_4789', 'ext': 'zip'}]}
Теперь разберем функции получения диалогов и сообщений. Этот метод сложнее предыдущих и значительно объемнее по коду (ввиду обработки только нужных полей и аттачментов).
В простейшей реализации, все сообщения можно собрать таким способом:
Python:
def get_conversations(vk, vk_tools):
conversation_list = vk_tools.get_all(method='messages.getConversations', max_count=100,
values={'extended': 1, 'fields': 'first_name, last_name, name'})
conversations = []
for conversation in conversation_list['items']:
messages = vk_tools.get_all(max_count=200, method='messages.getHistory',
values={'rev': 1, 'extended': 1, 'fields': 'first_name, last_name',
'peer_id': conversation['conversation']['peer']['id']})
conversations.append({'id': conversation['conversation']['peer']['id'], 'messages': messages})
return conversations
Метод собирает все сообщения, однако, в этой структуре много лишней информации. Если выделить только id, имя диалога, сообщения и вложения нужных типов, то метод сбора разрастется до подобного кода:
Python:
def get_conversations(vk, vk_tools):
# получаем список диалогов
conversation_list = vk_tools.get_all(method='messages.getConversations', max_count=100,
values={'extended': 1, 'fields': 'first_name, last_name, name'})
conversations = []
# формируем список обработанных диалогов
for conversation in conversation_list['items']:
conversations.append(get_dialog_data(conversation, vk, vk_tools))
return conversations
# сборка нужных данных в одной структуре
def get_dialog_data(conversation, vk, vk_tool):
# запоминаем id, type(chat, user, group), name
dialog = {'id': conversation['conversation']['peer']['id'], 'type': conversation['conversation']['peer']['type'],
'name': get_dialog_name(conversation, vk)}
# формируем сообщения и вложения
dialog['messages'], dialog['attachments'] = get_messages(vk, vk_tool, dialog['id'])
return dialog
def get_dialog_name(conversation, vk):
# если тип беседы - личный или группа,
if conversation['conversation']['peer']['type'] in ['user', 'group']:
# то добавляем пользователя в список {id: name}
users_add(conversation['conversation']['peer']['id'], vk)
# Получаем имя юзера или группы
name = users[abs(conversation['conversation']['peer']['id'])]
# если диалог - чат,
elif conversation['conversation']['peer']['type'] == 'chat':
# то получаем имя из title
name = conversation['conversation']['chat_settings']['title']
else:
# иначе неожиданный результат, присвоим unknown
name = r'{unknown}'
# заменяем все "плохие" символы
for c in ['\\', '/', ':', '*', '?', '<', '>', '|', '"']:
name = name.replace(c, '_')
return name
def users_add(uid, vk):
try:
# если имени нет в списке
if uid not in users:
# то если юзер (id>0)
if uid > 0:
# получаем инфо о человеке
user = vk.users.get(user_ids=uid)[0]
# если удален, то имя - deleted
if ('deactivated' in user) and (user['deactivated'] == 'deleted') and (
user['first_name'] == 'DELETED'):
name = 'DELETED'
else:
# если все норм - имя фамилия
name = f"{user['first_name']} {user['last_name']}"
else:
# если группа (ид <0), то получаем инфо об группе
group = vk.messages.getConversationsById(peer_ids=uid, extended=1)['groups'][0]
# и получаем имя
name = group['name']
# добавляем в список
users[abs(uid)] = name
except:
# в случае ошибки присвоим неизвестное имя
users[abs(uid)] = '{unknown user}'
# получаем сообщения и вложения
def get_messages(vk, vk_tools, cid):
messages = []
attachments = {}
# читаем сообщения методом getHistory
history = vk_tools.get_all(max_count=200, method='messages.getHistory',
values={'rev': 1, 'extended': 1, 'fields': 'first_name, last_name', 'peer_id': cid})
# Для каждого сообщения
for message in history['items']:
# добавляем пользователя в список
users_add(message['from_id'], vk)
# обрабатываем сообщение
mess = message_handler(message)
# обрабатываем аттачменты
attach = attach_handler(message)
if mess: messages.append(mess)
# добавляем в структура {type: [objects]}
for at_type in attach:
if at_type not in attachments: attachments[at_type] = []
attachments[at_type] += attach[at_type]
return messages, attachments
def message_handler(msg)
# если сообщение не пусто
if len(msg['text']) > 0: text = [line for line in msg['text'].split('\n') if line]
# то возвращаем текст, от кого, дату
return {'text': text, 'from': users.get(msg['from_id']), 'date': msg['date']}
return None
def attach_handler(msg):
attachments = {}
# для каждого вложения
for attach in msg['attachments']:
# определяем тип
at_type = attach['type']
at = attach[at_type]
# если нужный тип не в списке вложений, то создаем список
if at_type not in attachments and at_type in ['photo', 'doc', 'audio_message']:
attachments[at_type] = []
# в зависимости от типа, добавляем нужную структуру
if at_type == 'photo':
attachments[at_type].append(at['sizes'][-1]['url'])
elif at_type == 'doc':
attachments[at_type].append({'url': at['url'], 'access_key': at['access_key'], 'size': at['size'],
'name': f"{at['title']}_{at['id']}.{at['ext']}", 'date': at['date']})
elif at_type == 'audio_message':
attachments[at_type].append({'url': at['link_ogg'], 'access_key': at['access_key'],
'name': f"{at['owner_id']}_{at['id']}.oog"})
return attachments
JSON:
{
"id": "<id>", "type": "user", "name": "Имя Фамилия",
"messages": [{ "text": ["Держи ссылку", "http://vk.com/<url>"], "from": "Имя Фамилия", "date": 1465503764}],
"attachments": {
"photo": ["https://pp.userapi.com/<someurl>"],
"doc": [
{
"url": "https://vk.com/doc<id>_437686018?hash=953f6&api=1&no_preview=1",
"access_key": "e9e3a1868e76702b49", "size": 868057,
"name": "tumalo1_400.gif_437686018.gif","date": 1469215825},
{
"url": "https://vk.com/doc<id>_437653303?hash=36d440&api=1&no_preview=1",
"access_key": "5578816d89e9600d63", "size": 966158,
"name": "https://vk.com/p_437653303.gif", "date": 1468267537}
]
}
}
На этом все нужные данные собраны, теперь научимся скачивать файлы.
Скачивание файлов.
В простом представлении фукнкция выглядит так:
Python:
import shutil
from os.path import exists
# функция по скачиванию файла по адресу url в файл path
def simple_download(url, path):
try:
# если файл еще на скачан
if not exists(path):
# делаем запрос по ссылке, указываем что это поток и задаем таймаут
r = requests.get(url, stream=True, timeout=(30, 5))
# открываем файл по пути path в режиме записи байтов
with open(path, 'wb') as f:
# сохраняем объект в файл
shutil.copyfileobj(r.raw, f)
# в случае ошибки выводим ее на экран
except Exception as e:
print(e)
На самом деле, если совсем минимизировать(исключительно для понимания механизма), то получится такая функция:
Python:
def simple_download(url, path):
r = requests.get(url, stream=True, timeout=(30, 5))
with open(path, 'wb') as f:
hutil.copyfileobj(r.raw, f)
В первом варианте, учитывается отказ от повторного скачивания файла и обработка ошибочного запроса (не вылетает из программы при ошибке).
По поводу повторного скачивания: если файл с таким именем существует, значит не скачиваем заново. Для данного проекта актуально, так как мы формируем уникальное имя файла по id. Для других проектов, эта "проверка на повторное скачивание" не является достоверной.
Теперь адаптируем скачивание под наши цели + добавим многопоточность:
Python:
import shutil
from itertools import repeat
from multiprocessing.pool import Pool
from os import cpu_count
from os.path import join, exists
PULL_PROCESSES = 4 * cpu_count()
def download_engine(object_list, path):
with Pool(PULL_PROCESSES) as pool:
pool.starmap(download, zip(object_list, repeat(path)))
def download(obj, root):
try:
filename, url = get_filename_url(obj)
path = join(root, filename)
if not exists(path):
r = requests.get(url, stream=True, timeout=(30, 5))
with open(path, 'wb') as f:
shutil.copyfileobj(r.raw, f)
except Exception as e:
print(e)
return False
def get_filename_url(obj):
if not obj:
raise ValueError('Объект пустой')
# если получена строка, то запоминаем ее как url и последнюю часть после / - имя файла
if isinstance(obj, str):
url = obj
del obj
filename = url.split('/')[-1]
# если получен словарь, то берем url из поля url, имя собираем в update_path
elif isinstance(obj, dict):
url = obj.pop('url')
options = obj
filename, url = update_path(url, options=options)
else:
# иначе не обрабатываем
raise ValueError('Неизвестный объект')
# заменяем недопустимые символы на _
for char in ['\\', '/', ':', '*', '?', '<', '>', '|', '"']:
filename = filename.replace(char, '_')
# возвращаем имя файла и url
return filename, url
# собираем имя и урл по "опциям" словаря
def update_path(url, filename=None, options=None):
if options is None:
options = {}
if 'name' in options:
filename = '_'.join(options['name'].split(' '))
if 'ext' in options:
if filename.split('.')[-1] != options['ext']:
filename += f".{options['ext']}"
if 'prefix' in options:
filename = str(options['prefix']) + '_' + filename
if 'access_key' in options:
url = f"{url}?access_key={options['access_key']}"
return filename, url
Теперь мы можем скачивать любые файл из наших структур. Вот пример как это делать:
Python:
def dump_albums(albums, path):
# для каждого альбома
for album in albums:
# создаем свой путь
current_path = join(path, album['name'])
makedirs(current_path, exist_ok=True)
# скачиваем по ссылкам из photos
download_engine(album['photos'], current_path)
def dump_docs(docs, path):
makedirs(path, exist_ok=True)
download_engine(docs['docs'], path)
def dump_dialogs(dialogs, path):
for dialog in dialogs:
dialog_name = f"{dialog['name'].replace(' ', '_')}_{dialog['id']}"
current_path = join(path, dialog_name)
makedirs(current_path, exist_ok=True)
with open(f'{join(current_path,dialog_name)}.json', 'w') as dialog_json:
json.dump(dialog, dialog_json)
for mode in dialog['attachments']:
attachment_path = join(current_path, mode)
download_engine(dialog['attachments'][mode], attachment_path)
Конец первой части. Полученный код можете посмотреть в прикрепленных файлах - sandbox.py
Часть 2 - Наведение красоты
Теперь соберем все наработки в обособленные классы. Выделим следующие классы:
- LoginVK - класс по работе с авторизацией (возвращает сессию)
- MethodsVK - сборщик данных, используя методы ВК (используются только тут) (возвращает облегченные словари нужного вида)
- DownloadManager - класс для скачивания списка файлов в несколько потоков. Генерация имен для скачанных файлов тоже тут
- DumpVK - методы по связи между словарями с данными и downloadManager'ом
Провел рефакторинг и добавив некоторые функции:
- читаемый вид размера документа и дат сообщений
- сохранение инфо об аккаунте, списков пользователей
- дамп-менеджер
- сохранение переписки в txt формате
- добавление лога ошибок
Python:
def dump_manager(config):
dump_config = config['dump_config']
if config['mode'] == 'collect':
vk = collect(config['login_data'])
dump_config.update({'albums': vk.albums, 'docs': vk.docs, 'conversations': vk.conversations, 'users': vk.users,
'account': vk.account})
elif config['mode'] == 'dump':
dump_config.update({'albums': load_collection(dump_config['albums']),
'docs': load_collection(dump_config['docs']),
'conversations': load_collection(dump_config['conversations'])})
elif config['mode'] == 'redump_errors':
try_dump_error_list(dump_config['path'], dump_config['download_errors'])
if config['mode'] in ['collect', 'dump']:
dump_vk = DumpVK(dump_config)
dump_vk.dump()
def collect(config):
login_vk = LoginVK(config)
return MethodsVK(login_vk.vk, login_vk.vk_tools, login_vk.account)
def load_collection(filename):
try:
with open(filename, 'r') as collection_file:
return json.load(collection_file)
except:
return []
def try_dump_error_list(path, filename):
with open(filename, 'r') as errors_file:
error_list = json.load(errors_file)
dump_list = [error['obj'] for error in error_list]
errors = DownloadManager.download_engine(dump_list, join(path, 'errors'))
with open(filename, 'w') as download_errors_file:
json.dump(errors, download_errors_file)
if __name__ == '__main__':
try:
with open('config.json', 'r') as config_file:
vk_config = json.load(config_file)
dump_manager(vk_config)
except Exception as e:
error_log.add(__name__, e)
error_log.save_log('error.log')
Подробнее про дамп-менеджер:
- Сбор данных - collect - произвести подключение к вк, произвести полный сбор данных в списки json.
- если download = true, то файлы скачиваются сразу.
- если download = false, то скачивание не происходит.
- При любом варианте "коллекции файлов" сохраняются в отдельные json(фото+диалоги+документы)
- Скачивание данных - dump - скачивание уже существующих коллекций (из файлов)
- Обработка ошибок - redump_error - При большом количестве потоков скачивания выдает ошибку - много запросов к ресурсу(при ошибке скачивания файла он логгируется в отдельный список). В данном режиме происходит повторное скачивание файлов из списка ошибок. Если успешно, то файл из списка удаляется.
JSON:
[
{
"mode": "collect",
"dump_config": {
"path": "dump",
"download": false,
"download_errors": "download_errors.json"
},
"login_data": {
"token": "",
"login": "",
"password": ""
}
},
{
"mode": "dump",
"dump_config": {
"albums": "albums.json",
"docs": "docs.json",
"conversations": "conversations.json",
"path": "dump",
"download": true,
"download_errors": "download_errors.json"
}
},
{
"mode": "redump_errors",
"dump_config": {
"path": "dump",
"download_errors": "download_errors.json"
}
}
]
Best-way эксплуатация:
- Запускаем конфиг collect БЕЗ скачивания - 1й пример
- Копируем полученные файлы (conversations.json, docs.json, albums.json) в корень скрипта(рядом с файлом config.json)
- Запускаем конфиг dump (данные из файлов, download = true) - 2ой пример конфига.
- В случае ошибок при скачивании, запустить конфиг redump_error - 3й пример
- Для скачивания видео, аудио, лайкосиков и т.д.
- Обработайте методы вк по получению нужной инфы в классе MethodsVK
- Введите переменные для хранения новых структур
- В классе DumpVK добавить метод по скачиванию структуры (мост между url ваших объектов, и download_manager'ом)
- делайте по подобию других методов, там все наглядно
- Для скачивания новых типов вложений добавить в attach_handler подобную инструкцию:
-
Python:
if at_type == 'your_type': attachments[at_type].append({'url', 'name', 'ext', etc})
-
На последок создадим exe версию приложения для Windows:
Находясь в виртуальном окружении установите модуль:
pip install pyinstaller
Для автоматизации процесса рекомендую использовать bat файл следующего вида:
Bash:
call env\Scripts\activate
python -OO -m PyInstaller --noconfirm --log-level=WARN ^
--onefile --noconsole ^
--icon=vk.ico --name=vk_dump ^ vk.py
Этот батник соберет весь код vk.py в один файл vk_dump.exe, с иконкой vk.ico
При попытке собрать exe, у меня появилось множество ошибок, связанных с импортом.
Решение:
В виртуальном окружении удалите модуль:
и повторите запуск батника.
Решение:
В виртуальном окружении удалите модуль:
pip uninstall enum34
и повторите запуск батника.
ATTENTION! Я не стал выкладывать exe файл, и вот почему:
Проверяя работоспособность исполняемого файла, я успешно собрал данные в json-коллекции, а на этапе дампа по файлам, exe'шник засорил все 4 ГБ ОЗУ (создал около 2000 процессов!) на виртуальной машине, и через 45 минут я отключил машину, а при перезагрузке обнаружил, что он ничего и не скачал. Сам скрипт РАЗУМЕЕТСЯ рабочий (проверял в linux и windows через pycharm).
Поэтому, дабы не прослыть дядей, который майнеры вам в компы сует, я приложил инструкцию по созданию exe в пару кликов (в сурсах будут все батники), а там вы уж сами думайте, нужно ли делать ехе для данного проекта или нет.
Проверяя работоспособность исполняемого файла, я успешно собрал данные в json-коллекции, а на этапе дампа по файлам, exe'шник засорил все 4 ГБ ОЗУ (создал около 2000 процессов!) на виртуальной машине, и через 45 минут я отключил машину, а при перезагрузке обнаружил, что он ничего и не скачал. Сам скрипт РАЗУМЕЕТСЯ рабочий (проверял в linux и windows через pycharm).
Поэтому, дабы не прослыть дядей, который майнеры вам в компы сует, я приложил инструкцию по созданию exe в пару кликов (в сурсах будут все батники), а там вы уж сами думайте, нужно ли делать ехе для данного проекта или нет.
Приложенные архивы:
- source.zip - исходные коды данного проекта
- vk.py - основной модуль со всеми классами описанными в статье
- sandbox.py - наработки из первой части статьи
- error_log.py - класс для логгирования ошибок
- config.json - 1ый пример конфига - коллекция данных
- additional.zip - дополнительные необязательные файлы для проекта:
- make_env.bat - автоустановка виртуального окружения, установка зависимостей из requirements.txt
- requirements.txt - необходимые дополнительные модули для проекта
- template_configs.json - примеры правильных конфигов
- make_exe.bat - компиляция vk.py в vk_dump.exe (если будет ошибка, удалите enum34)
- vk.ico - иконка для vk_dump.exe