Загрузка музыки с VK средствами Python

от автора

Вступление

Лирическое отступление

Здравствуй, публика Хабрахабра. Я уже некоторое время наблюдаю за Вами, читаю Ваши работы. Честно признаться, меня завораживает тонкий и одновременно смелый мир Хабра. Поэтому, немного поразмыслив, я решил влиться в Вашу компанию. Это, как Вы уже, наверное, заметили, мой первый пост, но я не призываю Вас быть помягче ко мне. Скорее, я хочу испытать все те чувства, которые пережили или переживают бывалые пользователи. Давно хотел это написать здесь — добро пожаловать под кат.

Что, как и, главное, зачем?

Все просто: скрипт, написанный на Python 3.3, позволяющий загрузить указанную композицию с небезызвестного vk.com. Я использовал только стандартные модули: urllib и html.parser. Выражу общее мнение, если скажу, что это тот еще велосипед.

Код

Собственно, код разделен на три условные части: класс для парсинга формы, класс для парсинга списка композиций и главная часть.

Парсинг формы входа

Как я уже упоминал, парсить мы будем при помощи html.parser.

class FormParser(HTMLParser):     def __init__(self):         HTMLParser.__init__(self)         self.url = None         self.params = {}         self.in_form = False         self.form_parsed = False         self.method = "GET"      def handle_starttag(self, tag, attrs):         tag = tag.lower()         if tag == "form":             if self.form_parsed:                 raise RuntimeError("Second form")             if self.in_form:                 raise RuntimeError("Already in form")             self.in_form = True          if not self.in_form:             return         attrs = dict((name.lower(), value) for name, value in attrs)         if tag == "form":             self.url = attrs["action"]              if "method" in attrs:                 self.method = attrs["method"]         elif tag == "input" and "type" in attrs and "name" in attrs:             if attrs["type"] in ["hidden", "text", "password"]:                 self.params[attrs["name"]] = attrs["value"] if "value" in attrs else ""      def handle_endtag(self, tag):         tag = tag.lower()         if tag == "form":             if not self.in_form:                 raise RuntimeError("Unexpected </form>")             self.in_form = False             self.form_parsed = True 

Класс занимается тем, что находит тег form, input и прилежащие к ним атрибуты, вроде method, action и так далее.

Парсинг списка композиций

Код имеет похожую структуру и приведен ниже.

class TrackSearch(HTMLParser):     def __init__(self):         HTMLParser.__init__(self)         self.url = None         self.params = {}         self.in_form = False         self.form_parsed = False         self.method = "GET"              def handle_starttag(self, tag, attrs):         if self.url == None or len(self.url) < 10:             tag = tag.lower()             if tag == "input":                 attrs = dict((name.lower(), value) for name, value in attrs)                 if attrs["type"] == "hidden":                     self.url = attrs["value"] 

Думаю, ничего сложного здесь нет. Класс парсит список в поисках первой композиции в начале списка — самый релевантный вариант — и сохраняет ссылку на неё в self.url. Проверка len(self.url) < 10 нужна лишь для того, чтобы отсеять первые два input, необходимые для функционирования поиска VK.

Интерфейс и вызовы

Конечно, классов, указанных выше, недостаточно. Чтобы успешно авторизоваться, необходимо правильно обработать cookie. На помощь приходит urllib.request и http.cookiejar. Создаем обработчик.

opener = urllib.request.build_opener(         urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()),         urllib.request.HTTPRedirectHandler()) 

Теперь, когда других препятствий нет, мы можем начать.

#Сбор необходимой информации print("VK Music Downloader") login = input("Телефон или email > ") password = input("Пароль > ") track = input("Исполнитель и название композиции > ") filename = track + ".mp3" track = urllib.parse.quote(track)  #Авторизация print("Авторизация...") parser = FormParser() response = str(opener.open("http://m.vk.com/").read()) parser.feed(response) parser.params["email"] = login parser.params["pass"] = password response = opener.open(parser.url, urllib.parse.urlencode(parser.params).encode()) parser.close()  #Поиск print("Поиск композиции...") response = str(opener.open("http://m.vk.com/audio?act=search&q=%s" % track).read()) seacher = TrackSearch() seacher.feed(response)  #Загрузка print("Загрузка > %s" % filename) with urllib.request.urlopen(seacher.url) as data, \      open(filename, 'wb') as fout:      fout.write(data.read())  seacher.close() input("Загрузка завершена") 

Заключение

Пример работы скрипта.

На этом мой первый пост заканчивается. Спасибо тем, кто уделил время, чтобы просмотреть его. Если у Вас появились вопросы, я с радостью отвечу. Всего доброго.

ссылка на оригинал статьи http://habrahabr.ru/post/215377/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *