- PVSM.RU - https://www.pvsm.ru -
Приветствую Вас, Читатели!
В этом [1] посте я рассказал о своей программе для скробблинга треков на Last.fm [2]. Теперь я хочу рассказать Вам, как на языке C# наладить взаимодействие с Last.fm API [3] на примере скробблинга трека.
Первое, что нам нужно сделать — это зарегистрировать свой API аккаунт. Заходим в свой профиль и переходим по этой ссылке [4]. После заполнения нужных полей мы получим так называемые API Key и секретный ключ. Они понадобятся для идентификации вашего клиента сервисом и получения ключа сессии. Проблем с их получением у меня не возникло.
Так как скробблинг трека требует получения ключа сессии, то нас будут интересовать следующие методы:
— Получение токена [5]
— Получение ключа сессии [6]
— Скроббл трека [7]
Упрощённая схема такова — мы получаем токен, используя наш API Key, потом получаем ключ сессии, используя токен и секретный ключ, потом скробблим трек, используя ключ сессии, токен и ещё несколько параметров.
Также нам понадобится использование двух классов — HttpWebRequest [8] и HttpWebResponse [9] для осуществления HTTP-запросов.
Итак, приступим к рассмотрению кода.
Сначала метод для получения сессии:
// создаём объект HttpWebRequest через статический метод Create класса WebRequest, явно приводим результат к HttpWebRequest. В параметрах указываем страницу, которая указана в API, в качестве параметров - method=auth.gettoken и наш API Key
HttpWebRequest tokenRequest = (HttpWebRequest)WebRequest.Create("http://ws.audioscrobbler.com/2.0/?method=auth.gettoken&api_key=" + ApiKey);
// получаем ответ сервера
HttpWebResponse tokenResponse = (HttpWebResponse)tokenRequest.GetResponse();
// и полностью считываем его в строку
string tokenResult = new StreamReader(tokenResponse.GetResponseStream(), Encoding.UTF8).ReadToEnd();
// извлекаем то, что нам нужно. Можно сделать и через парсинг XML (видимо, я о нём ещё не знал в тот момент, когда писал этот код).
string token = String.Empty;
for (int i = tokenResult.IndexOf("<token>") + 7; i < tokenResult.IndexOf("</token"); i++)
{
token += tokenResult[i];
}
// запускаем в браузере по умолчанию страницу http://www.last.fm/api/auth/ c параметрами API Key и только что полученным токеном)
Process s = Process.Start("http://www.last.fm/api/auth/?api_key=" + ApiKey + "&token=" + token);
// запускается страница, где у пользователя спрашивается, можно ли разрешить данному приложению доступ к профилю.
// ждём подтверждения от пользователя
DialogResult d = MessageBox.Show("Вы подтвердили доступ?", "Подтверждение", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
// если пользователь дал согласие
if (d == DialogResult.OK)
{
// создаём сигнатуру для получения сессии (указываем API Key, метод, токен и наш секретный ключ, всё это без символов '&' и '='
string tmp = "api_key" + ApiKey + "methodauth.getsessiontoken" + token + mySecret;
// хешируем это алгоритмом MD5 (думаю, у вас не будет проблем найти его в Интернете)
string sig = MD5(tmp);
// получаем сессию похожим способом
HttpWebRequest sessionRequest = (HttpWebRequest)WebRequest.Create("http://ws.audioscrobbler.com/2.0/?method=auth.getsession&token=" + token + "&api_key=" + ApiKey + "&api_sig=" + sig);
// уже не помню, зачем это свойство выставлять в true, но это обязательно. Зачем-то им нужно перенаправление.
sessionRequest.AllowAutoRedirect = true;
// получаем ответ
HttpWebResponse sessionResponse = (HttpWebResponse)sessionRequest.GetResponse();
string sessionResult = new StreamReader(sessionResponse.GetResponseStream(),
Encoding.UTF8).ReadToEnd();
// извлечение сессии (опять же проще использовать XML парсер)
for (int i = sessionResult.IndexOf("<key>") + 5; i < sessionResult.IndexOf("</key>"); i++)
{
sessionKey += sessionResult[i];
}
}
Итак, полдела сделано, двигаемся дальше. Теперь нужно заскробблить трек.
// узнаем UNIX-время для текущего момента
TimeSpan rtime = DateTime.Now - (new DateTime(1970, 1, 1, 0, 0, 0));
TimeSpan t1 = new TimeSpan(3, 0, 0);
rtime -= t1; // вычитаем три часа, чтобы не было несоответствия из-за разницы в часовых поясах
// получаем количество секунд
int timestamp = (int)rtime.TotalSeconds;
// формируем строку запроса
string submissionReqString = String.Empty;
//добавляем параметры (указываем метод, сессию и API Key):
submissionReqString += "method=track.scrobble&sk=" + sessionKey + "&api_key=" + ApiKey;
// добавляем только обязательную информацию о треке (исполнитель, трек, время прослушивания, альбом), кодируя их с помощью статического метода UrlEncode класса HttpUtility.
submissionReqString += "&artist=" + HttpUtility.UrlEncode(artist);
submissionReqString += "&track=" + HttpUtility.UrlEncode(track);
submissionReqString += "& timestamp=" + timestamp.ToString(); // в этой строке не должно быть пробела между & и t. Просто почему-то Хабр неправильно отображает этот участок, если пробел убрать.
submissionReqString += "&album=" + HttpUtility.UrlEncode(album);
// формируем сигнатуру (параметры должны записываться сплошняком (без символов '&' и '=' и в алфавитном порядке):
string signature = String.Empty;
// сначала добавляем альбом
signature += "album" + album;
// потом API Key
signature += "api_key" + ApiKey;
// исполнитель
signature += "artist" + artist;
// метод и ключ сессии
signature += "methodtrack.scrobblesk" + sessionKey;
// время
signature += "timestamp" + timestamp;
// имя трека
signature += "track" + track;
// добавляем секретный код в конец
signature += mySecret;
// добавляем сформированную и захешированную MD5 сигнатуру к строке запроса
submissionReqString += "&api_sig=" + MD5(signature);
// и на этот раз делаем POST запрос на нужную страницу
HttpWebRequest submissionRequest = (HttpWebRequest)WebRequest.Create("http://ws.audioscrobbler.com/2.0/"); // адрес запроса без параметров
// очень важная строка. Долго я мучался, пока не выяснил, что она обязательно должна быть
submissionRequest.ServicePoint.Expect100Continue = false;
// Настраиваем параметры запроса
submissionRequest.UserAgent = "Mozilla/5.0";
// Указываем метод отправки данных скрипту, в случае с POST обязательно
submissionRequest.Method = "POST";
// В случае с POST обязательная строка
submissionRequest.ContentType = "application/x-www-form-urlencoded";
// ставим таймаут, чтобы программа не повисла при неудаче обращения к серверу, а выкинула Exception
submissionRequest.Timeout = 6000;
// Преобразуем данные в соответствующую кодировку, получаем массив байтов из строки с параметрами (UTF8 обязательно)
byte[] EncodedPostParams = Encoding.UTF8.GetBytes(submissionReqString);
submissionRequest.ContentLength = EncodedPostParams.Length;
// Записываем данные в поток запроса (массив байтов, откуда начинаем, сколько записываем)
submissionRequest.GetRequestStream().Write(EncodedPostParams, 0, EncodedPostParams.Length);
// закрываем поток
submissionRequest.GetRequestStream().Close();
// получаем ответ сервера
HttpWebResponse submissionResponse = (HttpWebResponse)submissionRequest.GetResponse();
// считываем поток ответа
string submissionResult = new StreamReader(submissionResponse.GetResponseStream(), Encoding.UTF8).ReadToEnd();
// разбор полётов. Если ответ не содержит status="ok", то дело плохо, выкидываем Exception и где-нибудь ловим его.
if (!submissionResult.Contains("status="ok""))
throw new Exception("Треки не отправлены! Причина - " + submissionResult);
// иначе всё хорошо, выходим из метода и оповещаем пользователя, что трек заскробблен.
Таким образом, треки скробблятся без ввода пароля. Это обновлённый API, раньше ввод пароля требовался (это можно понять из моей программы). Сохранив куда-нибудь ключ сессии, вам не нужно будет каждый раз просить пользователя подтверждать доступ (ключ будет действовать до тех пор, пока пользователь не «отключит» ваш клиент от своего профиля на этой [10] странице).
Основные ссылки я привёл в начале статьи. Пожалуй, остаётся добавить ссылку на Last.fm форум для использующих API [11] (только на английском). Без его использования я вряд ли дошёл бы до конца.
На этом всё. Надеюсь, я достаточно подробно описал каждый свой шаг. Буду рад ответить на Ваши вопросы, если таковые возникнут.
Спасибо за внимание.
Автор: v_decadence
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/net/6675
Ссылки в тексте:
[1] этом: http://habrahabr.ru/post/143082/
[2] Last.fm: http://www.lastfm.ru/
[3] Last.fm API: http://www.last.fm/api
[4] этой ссылке: http://www.last.fm/api/account
[5] Получение токена: http://www.last.fm/api/show/auth.getToken
[6] Получение ключа сессии: http://www.last.fm/api/show/auth.getSession
[7] Скроббл трека: http://www.last.fm/api/show/track.scrobble
[8] HttpWebRequest: http://msdn.microsoft.com/ru-ru/library/system.net.httpwebrequest.aspx
[9] HttpWebResponse: http://msdn.microsoft.com/ru-ru/library/system.net.httpwebresponse.aspx
[10] этой: http://www.lastfm.ru/settings/applications
[11] API: http://www.lastfm.ru/group/Last.fm+Web+Services/forum/21604
Нажмите здесь для печати.