{"id":172131,"date":"2013-03-10T10:10:03","date_gmt":"2013-03-10T06:10:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=172131"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=172131","title":{"rendered":"<span class=\"post_title\">\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0444\u043e\u0442\u043e\u0430\u043b\u044c\u0431\u043e\u043c\u043e\u0432 \u0438\u0437 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0430<\/span>"},"content":{"rendered":"<div class=\"content html_format\">\n<h4>\u041f\u0440\u0435\u0430\u043c\u0431\u0443\u043b\u0430<\/h4>\n<p>  \u0414\u0435\u043b\u043e \u0431\u044b\u043b\u043e \u0432\u0435\u0447\u0435\u0440\u043e\u043c, \u0434\u0435\u043b\u0430\u0442\u044c \u0431\u044b\u043b\u043e \u043d\u0435\u0447\u0435\u0433\u043e \u0438 \u0442\u0443\u0442 \u043c\u043d\u0435 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u043f\u0440\u0438\u0448\u043b\u0430 \u043c\u044b\u0441\u043b\u044c: \u00ab\u041a\u0430\u043a \u0436\u0435 \u043c\u043d\u0435 \u0432\u044b\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0441\u0435 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u0438\u0437 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0430 \u043d\u0430 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440?\u00bb \u041d\u0435\u0434\u043e\u043b\u0433\u043e \u0434\u0443\u043c\u0430\u044f, \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438 \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u044f \u043d\u0435 \u043e\u0434\u0438\u043d \u0442\u0430\u043a\u043e\u0439.<\/p>\n<h4>\u041f\u043e\u0435\u0445\u0430\u043b\u0438<\/h4>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 API, \u043f\u0443\u0442\u0451\u043c \u043a\u0440\u0430\u0442\u043a\u0438\u0445 \u043f\u043e\u0438\u0441\u043a\u043e\u0432, \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/github.com\/python273\/vk_api\">vk_api<\/a>. \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u0435\u0442\u044c\u044e \u043e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <a href=\"http:\/\/python-requests.org\">Requests<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u044d\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430.<\/p>\n<h4>\u041f\u043e\u0449\u0443\u043f\u0430\u0442\u044c<\/h4>\n<p>  <a href=\"http:\/\/meamka.me\/VKPorter\/\">GitHub Pages \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a><br \/>  <a name=\"habracut\"><\/a><\/p>\n<p>  \u0421\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043a\u0440\u0430\u0439\u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c, \u043d\u043e \u0441 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u0441\u0432\u043e\u0435\u0439 \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f. \u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u0443\u043c\u0435\u0441\u0442\u0438\u043b\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435.<\/p>\n<pre><code class=\"python\">#!\/usr\/bin\/env python  &quot;&quot;&quot;     :mod:`vkporter`     ~~~~~~~~~~~~~~~      A micro tool for export photo albums from `vk.com &lt;https:\/\/vk.com&gt;`_.      It's based on `VK_API &lt;https:\/\/github.com\/python273\/vk_api&gt;`_      by Kirill Python &lt;mikeking568@gmail.com&gt;,      `Requests &lt;python-requests.org&gt;`_      and `ProgressBar &lt;https:\/\/code.google.com\/p\/python-progressbar\/&gt;`_.      :copyright: (c) 2013 by Andrey Maksimov.     :license: BSD, see LICENSE for more details. &quot;&quot;&quot;  __author__ = 'Andrey Maksimov &lt;meamka@me.com&gt;' __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(&quot;Cannot find 'requests' module. Please install it and try again.&quot;)     sys.exit(0)  try:     from vk_api import VkApi except ImportError:     print(&quot;Cannot find 'vk_api' module. Please install it and try again.&quot;)     sys.exit(0)   def connect(login, password):     &quot;&quot;&quot;Initialize connection with `vk.com &lt;https:\/\/vk.com&gt;`_ 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`     &quot;&quot;&quot;     return VkApi(login, password)   def get_albums(connection):     &quot;&quot;&quot;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     &quot;&quot;&quot;     try:         return connection.method('photos.getAlbums')     except Exception as e:         print(e)         return None   def get_photos(connection, album_id):     &quot;&quot;&quot;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     &quot;&quot;&quot;     try:         return connection.method('photos.get', {'aid': album_id})     except Exception as e:         print(e)         return None   def download(photo, output):     &quot;&quot;&quot;Download photo      :param photo:     &quot;&quot;&quot;     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):     &quot;&quot;&quot;Small function to format numbered size to human readable string      :param num: bytes to format     :type num: int      :return: human readable size     &quot;&quot;&quot;     for x in ['bytes', 'KB', 'MB', 'GB', 'TB']:         if num &lt; 1024.0:             return &quot;%3.1f %s&quot; % (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(&quot;Password: &quot;)          # Initialize vk.com connection         connection = connect(args.username, password)          # Request list of photo albums         albums = get_albums(connection)         print(&quot;Found %s album%s:&quot; % (len(albums), 's' if len(albums) &gt; 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']) &gt; 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(                     &quot;\\rExporting %s... %s of %s (%2d%%)&quot; % (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(&quot;Done in %s&quot; % (datetime.datetime.now() - start_time))  <\/code><\/pre>\n<h4>\u041f\u0440\u0438\u043c\u0435\u0440\u044b<\/h4>\n<p>  \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043f\u0430\u043f\u043a\u0443 <code>.\/exported<\/code>  <\/p>\n<pre><code class=\"bash\">$ .\/vkporter.py username@vk.com <\/code><\/pre>\n<p>  \u041f\u0443\u0442\u044c \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435  <\/p>\n<pre><code class=\"bash\">$ .\/vkporter.py -o ~\/Documents\/Exported username@vk.com <\/code><\/pre>\n<p>  \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<br \/>  <img decoding=\"async\" src=\"http:\/\/f.cl.ly\/items\/1a2m3W3Z2s2z0k2Y3s1k\/vkporter.png\" alt=\"image\"\/>    \t \t\t   \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/172131\/\"> http:\/\/habrahabr.ru\/post\/172131\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">\n<h4>\u041f\u0440\u0435\u0430\u043c\u0431\u0443\u043b\u0430<\/h4>\n<p>  \u0414\u0435\u043b\u043e \u0431\u044b\u043b\u043e \u0432\u0435\u0447\u0435\u0440\u043e\u043c, \u0434\u0435\u043b\u0430\u0442\u044c \u0431\u044b\u043b\u043e \u043d\u0435\u0447\u0435\u0433\u043e \u0438 \u0442\u0443\u0442 \u043c\u043d\u0435 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u043f\u0440\u0438\u0448\u043b\u0430 \u043c\u044b\u0441\u043b\u044c: \u00ab\u041a\u0430\u043a \u0436\u0435 \u043c\u043d\u0435 \u0432\u044b\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0441\u0435 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u0438\u0437 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0430 \u043d\u0430 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440?\u00bb \u041d\u0435\u0434\u043e\u043b\u0433\u043e \u0434\u0443\u043c\u0430\u044f, \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438 \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u044f \u043d\u0435 \u043e\u0434\u0438\u043d \u0442\u0430\u043a\u043e\u0439.<\/p>\n<h4>\u041f\u043e\u0435\u0445\u0430\u043b\u0438<\/h4>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 API, \u043f\u0443\u0442\u0451\u043c \u043a\u0440\u0430\u0442\u043a\u0438\u0445 \u043f\u043e\u0438\u0441\u043a\u043e\u0432, \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/github.com\/python273\/vk_api\">vk_api<\/a>. \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u0435\u0442\u044c\u044e \u043e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <a href=\"http:\/\/python-requests.org\">Requests<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u044d\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430.<\/p>\n<h4>\u041f\u043e\u0449\u0443\u043f\u0430\u0442\u044c<\/h4>\n<p>  <a href=\"http:\/\/meamka.me\/VKPorter\/\">GitHub Pages \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-172131","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/172131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=172131"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/172131\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=172131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=172131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=172131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}