Библиотека vk_api для импорта списка audio пользователя вконтакта и альтернативные пути
Необходимо получать списки аудио пользователей вк, для этого я использую библиотеку vk_api, обеспечивающую работу с api вконтакта:
import vk_api
from vk_api import audio
Соответствуют ли действительности мои подозрения о том, что эта библиотека использует парсинг страниц с аудио пользователя, а не запрашивает списки аудио через api вконтакта?
В разделе https://vk.com/dev/audio сказано что доступ к публичному API аудиозаписей ограничен и дана ссылка на страницу https://vk.com/dev/audio_api с подробностями, где сказано:
1. Как это работает сейчас
Методы для работы с аудиозаписями пользователей и сообществ (audio) доступны для любых приложений, использующих публичный API ВКонтакте. В ответ на запрос сервер отправляет информацию о композиции, включая название, имя исполнителя, ссылку на mp3-файл. Приложение использует эти данные для отображения, воспроизведения и других действий с аудиозаписями.
2. Что изменится
С 16 декабря 2016 года мы отключаем публичный API для работы с аудиозаписями. Существующие методы секции audio будут недоступны для вызова, кроме методов для загрузки аудиофайлов.
Первый пункт звучит достаточно противоречиво относительно второго, потому что 2016 уже давно минул и если я правильно понял, то первый пункт уже не о том как работает сейчас, а о том как работало до 2016 года.
При первом использовании vk_api были какие то ошибки с bs4 и правильно ли я понял, что:
1) ввиду ограничений api вконтакта на работу с аудио, эта библиотека использует Beautiful Soup 4 для парсинга страниц с аудио пользователя?
2) Сам по себе парсинг работает по определению гораздо медленнее, чем могло бы работать через api, если бы такая возможность была, но ее нет и другого пути более быстро получать списки аудио пользователей, чем с помощью библиотеки vk_api (с Beautiful Soup 4) не существует?
Ответы (1 шт):
Во-первых,
Соответствуют ли действительности мои подозрения о том, что эта библиотека использует парсинг страниц с аудио пользователя, а не запрашивает списки аудио через api вконтакта?
- да, библиотека парсит данные из html
Во-вторых, скорее всего, ошибки с bs4 были из-за того, что изменился html-код на странице аудио, и теперь парсинг не работает.
В-третьих, как вариант, использовать библиотеку vk_audio ( тоже парсит данные из html, только данный способ пока работает)
vk = vk_audio.VkAudio(login="login",password="password")
vk.load()#загрузить музыку
your_audio = vk.Audios
print(your_audio[1].title,your_audio[1].url)
В-четвертых, если хотите более быстрый вариант api, то можете попробовать подделаться под клиента андроид-приложения:
import requests,hashlib,urllib,random,string,re
class VkAndroidApi(object):
session = requests.Session()
session.headers={"User-Agent": "VKAndroidApp/4.13.1-1206 (Android 4.4.3; SDK 19; armeabi; ; ru)","Accept": "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"}
def __init__(this,login=None,password=None,token=None,secret=None,v=5.95):
this.v=v;
this.device_id = "".join( random.choice(string.ascii_lowercase+string.digits) for i in range(16))
if token is not None and secret is not None:
this.token=token
this.secret=secret
return
#Генерируем рандомный device_id
answer = this.session.get(
"https://oauth.vk.com/token?grant_type=password&scope=nohttps,audio&client_id=2274003&client_secret=hHbZxrka2uZ6jB1inYsH&username={login}&password={password}".format(
login=login,
password=password
),
headers={'User-Agent': 'Mozilla/4.0 (compatible; ICS)'}).json()
if("error" in answer): raise PermissionError("invalid login|password!")
this.secret = answer["secret"]
this.token = answer["access_token"]
#Методы, "Открывающие" доступ к аудио. Без них, аудио получить не получится
this.method('execute.getUserInfo',func_v=9),
this._send('/method/auth.refreshToken?access_token={token}&v={v}&device_id={device_id}&lang=ru'.format(token=this.token,v=v,device_id=this.device_id))
def method(this,method,**params):
url =( "/method/{method}?v={v}&access_token={token}&device_id={device_id}".format(method=method,v=this.v,token=this.token,device_id=this.device_id)
+"".join("&%s=%s"%(i,params[i]) for i in params if params[i] is not None)
)#генерация ссылки по которой будет генерироваться md5-подпись
#обратите внимание - в даннаой ссылке нет urlencode параметров
return this._send(url,params,method);
def _send(this,url,params=None,method=None,headers=None):
hash = hashlib.md5((url+this.secret).encode()).hexdigest()
if method is not None and params is not None:
url = ("/method/{method}?v={v}&access_token={token}&device_id={device_id}".format(method=method,token=this.token,device_id=this.device_id,v=this.v)
+ "".join(
"&"+i+"="+urllib.parse.quote_plus(str(params[i])) for i in params if(params[i] is not None)
))
if headers is None:
return this.session.get('https://api.vk.com'+url+"&sig="+hash).json()
else:
return this.session.get('https://api.vk.com'+url+"&sig="+hash,headers=headers).json()
_pattern = re.compile(r'/[a-zA-Z\d]{6,}(/.*?[a-zA-Z\d]+?)/index.m3u8()')
def to_mp3(self,url):
return self._pattern.sub(r'\1\2.mp3',url)
Ну и использование:
vk = VkAndroidApi(login="login",password="password")#или token="token",secret="secret"
secret,token = vk.secret,vk.token
audios,playlists = vk.method("execute",code="return [API.audio.get({count:2}),API.audio.getPlaylists({count:1,owner_id:API.users.get()[0].id})];")['response']
#или
audios = vk.method("audio.get",owner_id=100)['response']