Skip to content

Instantly share code, notes, and snippets.

@hatkidchan
Created November 4, 2019 18:56
Show Gist options
  • Save hatkidchan/70116d88e510a5726ffbed8bfb9771af to your computer and use it in GitHub Desktop.
Save hatkidchan/70116d88e510a5726ffbed8bfb9771af to your computer and use it in GitHub Desktop.
Python script for downloading all photos from VK
#!/usr/bin/env python3
import urllib3
import json
import getpass
from zipfile import ZipFile
import os
class API:
def __init__(self):
self._access_token = None
self.http = urllib3.PoolManager()
def call(self, method, **kwargs):
kwargs.setdefault("access_token", self._access_token)
kwargs.setdefault("v", "5.78")
rq = self.http.request("GET", "https://api.vk.com/method/" + method,
fields=kwargs)
if rq.status // 100 != 2:
raise Exception("Status code is not 2XX", rq.status, rq.data)
data = json.loads(rq.data.decode("utf-8"))
if data.get("response"):
return data["response"]
raise Exception("VK API returned error:", data)
try:
api = API()
while True:
try:
api._access_token = getpass.getpass("Access token: ")
me = api.call("users.get", fields="domain")[0]
except:
continue
if me:
break
print("Logged in as {first_name} {last_name} @{domain}".format(**me))
zipf = ZipFile("vk_dump.zip", "w")
print("Fetching albums", end="...")
albums = api.call("photos.getAlbums", need_system=1)
print("OK!", albums["count"])
albums_data = {}
print("Fetching photos in each album...")
for album in albums["items"]:
print("{id} {title!r}: {size}".format(**album), end=" ... ")
albums_data[album["id"]] = []
for i in range(1 + album["size"] // 1000):
data = api.call("photos.get", album_id=album["id"], offset=i * 1000, count=1000)
albums_data[album["id"]] += data["items"]
print("Got", len(albums_data[album["id"]]))
for album_info in albums["items"]:
album = albums_data[album_info["id"]]
c = len(album)
for i, photo in enumerate(album, 1):
photo_name = "photo{date}_{owner_id}_{id}.jpg".format(**photo)
filename = os.path.join(album_info["title"], photo_name)
print(i, c, "Downloading", filename, end=" ... ")
with zipf.open(filename, "w") as outf:
req = api.http.request("GET", photo["sizes"][-1]["url"], preload_content=False)
while True:
chunk = req.read(65536)
if not chunk:
print("Done")
break
outf.write(chunk)
zipf.close()
except KeyboardInterrupt:
quit()
except Exception:
import traceback
import time
print("Exception occurred")
print(traceback.format_exc())
print("Precc CTRL+C to exit")
while True:
time.sleep(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment