前言:最近闲来无事,看了网上豆瓣的第三方客户端,手有点痒,决定自己动手开发一个客户端,比较了荔枝和喜马拉雅,决定开发喜马拉雅的第三方客户端。
客户端使用了WPF开发。
1.抓取接口;
首先得解决接口数据的问题,使用了手机端的喜马拉雅,抓包看了接口。这里推荐使用fiddler2这个工具。从图中可以看到接口信息,包括接口地址和参数的一些数据。
2.通过http获取接口数据和转换接口数据格式。
这里提供一个HttpWebRequestOpt类来获取接口数据。
using System; using System.Collections.Specialized; using System.IO; using System.Net; using System.Text; namespace XIMALAYA.PCDesktop.Untils { /// <summary> /// 数据操作类 /// </summary> public class HttpWebRequestOpt { /// <summary> /// /// </summary> public string UserAgent { get; set; } /// <summary> /// cookie /// </summary> private CookieContainer Cookies { get; set; } private HttpWebRequestOpt() { //FileVersionInfo myFileVersion = FileVersionInfo.GetVersionInfo(Path.Combine(Directory.GetCurrentDirectory(), "XIMALAYA.PCDesktop.exe")); this.Cookies = new CookieContainer(); //this.UserAgent = string.Format("ting-ximalaya_v{0} name/ximalaya os/{1} osName/{2}", myFileVersion.FileVersion, OSInfo.Instance.OsInfo.VersionString, OSInfo.Instance.OsInfo.Platform.ToString()); //this.Cookies.Add(new Cookie("4&_token", "935&d63fef280403904a8c0a5ee0dbe228f2d064", "/", ".ximalaya.com")); } /// <summary> /// 添加cookie /// </summary> /// <param name="cookie"></param> public void SetCookies(Cookie cookie) { this.Cookies.Add(cookie); } /// <summary> /// 添加cookie /// </summary> /// <param name="cookie"></param> public void SetCookies(string key, string val) { this.Cookies.Add(new Cookie(key, val, "/", ".ximalaya.com")); } /// <summary> /// 通过POST方式发送数据 /// </summary> /// <param name="Url">url</param> /// <param name="postDataStr">Post数据</param> /// <returns></returns> public string SendDataByPost(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); request.CookieContainer = this.Cookies; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = postDataStr.Length; request.UserAgent = this.UserAgent; Stream myRequestStream = request.GetRequestStream(); StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312")); myStreamWriter.Write(postDataStr); myStreamWriter.Close(); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; } /// <summary> /// 通过GET方式发送数据 /// </summary> /// <param name="Url">url</param> /// <param name="postDataStr">GET数据</param> /// <returns></returns> public string SendDataByGET(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); request.CookieContainer = this.Cookies; request.Method = "GET"; request.ContentType = "text/html;charset=UTF-8"; request.UserAgent = this.UserAgent; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; } /// <summary> /// 异步通过POST方式发送数据 /// </summary> /// <param name="Url">url</param> /// <param name="postDataStr">GET数据</param> /// <param name="async"></param> public void SendDataByPostAsyn(string Url, string postDataStr, AsyncCallback async) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); request.CookieContainer = this.Cookies; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = postDataStr.Length; request.UserAgent = this.UserAgent; Stream myRequestStream = request.GetRequestStream(); StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312")); myStreamWriter.Write(postDataStr); myStreamWriter.Close(); myRequestStream.Close(); request.BeginGetResponse(async, request); } /// <summary> /// 异步通过GET方式发送数据 /// </summary> /// <param name="Url">url</param> /// <param name="postDataStr">GET数据</param> /// <param name="async"></param> /// <returns></returns> public void SendDataByGETAsyn(string Url, string postDataStr, AsyncCallback async) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); request.CookieContainer = this.Cookies; request.Method = "GET"; request.ContentType = "text/html;charset=UTF-8"; request.UserAgent = this.UserAgent; request.BeginGetResponse(async, request); } /// <summary> /// 使用HttpWebRequest POST图片等文件,带参数 /// </summary> /// <param name="url"></param> /// <param name="file"></param> /// <param name="paramName"></param> /// <param name="contentType"></param> /// <param name="nvc"></param> /// <returns></returns> public string HttpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc) { string result = string.Empty; string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url); wr.ContentType = "multipart/form-data; boundary=" + boundary; wr.Method = "POST"; wr.KeepAlive = true; wr.Credentials = System.Net.CredentialCache.DefaultCredentials; Stream rs = wr.GetRequestStream(); string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; foreach (string key in nvc.Keys) { rs.Write(boundarybytes, 0, boundarybytes.Length); string formitem = string.Format(formdataTemplate, key, nvc[key]); byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); rs.Write(formitembytes, 0, formitembytes.Length); } rs.Write(boundarybytes, 0, boundarybytes.Length); string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n"; string header = string.Format(headerTemplate, paramName, file, contentType); byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); rs.Write(headerbytes, 0, headerbytes.Length); FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read); byte[] buffer = new byte[4096]; int bytesRead = 0; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) { rs.Write(buffer, 0, bytesRead); } fileStream.Close(); byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); rs.Write(trailer, 0, trailer.Length); rs.Close(); WebResponse wresp = null; try { wresp = wr.GetResponse(); Stream stream2 = wresp.GetResponseStream(); StreamReader reader2 = new StreamReader(stream2); result = reader2.ReadToEnd(); } catch (Exception ex) { if (wresp != null) { wresp.Close(); wresp = null; } } finally { wr = null; } return result; } } }