В свете принятия последних законов, а также после удаления n-ного количества моих аудиозаписей из ВК поневоле начинаешь задумываться о сохранении своей аудиоколлекции. За несколько лет размер моего плейлиста ВКонтакте достиг почти двух тысяч треков. Для сохранения всего этого счастья был написан нижеследующий модуль(естественно на python):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# -*- coding: utf-8 -*-

import urllib, urllib2, cookielib, re, sys, os

headers = {'User-Agent' : 'Mozilla/5.0 (X11; Ubuntu;
    Linux i686; rv:26.0) Gecko/20100101 Firefox/26.0'}

class VKError(Exception):
    pass

def delWebchars(str):
    webchars = re.findall('&.*?;', str)
    for ch in webchars:
        newch = ch
        if ch[1] == "#":
            newch = unichr(int(ch[2:-1]))
        else:
            if ch.lower() == '"': newch = '\"'
            elif ch.lower() == "&": newch = "&"
        str = str.replace(ch, newch)
    str = str.replace(";", "")
    str = str.replace(os.sep, "")
    return str

def getVKIP_h():
    ip_h = re.findall('.+?ip_h=(.+?)\&',urllib.urlopen("http://vk.com").read())
    return ip_h[0]

def VKlogin(nickname, password):
    print "Preparing"
    cookie = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
    urllib2.install_opener(opener)
    ip_h = getVKIP_h()
    data = {"act": "login", "ip_h":ip_h, "_origin":"http://vk.com",
        "email":nickname, "pass":password}
    sendData = urllib.urlencode(data)
    req = urllib2.Request("http://login.vk.com", sendData, headers)
    page = urllib2.urlopen(req).read()
    matches = re.findall(".+?(login.php).+?", page) #dont work search or match
    if len(matches) != 0: raise VKError("Login failed!")

def getVKAudiopage(id, pageNumber=0):
    data = {"act":"load_audios_silent",
            "id":id,
            "please_dont_ddos":"2",
            "al":"1"}
    sendData = urllib.urlencode(data)
    req = urllib2.Request("http://vk.com/audio.php", sendData, headers)
    page = urllib2.urlopen(req).read()
    audiopage = unicode(str(page),'cp1251')
    matches = re.findall(".+?(.mp3).+?", audiopage) #dont work search or match
    if len(matches) == 0: raise VKError("Receiving audiopage error.")
    return audiopage

def getVKAudiolinks(audiopage):
    names = re.findall(
'.+?\[\'.+?\',\'(.+?)\',\'(http://.+?\.mp3).+?,\'.*?\',\'.*?\',\'(.+?)\',\'(.+?)\'',
    audiopage)
    linklist = []
    for name in names:
        trackId = name[0]
        artist = name[2].title()
        song = name[3].title()
        filename = artist+" - "+song+".mp3"
        filename = " ".join(delWebchars(filename).split())
        #if not any(filename==fl link,fl in linklist): #dublicate search
        linklist.append((name[1], filename, trackId))
    linklist = list(set(linklist)) #remove dublicates
    return linklist

def getVKAudio(email, password, id):
    lst = []
    try:
        if not email or not password:
            raise VKError("Error. Login or password are not specified.")
        print "Logging."
        VKlogin(email, password)
        print "Successfully logged."
        print "Receiving audiopage."
        page = getVKAudiopage(id)
        print "Parsing audio."
        lst = getVKAudiolinks(page)
        print "Successfully parsed %d songs." % len(lst)
    except VKError, e:
        print e
        sys.exit(1)
    except Exception, e:
        print e
        sys.exit(1)

    return lst

Код немного кривой, но работает. После выполнения функции

1
getVKAudio(логин, пароль, id)

на выходе получаем список кортежей вида:

(http://cs1-41v4.vk.me/p22/c8134a62fe9ff9.mp3, David Bowie - Heroes.mp3, 255957177)
где последний элемент - ID трека в базе данных ВКонтакте.
Далее список можно использовать в своих интересах. Например записать в файл и скормить любимому download-менеджеру:
1
2
3
4
5
6
7
outfilename = "VKdownloadlist.txt"
sep = ";"
audlist = getVKAudio(email, password, userid)
outfile = open(outfilename,"wb")
for link, filename in audlist:
    outfile.write((link + sep + filename + "\n").encode("utf-8"))
outfile.close()

Следующим шагом будет написание полноценного скрипта для односторонней синхронизации локальной директории и аудиоколлекции ВКонтакте.