c#使用控制台实现QQ音乐爬虫
对于如何分析我没有过程,因为网上很多dalao都有说明,以下是效果图
以下为完整代码
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;namespace ConsoleApp2
{class Program{//QQ音乐private static string m_strGetQQMusicList = "https://c.y.qq.com/soso/fcgi-bin/client_search_cp?new_json=1&w=<<SongName>>&format=json";private static string m_strGetQQMusicVkey = "https://u.y.qq.com/cgi-bin/musicu.fcg?&data={\"req_0\":{\"module\":\"vkey.GetVkeyServer\",\"method\":\"CgiGetVkey\",\"param\":{\"guid\":\"958563768\",\"songmid\":[\"<<mid>>\"],\"uin\":\"291116260\"}}}";private static string m_strGetQQMusicDownloadURL = "http://ws.stream.qqmusic.qq.com/";static void Main(string[] args){string SongName = "";while (SongName != "0"){Console.WriteLine("请输入需要下载的音乐,输入0结束!");SongName = Console.ReadLine();string url = m_strGetQQMusicList.Replace("<<SongName>>", SongName);HttpClient m_htpClient = new HttpClient();HttpResponseMessage m_htpResponse = m_htpClient.GetAsync(new Uri(url)).Result;string strResult = m_htpResponse.Content.ReadAsStringAsync().Result;if (strResult.Substring(1, 8) == "\"code\":0"){JObject jo = (JObject)JsonConvert.DeserializeObject(strResult);string mid = "";for (int i = 0; i < jo["data"]["song"]["list"].Count(); i++){if (i == 0){//下载搜到的第一个mid = jo["data"]["song"]["list"][i]["mid"].ToString();break;}}string loadurl = m_strGetQQMusicVkey.Replace("<<mid>>", mid);m_htpResponse = m_htpClient.GetAsync(new Uri(loadurl)).Result;strResult = m_htpResponse.Content.ReadAsStringAsync().Result;if (strResult.Substring(1, 8) == "\"code\":0"){jo = (JObject)JsonConvert.DeserializeObject(strResult);strResult = jo["req_0"]["data"]["midurlinfo"][0]["flowurl"].ToString();strResult = m_strGetQQMusicDownloadURL + strResult; // 音乐路径string m_strFileFormat = jo["req_0"]["data"]["midurlinfo"][0]["filename"].ToString();m_strFileFormat = m_strFileFormat.Substring(m_strFileFormat.IndexOf(".")); // 音乐后缀名if (strResult != ""){string strFileName = SongName + m_strFileFormat;try{long startPosition = 0; // 上次下载的文件起始位置FileStream writeStream; // 写入本地文件流对象if (File.Exists(strFileName)){writeStream = File.OpenWrite(strFileName); // 存在则打开要下载的文件startPosition = writeStream.Length; // 获取已经下载的长度writeStream.Seek(startPosition, SeekOrigin.Current); // 本地文件写入位置定位}else{writeStream = new FileStream(strFileName, FileMode.Create);// 文件不保存创建一个文件startPosition = 0;}HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(strResult);// 打开网络连接Stream readStream = myRequest.GetResponse().GetResponseStream();// 向服务器请求,获得服务器的回应数据流byte[] btArray = new byte[512];// 定义一个字节数据,用来向readStream读取内容和向writeStream写入内容int contentSize = readStream.Read(btArray, 0, btArray.Length);// 向远程文件读第一次while (contentSize > 0)// 如果读取长度大于零则继续读{writeStream.Write(btArray, 0, contentSize);// 写入本地文件contentSize = readStream.Read(btArray, 0, btArray.Length);// 继续向远程文件读取}}catch (Exception ex){Console.WriteLine(ex.Message.ToString() + "\n下载失败!\n"); ;}Console.WriteLine("下载成功!\n");}}}else{Console.WriteLine("下载失败!\n");}}}}
}