Преамбула
Дело было вечером, делать было нечего и тут мне в голову пришла мысль: «Как же мне выгрузить все фотографии из ВКонтакта на компьютер?» Недолго думая, я написал утилиту для этого и решил поделиться с общественностью, возможно я не один такой.
Поехали
В качестве инструмента для работы с API, путём кратких поисков, была выбрана библиотека vk_api. Для работы с сетью она использует Requests, поэтому и эта библиотека требуется для запуска.
Пощупать
Само приложение получилось крайне простым и небольшим, но с задачей своей справляется. Весь код уместился в одном единственном файле.
#!/usr/bin/env python """ :mod:`vkporter` ~~~~~~~~~~~~~~~ A micro tool for export photo albums from `vk.com <https://vk.com>`_. It's based on `VK_API <https://github.com/python273/vk_api>`_ by Kirill Python <mikeking568@gmail.com>, `Requests <python-requests.org>`_ and `ProgressBar <https://code.google.com/p/python-progressbar/>`_. :copyright: (c) 2013 by Andrey Maksimov. :license: BSD, see LICENSE for more details. """ __author__ = 'Andrey Maksimov <meamka@me.com>' __date__ = '09.03.13' __version__ = '0.1.1' import argparse import datetime from getpass import getpass import os import time import sys try: import requests except ImportError: print("Cannot find 'requests' module. Please install it and try again.") sys.exit(0) try: from vk_api import VkApi except ImportError: print("Cannot find 'vk_api' module. Please install it and try again.") sys.exit(0) def connect(login, password): """Initialize connection with `vk.com <https://vk.com>`_ and try to authorize user with given credentials. :param login: user login e. g. email, phone number :type login: str :param password: user password :type password: str :return: :mod:`vk_api.vk_api.VkApi` connection :rtype: :mod:`VkApi` """ return VkApi(login, password) def get_albums(connection): """Get albums list for currently authorized user. :param connection: :class:`vk_api.vk_api.VkApi` connection :type connection: :class:`vk_api.vk_api.VkApi` :return: list of photo albums or ``None`` :rtype: list """ try: return connection.method('photos.getAlbums') except Exception as e: print(e) return None def get_photos(connection, album_id): """Get photos list for selected album. :param connection: :class:`vk_api.vk_api.VkApi` connection :type connection: :class:`vk_api.vk_api.VkApi` :param album_id: album identifier returned by :func:`get_albums` :type album_id: int :return: list of photo albums or ``None`` :rtype: list """ try: return connection.method('photos.get', {'aid': album_id}) except Exception as e: print(e) return None def download(photo, output): """Download photo :param photo: """ url = photo.get('src_xxxbig') or photo.get('src_xxbig') or photo.get('src_xbig') or photo.get('src_big') r = requests.get(url) title = photo['pid'] with open(os.path.join(output, '%s.jpg' % title), 'wb') as f: for buf in r.iter_content(1024): if buf: f.write(buf) def sizeof_fmt(num): """Small function to format numbered size to human readable string :param num: bytes to format :type num: int :return: human readable size """ for x in ['bytes', 'KB', 'MB', 'GB', 'TB']: if num < 1024.0: return "%3.1f %s" % (num, x) num /= 1024.0 if __name__ == '__main__': parser = argparse.ArgumentParser(description='', version='%(prog)s ' + __version__) parser.add_argument('username', help='vk.com username') # parser.add_argument('password', help='vk.com username password') parser.add_argument('-o', '--output', help='output path to store photos', default=os.path.abspath(os.path.join(os.path.dirname(__file__), 'exported'))) args = parser.parse_args() # expand user path if necessary if args.output.startswith('~'): args.output = os.path.expanduser(args.output) start_time = datetime.datetime.now() try: password = getpass("Password: ") # Initialize vk.com connection connection = connect(args.username, password) # Request list of photo albums albums = get_albums(connection) print("Found %s album%s:" % (len(albums), 's' if len(albums) > 1 else '')) ix = 0 for album in albums: print('%3d. %-40s %4s item%s' % ( ix + 1, album['title'], album['size'], 's' if int(album['size']) > 1 else '')) ix += 1 # Sleep to prevent max request count time.sleep(1) if not os.path.exists(args.output): os.makedirs(args.output) for album in albums: response = get_photos(connection, album['aid']) output = os.path.join(args.output, album['title']) if not os.path.exists(output): os.makedirs(output) processed = 0 for photo in response: percent = round(float(processed) / float(len(response)) * 100, 2) sys.stdout.write( "\rExporting %s... %s of %s (%2d%%)" % (album['title'], processed, len(response), percent)) sys.stdout.flush() download(photo, output) processed += 1 except Exception as e: print(e) sys.exit(1) except KeyboardInterrupt: print('VKPorter exporting stopped by keyboard') sys.exit(0) finally: print("Done in %s" % (datetime.datetime.now() - start_time))
Примеры
По умолчанию экспорт происходит в папку ./exported
$ ./vkporter.py username@vk.com
Путь для экспорта можно указать при запуске
$ ./vkporter.py -o ~/Documents/Exported username@vk.com
Выглядит это примерно так:
ссылка на оригинал статьи http://habrahabr.ru/post/172131/
Добавить комментарий