近来无聊 写了一个google音乐的下载器
一个用wpf设计的google音乐下载器
刚发现,如果下载的多了,google会要求输入验证码的,那时这个程序就挂了,不灵了,嘿
安装包下载地址:
http://www.rayfile.com/zh-cn/files/32c497bd-bf13-11de-97fa-0014221b798a/
已经支持专辑批量下载及查找了
http解析方面,用了Winista的包
主要就是分析网页的html结构 用先深搜索的方式找到要分析记录的结点。
以寻找一个歌手的专辑列表为例 要顺着
<html>---
<body class="GooglePage",id="GooglePage"……
<div class="body_agent"……
这种结构一直找下去,直到找到
<div class ="results" id="album_list"
再往下进行进一步的分析,提取到相应的内容即可
这里把分析的算法提成了一个公共类
因为之前不了解BS及WPF相关的内容,中间走了不少弯路,有些代码还没有进行优化,反正我批量下载音乐(俺是80后,最喜欢周华健那个年代的歌手,故狂下之)的目的已经达到了,呵呵。
好了,不多说了,贴代码!
网页分析类
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Winista.Text.HtmlParser.Lex;
using Winista.Text.HtmlParser;
using Winista.Text.HtmlParser.Util;
namespace SFTech.GMusic
{
internal class AnalyseMethod
{
internal NodeList AnalyseResult
{
get;
private set;
}
internal bool IsAnalyseSucess
{
get;
private set;
}
public int AnalyseLevel { get; private set; }
public void Anayse(String[,] Keys,String Url)
{
System.Net.WebClient aWebClient = new System.Net.WebClient();
aWebClient.Encoding = System.Text.Encoding.GetEncoding("GB2312");
string html = aWebClient.DownloadString(Url);
Lexer lexer = new Lexer(html);
Parser parser = new Parser(lexer );
NodeList htmlNodes = parser.Parse(null);
Anayse(Keys, htmlNodes);
}
public void Anayse(String[,] Keys,NodeList htmlNodes )
{
IsAnalyseSucess = true;
bool[] Flag = new bool[Keys.GetLength(0)];
for (int K = 0; K < Keys.GetLength(0); K++)
{
for (int i = 0; i < htmlNodes.Count; i++)
{
String s = htmlNodes[i].GetText();
if (htmlNodes[i] is ITag)
{
var Node = htmlNodes[i] as ITag;
var Name = Node.TagName;
string CLASS = Node.Attributes["CLASS"] == null ? null : Node.Attributes["CLASS"].ToString();
string id = Node.Attributes["ID"] == null ? null : Node.Attributes["ID"].ToString();
System.Console.WriteLine("Tag--" + s);
if ((Keys[K, 0] == null || Node.TagName.Trim().ToLower() == Keys[K, 0].Trim().ToLower())
&& ( Keys[K, 1] == CLASS ||(Keys[K,1]!=null&&Keys[K,1].IndexOf(' ')>0 && Keys[K,1].Split(' ').Contains(CLASS)))
&& (Keys[K, 2] == id))
{
htmlNodes = Node.Children;
System.Console.WriteLine("Find Name:{0} ,Class:{1},ID:{2}", Name, CLASS, id);
Flag[K] = true;
break;
}
}
else
{
var I = htmlNodes[i];
System.Console.WriteLine("NoTag:" + s);
Flag[K] = false;
}
}
if (Flag[K] == false)
{
AnalyseLevel = K;
break;
}
}
IsAnalyseSucess = true;
this.AnalyseResult = htmlNodes;
for (int i = 0; i < Flag.Length; i++)
IsAnalyseSucess &= Flag[i];
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Winista.Text.HtmlParser.Lex;
using Winista.Text.HtmlParser;
using Winista.Text.HtmlParser.Util;
namespace SFTech.GMusic
{
internal class AnalyseMethod
{
internal NodeList AnalyseResult
{
get;
private set;
}
internal bool IsAnalyseSucess
{
get;
private set;
}
public int AnalyseLevel { get; private set; }
public void Anayse(String[,] Keys,String Url)
{
System.Net.WebClient aWebClient = new System.Net.WebClient();
aWebClient.Encoding = System.Text.Encoding.GetEncoding("GB2312");
string html = aWebClient.DownloadString(Url);
Lexer lexer = new Lexer(html);
Parser parser = new Parser(lexer );
NodeList htmlNodes = parser.Parse(null);
Anayse(Keys, htmlNodes);
}
public void Anayse(String[,] Keys,NodeList htmlNodes )
{
IsAnalyseSucess = true;
bool[] Flag = new bool[Keys.GetLength(0)];
for (int K = 0; K < Keys.GetLength(0); K++)
{
for (int i = 0; i < htmlNodes.Count; i++)
{
String s = htmlNodes[i].GetText();
if (htmlNodes[i] is ITag)
{
var Node = htmlNodes[i] as ITag;
var Name = Node.TagName;
string CLASS = Node.Attributes["CLASS"] == null ? null : Node.Attributes["CLASS"].ToString();
string id = Node.Attributes["ID"] == null ? null : Node.Attributes["ID"].ToString();
System.Console.WriteLine("Tag--" + s);
if ((Keys[K, 0] == null || Node.TagName.Trim().ToLower() == Keys[K, 0].Trim().ToLower())
&& ( Keys[K, 1] == CLASS ||(Keys[K,1]!=null&&Keys[K,1].IndexOf(' ')>0 && Keys[K,1].Split(' ').Contains(CLASS)))
&& (Keys[K, 2] == id))
{
htmlNodes = Node.Children;
System.Console.WriteLine("Find Name:{0} ,Class:{1},ID:{2}", Name, CLASS, id);
Flag[K] = true;
break;
}
}
else
{
var I = htmlNodes[i];
System.Console.WriteLine("NoTag:" + s);
Flag[K] = false;
}
}
if (Flag[K] == false)
{
AnalyseLevel = K;
break;
}
}
IsAnalyseSucess = true;
this.AnalyseResult = htmlNodes;
for (int i = 0; i < Flag.Length; i++)
IsAnalyseSucess &= Flag[i];
}
}
}
抽象的类别
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SFTech.GMusic
{
public abstract class Artist_Type
{
public String ShowName { get; protected set; }
public String Value { get; protected set; }
public override string ToString()
{
return ShowName;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SFTech.GMusic
{
public abstract class Artist_Type
{
public String ShowName { get; protected set; }
public String Value { get; protected set; }
public override string ToString()
{
return ShowName;
}
}
}
歌手类
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SFTech.GMusic
{
public class ArtistClass :Artist_Type
{
private ArtistClass(String name, string value)
{
this.Value = value;
this.ShowName = name;
}
public static ArtistClass[] ArtistClasses { get; private set; }
static ArtistClass()
{
ArtistClasses = new ArtistClass[3];
ArtistClasses[0] = new ArtistClass("男歌手", "male");
ArtistClasses[1] = new ArtistClass("女歌手", "female");
ArtistClasses[2] = new ArtistClass("乐队组合", "bandgroup");
}
public override string ToString()
{
return base.ToString();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SFTech.GMusic
{
public class ArtistClass :Artist_Type
{
private ArtistClass(String name, string value)
{
this.Value = value;
this.ShowName = name;
}
public static ArtistClass[] ArtistClasses { get; private set; }
static ArtistClass()
{
ArtistClasses = new ArtistClass[3];
ArtistClasses[0] = new ArtistClass("男歌手", "male");
ArtistClasses[1] = new ArtistClass("女歌手", "female");
ArtistClasses[2] = new ArtistClass("乐队组合", "bandgroup");
}
public override string ToString()
{
return base.ToString();
}
}
}
地区
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SFTech.GMusic
{
public class Region :Artist_Type
{
private Region(String name, string value)
{
this.Value = value;
this.ShowName = name;
}
public static Region[] Regions { get; private set; }
static Region()
{
Regions = new Region[4];
Regions[0] = new Region("华语", "cn");
Regions[1] = new Region("欧美", "eu_us");
Regions[2] = new Region("日韩", "jp_kr");
Regions[3] = new Region("其他", "others");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SFTech.GMusic
{
public class Region :Artist_Type
{
private Region(String name, string value)
{
this.Value = value;
this.ShowName = name;
}
public static Region[] Regions { get; private set; }
static Region()
{
Regions = new Region[4];
Regions[0] = new Region("华语", "cn");
Regions[1] = new Region("欧美", "eu_us");
Regions[2] = new Region("日韩", "jp_kr");
Regions[3] = new Region("其他", "others");
}
}
}
歌手类 可以得到一个人的所有专辑
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Winista.Text.HtmlParser;
namespace SFTech.GMusic
{
public class Artist
{
public static List<Artist> GetArtist(Region Reg, ArtistClass AClass)
{
List<Artist> _result = new List<Artist>();
AnalyseMethod method = new AnalyseMethod();
method.Anayse(GetListKeys,"http://www.google.cn/music/artistlibrary?region="+Reg.Value +"&type="+AClass.Value );
if(method.IsAnalyseSucess ){
var Nodes = method.AnalyseResult;
for(int i= 0;i<Nodes.Count;i++){
if(Nodes[i] is ITag ){
var tag = Nodes[i] as ITag;
if(tag.TagName =="DIV"&&tag.Attributes["CLASS"]!=null
&&tag.Attributes["CLASS"].ToString().Trim().ToLower()=="artists_frame"){
System.Console.WriteLine("分析到:"+tag.Attributes["ID"].ToString());
AnalyseMethod labelMethod = new AnalyseMethod();
labelMethod.Anayse(Artist.GetLabelKeys,tag.Children);
if(labelMethod.IsAnalyseSucess){
var LableNodes = labelMethod.AnalyseResult;
for(int j=0;j<LableNodes.Count;j++){
if(LableNodes[j] is ITag ){
var trTag = LableNodes[j] as ITag;
if(trTag.TagName =="TR"){
if(trTag.Children !=null
&&trTag.Children.Count>0){
for(int tdIndex = 0;tdIndex<trTag.Children.Count;tdIndex ++){
var tdTag = trTag.Children[tdIndex] as ITag;
if(tdTag != null){
if(tdTag.TagName == "TD" && tdTag.Attributes["CLASS"]!=null
&&(tdTag.Attributes["CLASS"].ToString()=="artist_name"||
tdTag.Attributes["CLASS"].ToString() =="artist_name wider")){
for(int herfIndex = 0;herfIndex<tdTag.Children.Count ;herfIndex ++){
var herNod = tdTag.Children[herfIndex] as ITag ;
if(herNod != null){
if(herNod.Attributes ["HREF"]!=null){
string url = herNod.Attributes["HREF"].ToString().Replace("&","&");
string name = StringCoder.Encode ( herNod.ToPlainTextString());
_result .Add(new Artist(name,"http://www.google.cn"+url));
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return _result;
}
public string Name
{
get;
private set;
}
public List<Album> Albums
{
get
{
if (_Albums == null)
LoadAlbums();
return _Albums;
}
}
public string Herf
{
get;
set;
}
public List<Song> HotSongs
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public string Description
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public Artist(String name, string herf)
{
Name = name;
Herf = herf;
}
public override string ToString()
{
//return base.ToString();
return Name + " " + Herf;
}
private List<Album> _Albums;
private void LoadAlbums()
{
var analyse= new AnalyseMethod();
analyse.Anayse(Keys, this.Herf);
if (analyse.IsAnalyseSucess == false)
{
if (analyse.AnalyseLevel == AlbumLevel)
_Albums = new List<Album>();
return;
}
else
{
var htmlNodes = analyse.AnalyseResult;
_Albums = new List<Album>();
for (int Index = 0; Index < htmlNodes.Count; Index++)
{
if (htmlNodes[Index] is ITag)
{
var Tag = htmlNodes[Index] as ITag;
if (Tag.TagName.Trim().ToLower() == "table")
{
if (Tag.Attributes["ID"] != null && Tag.Attributes["ID"].ToString().Trim() == "album_item" &&
Tag.Attributes["CLASS"] != null && Tag.Attributes["CLASS"].ToString().Trim() == "AlbumItem")
{
analyse.Anayse(AlbumKeys, Tag.Children);
if (analyse.IsAnalyseSucess)
{
var result = analyse.AnalyseResult;
INode node = result[0];
String AName = "";
String AHref = "";
for (int rI = 0; rI < result.Count; rI++)
{
if (result[rI] is ITag)
{
var rTag = result[rI] as ITag;
if (rTag.Attributes["NAME"] != null
&& rTag.Attributes["NAME"].ToString().Trim() == "LandingPageLink")
AName = StringCoder.Encode(rTag.ToPlainTextString());
else if (rTag.Attributes["ID"] != null
)
{
string a = rTag.Attributes["ID"].ToString();
if (a.IndexOf("album-streaming-") == 0)
AHref = a.Replace("album-streaming-", "/music/album?id=");
}
}
}
_Albums.Add(new Album(AName, "http://www.google.cn"+AHref));
}
}
}
}
}
}
}
private static String[,] Keys = new string[,]
{
{"html",null,null },
{"body","GooglePage","GooglePage"},
{"div","body_agent",null},
{"div",null,"music_header"},
{"div",null,"main_content"},
{"table","fulltable",null },
{"tr",null,null },
{"td","maincontent paddingright",null },
{"div",null,"artist-albums-list"},
{"div","results","album_list"}
};
public static int AlbumLevel = 8;
private static string[,] AlbumKeys = new string[,]{
{"tr",null,null},
{"td",null,null},
{"table","AlbumInfo",null },
{"tr",null,null},
{"td","Title",null }};
private static string [,] GetListKeys = new string [,]{
{"html",null,null },
{"body","GooglePage","GooglePage"},
{"div","body_agent",null},
{"div",null,"music_header"},
{"div",null,"main_content"},
{"div",null,"rightbox"},
{"div",null,"artists_division"}
};
private static string [,] GetLabelKeys =new string[,]{
{"table","artists_frame",null},
{"tr",null,null },
{"td","artist_name_list",null},
{"div","artist_name_list",null},
{"table","artist_name_list",null}};
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Winista.Text.HtmlParser;
namespace SFTech.GMusic
{
public class Artist
{
public static List<Artist> GetArtist(Region Reg, ArtistClass AClass)
{
List<Artist> _result = new List<Artist>();
AnalyseMethod method = new AnalyseMethod();
method.Anayse(GetListKeys,"http://www.google.cn/music/artistlibrary?region="+Reg.Value +"&type="+AClass.Value );
if(method.IsAnalyseSucess ){
var Nodes = method.AnalyseResult;
for(int i= 0;i<Nodes.Count;i++){
if(Nodes[i] is ITag ){
var tag = Nodes[i] as ITag;
if(tag.TagName =="DIV"&&tag.Attributes["CLASS"]!=null
&&tag.Attributes["CLASS"].ToString().Trim().ToLower()=="artists_frame"){
System.Console.WriteLine("分析到:"+tag.Attributes["ID"].ToString());
AnalyseMethod labelMethod = new AnalyseMethod();
labelMethod.Anayse(Artist.GetLabelKeys,tag.Children);
if(labelMethod.IsAnalyseSucess){
var LableNodes = labelMethod.AnalyseResult;
for(int j=0;j<LableNodes.Count;j++){
if(LableNodes[j] is ITag ){
var trTag = LableNodes[j] as ITag;
if(trTag.TagName =="TR"){
if(trTag.Children !=null
&&trTag.Children.Count>0){
for(int tdIndex = 0;tdIndex<trTag.Children.Count;tdIndex ++){
var tdTag = trTag.Children[tdIndex] as ITag;
if(tdTag != null){
if(tdTag.TagName == "TD" && tdTag.Attributes["CLASS"]!=null
&&(tdTag.Attributes["CLASS"].ToString()=="artist_name"||
tdTag.Attributes["CLASS"].ToString() =="artist_name wider")){
for(int herfIndex = 0;herfIndex<tdTag.Children.Count ;herfIndex ++){
var herNod = tdTag.Children[herfIndex] as ITag ;
if(herNod != null){
if(herNod.Attributes ["HREF"]!=null){
string url = herNod.Attributes["HREF"].ToString().Replace("&","&");
string name = StringCoder.Encode ( herNod.ToPlainTextString());
_result .Add(new Artist(name,"http://www.google.cn"+url));
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return _result;
}
public string Name
{
get;
private set;
}
public List<Album> Albums
{
get
{
if (_Albums == null)
LoadAlbums();
return _Albums;
}
}
public string Herf
{
get;
set;
}
public List<Song> HotSongs
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public string Description
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public Artist(String name, string herf)
{
Name = name;
Herf = herf;
}
public override string ToString()
{
//return base.ToString();
return Name + " " + Herf;
}
private List<Album> _Albums;
private void LoadAlbums()
{
var analyse= new AnalyseMethod();
analyse.Anayse(Keys, this.Herf);
if (analyse.IsAnalyseSucess == false)
{
if (analyse.AnalyseLevel == AlbumLevel)
_Albums = new List<Album>();
return;
}
else
{
var htmlNodes = analyse.AnalyseResult;
_Albums = new List<Album>();
for (int Index = 0; Index < htmlNodes.Count; Index++)
{
if (htmlNodes[Index] is ITag)
{
var Tag = htmlNodes[Index] as ITag;
if (Tag.TagName.Trim().ToLower() == "table")
{
if (Tag.Attributes["ID"] != null && Tag.Attributes["ID"].ToString().Trim() == "album_item" &&
Tag.Attributes["CLASS"] != null && Tag.Attributes["CLASS"].ToString().Trim() == "AlbumItem")
{
analyse.Anayse(AlbumKeys, Tag.Children);
if (analyse.IsAnalyseSucess)
{
var result = analyse.AnalyseResult;
INode node = result[0];
String AName = "";
String AHref = "";
for (int rI = 0; rI < result.Count; rI++)
{
if (result[rI] is ITag)
{
var rTag = result[rI] as ITag;
if (rTag.Attributes["NAME"] != null
&& rTag.Attributes["NAME"].ToString().Trim() == "LandingPageLink")
AName = StringCoder.Encode(rTag.ToPlainTextString());
else if (rTag.Attributes["ID"] != null
)
{
string a = rTag.Attributes["ID"].ToString();
if (a.IndexOf("album-streaming-") == 0)
AHref = a.Replace("album-streaming-", "/music/album?id=");
}
}
}
_Albums.Add(new Album(AName, "http://www.google.cn"+AHref));
}
}
}
}
}
}
}
private static String[,] Keys = new string[,]
{
{"html",null,null },
{"body","GooglePage","GooglePage"},
{"div","body_agent",null},
{"div",null,"music_header"},
{"div",null,"main_content"},
{"table","fulltable",null },
{"tr",null,null },
{"td","maincontent paddingright",null },
{"div",null,"artist-albums-list"},
{"div","results","album_list"}
};
public static int AlbumLevel = 8;
private static string[,] AlbumKeys = new string[,]{
{"tr",null,null},
{"td",null,null},
{"table","AlbumInfo",null },
{"tr",null,null},
{"td","Title",null }};
private static string [,] GetListKeys = new string [,]{
{"html",null,null },
{"body","GooglePage","GooglePage"},
{"div","body_agent",null},
{"div",null,"music_header"},
{"div",null,"main_content"},
{"div",null,"rightbox"},
{"div",null,"artists_division"}
};
private static string [,] GetLabelKeys =new string[,]{
{"table","artists_frame",null},
{"tr",null,null },
{"td","artist_name_list",null},
{"div","artist_name_list",null},
{"table","artist_name_list",null}};
}
}
专辑类 Album
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Winista.Text.HtmlParser;
using Winista.Text.HtmlParser.Lex;
using Winista.Text.HtmlParser.Util;
using System.Web;
namespace SFTech.GMusic
{
public class Album
{
public string Name
{
get;
private set;
}
public System.DateTime Date
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public String Description
{
get;
private set;
}
public List<Song> Songs
{
get
{
if(_Songs ==null)
LoadSongs();
return _Songs;
}
}
public string Herf
{
get;
private set;
}
public Album(String Name, String herf)
{
this.Name = Name;
this.Herf = herf;
}
private List<Song> _Songs;
private void LoadSongs()
{
var analyse= new AnalyseMethod();
analyse.Anayse(Keys, this.Herf);
if (analyse.IsAnalyseSucess == false)
return;
else
{
var htmlNodes = analyse.AnalyseResult;
_Songs = new List<Song>();
for (int Index = 0; Index < htmlNodes.Count; Index++)
{
if (htmlNodes[Index] is ITag)
{
var Tag = htmlNodes[Index] as ITag;
if (Tag.TagName.Trim().ToLower() == "tr")
{
if (Tag.Attributes["ID"] != null)
{
var SId = Tag.Attributes["ID"].ToString();
var did = SId;
if (SId != null || SId.IndexOf("row") == 0)
{
SId = SId.Substring(3);
did = SId;
String SName = "";
for (int CIndex = 0; CIndex < Tag.Children.Count; CIndex++)
{
if (Tag.Children[CIndex] is ITag)
{
var NameTag = Tag.Children[CIndex] as ITag;
if (NameTag.TagName.Trim().ToLower() == "td"
&& NameTag.Attributes["CLASS"] != null
&& NameTag.Attributes["CLASS"].ToString() == "Title BottomBorder"
)
{
SName = StringCoder.Encode(NameTag.ToPlainTextString());
}
if (NameTag.TagName.Trim().ToLower() == "td"
&& NameTag.Attributes["CLASS"] != null
&& NameTag.Attributes["CLASS"].ToString() == "Icon BottomBorder"
)
{
bool isFind = false;
for (int k = 0; k < NameTag.Children.Count; k++)
{
var HerfTag = NameTag.Children[k] as ITag;
//if (HerfTag != null)
//{
// System.Console.WriteLine(HerfTag.Attributes["TITLE"]);
//}
if (HerfTag != null &&
HerfTag.TagName.Trim().ToLower()=="a"
&&HerfTag.Attributes["TITLE"] != null
)
{
SId = HerfTag.Attributes["ONCLICK"].ToString();
if (SId.IndexOf("download.html") > 0)
{
// SId = SId.Replace("&", "&").Replace(""", "\"");
SId = HttpUtility.HtmlDecode(SId );
SId = HttpUtility.UrlDecode(SId);
SId = SId.Replace("\\x3d", "=");
SId =SId.Replace("\\x26", "&");
String[] s = SId.Split(new string[] { "\""}, StringSplitOptions.RemoveEmptyEntries);
SId = s[1];
isFind = true;
break;
}
}
}
if (isFind)
break;
// SName = StringCoder.Encode(NameTag.ToPlainTextString());
//break;
}
}
}
_Songs.Add(new Song(SId,did , SName));
}
}
}
}
}
}
}
//类型,ID
private static string[,] Keys = new string[,]{
{"html",null,null },
{"body","GooglePage","GooglePage"},
{"div","body_agent",null},
{"div",null,"music_header"},
{"div",null,"main_content"},
{"table","fulltable",null },
{"tr",null,null },
{"td","maincontent paddingright",null },
{"div",null,"album_song_list"},
{"div","results",null},
{"table","SongList","song_list"}
};
public override string ToString()
{
//return base.ToString();
return this.Name;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Winista.Text.HtmlParser;
using Winista.Text.HtmlParser.Lex;
using Winista.Text.HtmlParser.Util;
using System.Web;
namespace SFTech.GMusic
{
public class Album
{
public string Name
{
get;
private set;
}
public System.DateTime Date
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public String Description
{
get;
private set;
}
public List<Song> Songs
{
get
{
if(_Songs ==null)
LoadSongs();
return _Songs;
}
}
public string Herf
{
get;
private set;
}
public Album(String Name, String herf)
{
this.Name = Name;
this.Herf = herf;
}
private List<Song> _Songs;
private void LoadSongs()
{
var analyse= new AnalyseMethod();
analyse.Anayse(Keys, this.Herf);
if (analyse.IsAnalyseSucess == false)
return;
else
{
var htmlNodes = analyse.AnalyseResult;
_Songs = new List<Song>();
for (int Index = 0; Index < htmlNodes.Count; Index++)
{
if (htmlNodes[Index] is ITag)
{
var Tag = htmlNodes[Index] as ITag;
if (Tag.TagName.Trim().ToLower() == "tr")
{
if (Tag.Attributes["ID"] != null)
{
var SId = Tag.Attributes["ID"].ToString();
var did = SId;
if (SId != null || SId.IndexOf("row") == 0)
{
SId = SId.Substring(3);
did = SId;
String SName = "";
for (int CIndex = 0; CIndex < Tag.Children.Count; CIndex++)
{
if (Tag.Children[CIndex] is ITag)
{
var NameTag = Tag.Children[CIndex] as ITag;
if (NameTag.TagName.Trim().ToLower() == "td"
&& NameTag.Attributes["CLASS"] != null
&& NameTag.Attributes["CLASS"].ToString() == "Title BottomBorder"
)
{
SName = StringCoder.Encode(NameTag.ToPlainTextString());
}
if (NameTag.TagName.Trim().ToLower() == "td"
&& NameTag.Attributes["CLASS"] != null
&& NameTag.Attributes["CLASS"].ToString() == "Icon BottomBorder"
)
{
bool isFind = false;
for (int k = 0; k < NameTag.Children.Count; k++)
{
var HerfTag = NameTag.Children[k] as ITag;
//if (HerfTag != null)
//{
// System.Console.WriteLine(HerfTag.Attributes["TITLE"]);
//}
if (HerfTag != null &&
HerfTag.TagName.Trim().ToLower()=="a"
&&HerfTag.Attributes["TITLE"] != null
)
{
SId = HerfTag.Attributes["ONCLICK"].ToString();
if (SId.IndexOf("download.html") > 0)
{
// SId = SId.Replace("&", "&").Replace(""", "\"");
SId = HttpUtility.HtmlDecode(SId );
SId = HttpUtility.UrlDecode(SId);
SId = SId.Replace("\\x3d", "=");
SId =SId.Replace("\\x26", "&");
String[] s = SId.Split(new string[] { "\""}, StringSplitOptions.RemoveEmptyEntries);
SId = s[1];
isFind = true;
break;
}
}
}
if (isFind)
break;
// SName = StringCoder.Encode(NameTag.ToPlainTextString());
//break;
}
}
}
_Songs.Add(new Song(SId,did , SName));
}
}
}
}
}
}
}
//类型,ID
private static string[,] Keys = new string[,]{
{"html",null,null },
{"body","GooglePage","GooglePage"},
{"div","body_agent",null},
{"div",null,"music_header"},
{"div",null,"main_content"},
{"table","fulltable",null },
{"tr",null,null },
{"td","maincontent paddingright",null },
{"div",null,"album_song_list"},
{"div","results",null},
{"table","SongList","song_list"}
};
public override string ToString()
{
//return base.ToString();
return this.Name;
}
}
}
歌曲类
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Winista.Text.HtmlParser;
namespace SFTech.GMusic
{
public class Song
{
public string ID
{
get;
private set;
}
public string Name
{
get;
private set;
}
internal String GetUrl()
{
String url = "http://www.google.cn" + this.ID;
//System.Net.HttpWebRequest.Create(url).GetResponse().ResponseUri.t
var methodd = new AnalyseMethod();
string DownLoadUrl="";
methodd.Anayse(Keys, url);
if (methodd.IsAnalyseSucess == false)
{
url = "http://www.google.cn/music/top100/musicdownload?id=" + this.SongID;// Saee43bb8a885d3db
methodd.Anayse(Keys, url);
}
if (methodd.IsAnalyseSucess)
{
var nods = methodd.AnalyseResult;
for (int i = 0; i < nods.Count; i++)
{
if (nods[i] is ITag)
{
var Tag = nods[i] as ITag;
if (Tag.TagName == "A")
{
if (Tag.Attributes["HREF"] != null)
{
String temp=Tag.Attributes["HREF"].ToString();
if (temp.IndexOf("/music/top100/url?q=http") == 0)
{
DownLoadUrl = temp.Replace("&","&");
break;
}
}
}
}
}
}
if (DownLoadUrl != null)
{
String durl = "http://www.google.cn" + DownLoadUrl;
return durl;
}
return null;
}
public Song(String id,String did, String name)
{
ID = id;
Name = name.Trim();
SongID = did;
}
public String SongID
{
get;
private set;
}
public override string ToString()
{
//return base.ToString();
return Name;
}
private static String[,] Keys = new String[,]{
{"html",null,null},
{"body",null,null},
{"div","download",null}
};
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Winista.Text.HtmlParser;
namespace SFTech.GMusic
{
public class Song
{
public string ID
{
get;
private set;
}
public string Name
{
get;
private set;
}
internal String GetUrl()
{
String url = "http://www.google.cn" + this.ID;
//System.Net.HttpWebRequest.Create(url).GetResponse().ResponseUri.t
var methodd = new AnalyseMethod();
string DownLoadUrl="";
methodd.Anayse(Keys, url);
if (methodd.IsAnalyseSucess == false)
{
url = "http://www.google.cn/music/top100/musicdownload?id=" + this.SongID;// Saee43bb8a885d3db
methodd.Anayse(Keys, url);
}
if (methodd.IsAnalyseSucess)
{
var nods = methodd.AnalyseResult;
for (int i = 0; i < nods.Count; i++)
{
if (nods[i] is ITag)
{
var Tag = nods[i] as ITag;
if (Tag.TagName == "A")
{
if (Tag.Attributes["HREF"] != null)
{
String temp=Tag.Attributes["HREF"].ToString();
if (temp.IndexOf("/music/top100/url?q=http") == 0)
{
DownLoadUrl = temp.Replace("&","&");
break;
}
}
}
}
}
}
if (DownLoadUrl != null)
{
String durl = "http://www.google.cn" + DownLoadUrl;
return durl;
}
return null;
}
public Song(String id,String did, String name)
{
ID = id;
Name = name.Trim();
SongID = did;
}
public String SongID
{
get;
private set;
}
public override string ToString()
{
//return base.ToString();
return Name;
}
private static String[,] Keys = new String[,]{
{"html",null,null},
{"body",null,null},
{"div","download",null}
};
}
}
下载的状态
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SFTech.GMusic
{
public enum DownloadState
{
GetUrl,
DownLoading,
Suspand,
Success,
Queue,
Failed
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SFTech.GMusic
{
public enum DownloadState
{
GetUrl,
DownLoading,
Suspand,
Success,
Queue,
Failed
}
}
下载
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.ComponentModel;
namespace SFTech.GMusic
{
public class SongDownloader : INotifyPropertyChanged
{
private static object ob = new object();
private DownloadState downLoadState;
public DownloadState DownloadState
{
get
{
return downLoadState;
}
set
{
downLoadState = value;
Notify("DownloadState");
}
}
public Song Song
{
get;
private set;
}
private int downloadRate;
public int DownLoadRate
{
get
{
return downloadRate;
}
set
{
downloadRate = value;
Notify("DownLoadRate");
}
}
/// <summary>
/// 获取下载文件大小
/// </summary>
/// <param name="url">连接</param>
/// <returns>文件长度</returns>
private long getDownLength(string url)
{
try
{
WebRequest wrq = WebRequest.Create(url);
WebResponse wrp = (WebResponse)wrq.GetResponse();
wrp.Close();
return wrp.ContentLength;
}
catch (Exception ex)
{
// MessageBox.Show(ex.Message);
return 0;
}
}
//服务器文件大小
private long fileLength;
//已经下载文件大小
private long downLength;
//下载暂停终止状态
public static bool stopDown;
private System.Threading.Thread work;
private void DownLoadFile(object file)
{
this.DownloadState = DownloadState.Queue;
lock (ob)
{
try
{
long lStartPos = 0;
this.DownloadState = DownloadState.GetUrl;
string url = this.Song.GetUrl();
Stream fs = null, ns = null;
string fileName = file.ToString();
fileName = fileName + this.Name + ".mp3";
//得到网络文件大小
fileLength = this.getDownLength(url);
if (fileLength > 0)
{
if (File.Exists(fileName))
{
//打开文件,并得到已经下载量
fs = File.OpenWrite(fileName);
lStartPos = downLength = fs.Length;
//进度条
this.DownLoadRate = (int)(downLength * 100 / fileLength);
if (downLength == fileLength)
{
this.DownloadState = DownloadState.Success;
fs.Close();
fs.Dispose();
return;
}
else
{
//移动文件流中的当前指针
fs.Seek(lStartPos, SeekOrigin.Current);
this.DownloadState = DownloadState.DownLoading;
}
}
else //文件不存在则重新创建
{
fs = File.Create(fileName);
//fs = new System.IO.FileStream(fileName, FileMode.Create);
lStartPos = 0;
}
//打开网络连接
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
if (lStartPos > 0)
request.AddRange((int)lStartPos); //设置Range值
//向服务器请求,获得服务器回应数据流
ns = request.GetResponse().GetResponseStream();
byte[] nbytes = new byte[1024];
int nReadSize = 0;
this.DownloadState = DownloadState.DownLoading;
nReadSize = ns.Read(nbytes, 0, 1024);
while (nReadSize > 0)
{
if (stopDown) //是否暂停下载
break;
downLength += nReadSize;//已经下载大小
fs.Write(nbytes, 0, nReadSize);//写文件
nReadSize = ns.Read(nbytes, 0, 1024); //继续读流
this.DownLoadRate = (int)(downLength * 100 / fileLength);
//System.Net.Mime.MediaTypeNames.Application.DoEvents();
}
fs.Close();
fs.Dispose();
ns.Close();
ns.Dispose();
this.DownloadState = DownloadState.Success;
}
catch (Exception ex)
{
if (fs != null)
{
fs.Close();
fs.Dispose();
}
if (ns != null)
{
ns.Close();
ns.Dispose();
}
}
}
}
catch
{
this.DownloadState = DownloadState.Failed;
}
}
}
public void BeginDownLoadAs(String fileName)
{
if (work == null)
{
work = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(
this.DownLoadFile));
work.Start(fileName as object );
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void Notify(String Name)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(Name));
}
#endregion
public SongDownloader(Song song)
{
this.Song = song;
}
public string Name
{
get
{
return this.Song.Name;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.ComponentModel;
namespace SFTech.GMusic
{
public class SongDownloader : INotifyPropertyChanged
{
private static object ob = new object();
private DownloadState downLoadState;
public DownloadState DownloadState
{
get
{
return downLoadState;
}
set
{
downLoadState = value;
Notify("DownloadState");
}
}
public Song Song
{
get;
private set;
}
private int downloadRate;
public int DownLoadRate
{
get
{
return downloadRate;
}
set
{
downloadRate = value;
Notify("DownLoadRate");
}
}
/// <summary>
/// 获取下载文件大小
/// </summary>
/// <param name="url">连接</param>
/// <returns>文件长度</returns>
private long getDownLength(string url)
{
try
{
WebRequest wrq = WebRequest.Create(url);
WebResponse wrp = (WebResponse)wrq.GetResponse();
wrp.Close();
return wrp.ContentLength;
}
catch (Exception ex)
{
// MessageBox.Show(ex.Message);
return 0;
}
}
//服务器文件大小
private long fileLength;
//已经下载文件大小
private long downLength;
//下载暂停终止状态
public static bool stopDown;
private System.Threading.Thread work;
private void DownLoadFile(object file)
{
this.DownloadState = DownloadState.Queue;
lock (ob)
{
try
{
long lStartPos = 0;
this.DownloadState = DownloadState.GetUrl;
string url = this.Song.GetUrl();
Stream fs = null, ns = null;
string fileName = file.ToString();
fileName = fileName + this.Name + ".mp3";
//得到网络文件大小
fileLength = this.getDownLength(url);
if (fileLength > 0)
{
if (File.Exists(fileName))
{
//打开文件,并得到已经下载量
fs = File.OpenWrite(fileName);
lStartPos = downLength = fs.Length;
//进度条
this.DownLoadRate = (int)(downLength * 100 / fileLength);
if (downLength == fileLength)
{
this.DownloadState = DownloadState.Success;
fs.Close();
fs.Dispose();
return;
}
else
{
//移动文件流中的当前指针
fs.Seek(lStartPos, SeekOrigin.Current);
this.DownloadState = DownloadState.DownLoading;
}
}
else //文件不存在则重新创建
{
fs = File.Create(fileName);
//fs = new System.IO.FileStream(fileName, FileMode.Create);
lStartPos = 0;
}
//打开网络连接
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
if (lStartPos > 0)
request.AddRange((int)lStartPos); //设置Range值
//向服务器请求,获得服务器回应数据流
ns = request.GetResponse().GetResponseStream();
byte[] nbytes = new byte[1024];
int nReadSize = 0;
this.DownloadState = DownloadState.DownLoading;
nReadSize = ns.Read(nbytes, 0, 1024);
while (nReadSize > 0)
{
if (stopDown) //是否暂停下载
break;
downLength += nReadSize;//已经下载大小
fs.Write(nbytes, 0, nReadSize);//写文件
nReadSize = ns.Read(nbytes, 0, 1024); //继续读流
this.DownLoadRate = (int)(downLength * 100 / fileLength);
//System.Net.Mime.MediaTypeNames.Application.DoEvents();
}
fs.Close();
fs.Dispose();
ns.Close();
ns.Dispose();
this.DownloadState = DownloadState.Success;
}
catch (Exception ex)
{
if (fs != null)
{
fs.Close();
fs.Dispose();
}
if (ns != null)
{
ns.Close();
ns.Dispose();
}
}
}
}
catch
{
this.DownloadState = DownloadState.Failed;
}
}
}
public void BeginDownLoadAs(String fileName)
{
if (work == null)
{
work = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(
this.DownLoadFile));
work.Start(fileName as object );
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void Notify(String Name)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(Name));
}
#endregion
public SongDownloader(Song song)
{
this.Song = song;
}
public string Name
{
get
{
return this.Song.Name;
}
}
}
}
一个辅助的串解析类
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SFTech.GMusic
{
public class StringCoder
{
public static string Encode(String str){
string outStr = "";
var temp = str;
int index = temp.IndexOf("銆?");
if (index >= 0)
{
temp = temp.Substring(2);
index = temp.IndexOf("銆?");
if (index >= 0)
temp = temp.Substring(0, index);
}
str = temp;
if (!string.IsNullOrEmpty(str))
{
string[] strlist = str.Split(new string[] { ";", "&", "#" }, StringSplitOptions.RemoveEmptyEntries);
if (strlist.Length == 1)
return str;
for (int i = 0; i < strlist.Length; i++)
{
//将unicode字符转为10进制整数,然后转为char中文字符
int result;
if(
int.TryParse(strlist[i],out result ))
outStr += (char)result;
else
outStr += strlist[i];
}
}
return outStr;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SFTech.GMusic
{
public class StringCoder
{
public static string Encode(String str){
string outStr = "";
var temp = str;
int index = temp.IndexOf("銆?");
if (index >= 0)
{
temp = temp.Substring(2);
index = temp.IndexOf("銆?");
if (index >= 0)
temp = temp.Substring(0, index);
}
str = temp;
if (!string.IsNullOrEmpty(str))
{
string[] strlist = str.Split(new string[] { ";", "&", "#" }, StringSplitOptions.RemoveEmptyEntries);
if (strlist.Length == 1)
return str;
for (int i = 0; i < strlist.Length; i++)
{
//将unicode字符转为10进制整数,然后转为char中文字符
int result;
if(
int.TryParse(strlist[i],out result ))
outStr += (char)result;
else
outStr += strlist[i];
}
}
return outStr;
}
}
}
最后是窗体的设计源码
Code
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="GMusic.Window1"
Title="痞子音乐" Height="553" Width="717" Loaded="Window_Loaded_1">
<!-- Style that will be applied to all buttons -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="210*" />
<ColumnDefinition Width="335*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Data Template (applied to each bound task item in the task collection) -->
<Grid.RowDefinitions>
<RowDefinition Height="53*"></RowDefinition>
<RowDefinition Height="341*"/>
<RowDefinition Height="121*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.Resources>
<DataTemplate x:Key="myTaskTemplate">
<Border Name="border" BorderBrush="DarkSlateBlue" BorderThickness="2"
CornerRadius="2" Padding="5" Margin="5" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="歌手名称:"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Name}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Padding="0,0,5,0" Text="歌手连接:"/>
<TextBlock Grid.Row="1" Grid.Column="1">
<Hyperlink NavigateUri="{Binding Path=Herf}">点击</Hyperlink>
</TextBlock>
<!--<TextBlock Grid.Row="2" Grid.Column="0" Padding="0,0,5,0" Text="Priority:"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>-->
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="AlbumDataTemplate">
<Border Name="border" BorderBrush="DarkSlateBlue" BorderThickness="2"
CornerRadius="2" Padding="5" Margin="5" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="专辑:"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Name}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Padding="0,0,5,0" Text="地址:"/>
<TextBlock Grid.Row="1" Grid.Column="1">
<Hyperlink NavigateUri="{Binding Path=Herf}">点击</Hyperlink>
</TextBlock>
<!--<TextBlock Grid.Row="2" Grid.Column="0" Padding="0,0,5,0" Text="Priority:"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>-->
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="SongDataTemplate">
<Border Name="border" Background="Azure" BorderBrush="DarkSlateBlue" BorderThickness="2"
CornerRadius="2" Padding="5" Margin="5" Height="35" >
<Grid HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width=" 50*" />
<ColumnDefinition Width=" 40" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="{Binding Path=Name}" HorizontalAlignment="Stretch" />
<!--ProgressBar Grid.Row="0" Grid.Column="1" Height="10" Value="0" HorizontalAlignment="Stretch" MinWidth="200" /-->
<Button Grid.Column=" 1" Grid.Row="0" HorizontalAlignment="Stretch" Tag="{Binding}" Click="Button_Click" >下载</Button>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="DownTemplate">
<Border Name="border" Background="Azure" BorderBrush="DarkSlateBlue" BorderThickness="2"
CornerRadius="2" Padding="5" Margin="5" Height="35" >
<Grid HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width=" 150" />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="{Binding Path=Name}" />
<ProgressBar Grid.Row=" 0" Grid.Column=" 1" Value="{Binding Path=DownLoadRate,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></ProgressBar>
<TextBlock Grid.Row=" 0" Grid.Column=" 2" Name="lbState"/>
<!--ProgressBar Grid.Row="0" Grid.Column="1" Height="10" Value="0" HorizontalAlignment="Stretch" MinWidth="200" /-->
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="GetUrl">
<Setter TargetName="lbState" Property="Text" Value="获取下载地址"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="DownLoading">
<Setter TargetName="lbState" Property="Text" Value="正在下载"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="Suspand">
<Setter TargetName="lbState" Property="Text" Value="暂停"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="Success">
<Setter TargetName="lbState" Property="Text" Value="下载完成"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="Queue">
<Setter TargetName="lbState" Property="Text" Value="排队中"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="Failed">
<Setter TargetName="lbState" Property="Text" Value="失败"></Setter>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Grid.Resources>
<ListBox
ItemTemplate="{StaticResource myTaskTemplate}" Grid.Row="1" Grid.RowSpan=" 2" Grid.Column=" 0" Name="ArtistList" HorizontalContentAlignment="Stretch" MouseDoubleClick="ArtistList_MouseDoubleClick">
</ListBox>
<!-- Data template is specified by the ItemTemplate attribute -->
<Grid Grid.Column="0" Grid.Row=" 0">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="58*"></ColumnDefinition>
<ColumnDefinition Width="92*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0">地区:</Label>
<Label Grid.Column="0" Grid.Row="1">类别:</Label>
<ComboBox Name="RegType" Grid.Column=" 1" Margin="0,1,0,1" Grid.Row=" 0"></ComboBox>
<ComboBox Name="ArtType" Grid.Column=" 1" Margin="0,1,0,1" Grid.Row=" 1"></ComboBox>
</Grid>
<Button Grid.Column="1" Margin="29,14,0,6" Name="button1" Click="button1_Click" HorizontalAlignment="Left" Width="75">获歌手列表</Button>
<ListBox Name="AlumList" Width="Auto" ItemTemplate="{StaticResource AlbumDataTemplate}" Grid.Column="1" Grid.Row="1" HorizontalContentAlignment="Stretch" MouseDoubleClick="AlumList_MouseDoubleClick" />
<ListBox Name="SongList" Width=" Auto" ItemTemplate="{StaticResource SongDataTemplate}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Stretch" />
<ListBox Name="DonwLoadList" Width=" Auto" ItemTemplate="{StaticResource DownTemplate}" Grid.Column=" 1" Grid.Row=" 2" Grid.ColumnSpan=" 2" HorizontalContentAlignment="Stretch" ></ListBox>
<Grid Grid.Column="2" Grid.RowSpan="1" Grid.Row=" 0" Name="grid1">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row=" 0" Grid.Column=" 0" Name="label1">保存路径</Label>
<TextBox Grid.Row=" 0" Grid.Column=" 1" Name="PathBox"></TextBox>
<Button Grid.Row=" 0" Grid.Column=" 2" Click="Button_Click_1" Name="BtnFile">浏览</Button>
</Grid>
</Grid>
</Window>
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="GMusic.Window1"
Title="痞子音乐" Height="553" Width="717" Loaded="Window_Loaded_1">
<!-- Style that will be applied to all buttons -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="210*" />
<ColumnDefinition Width="335*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Data Template (applied to each bound task item in the task collection) -->
<Grid.RowDefinitions>
<RowDefinition Height="53*"></RowDefinition>
<RowDefinition Height="341*"/>
<RowDefinition Height="121*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.Resources>
<DataTemplate x:Key="myTaskTemplate">
<Border Name="border" BorderBrush="DarkSlateBlue" BorderThickness="2"
CornerRadius="2" Padding="5" Margin="5" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="歌手名称:"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Name}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Padding="0,0,5,0" Text="歌手连接:"/>
<TextBlock Grid.Row="1" Grid.Column="1">
<Hyperlink NavigateUri="{Binding Path=Herf}">点击</Hyperlink>
</TextBlock>
<!--<TextBlock Grid.Row="2" Grid.Column="0" Padding="0,0,5,0" Text="Priority:"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>-->
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="AlbumDataTemplate">
<Border Name="border" BorderBrush="DarkSlateBlue" BorderThickness="2"
CornerRadius="2" Padding="5" Margin="5" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="专辑:"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Name}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Padding="0,0,5,0" Text="地址:"/>
<TextBlock Grid.Row="1" Grid.Column="1">
<Hyperlink NavigateUri="{Binding Path=Herf}">点击</Hyperlink>
</TextBlock>
<!--<TextBlock Grid.Row="2" Grid.Column="0" Padding="0,0,5,0" Text="Priority:"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>-->
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="SongDataTemplate">
<Border Name="border" Background="Azure" BorderBrush="DarkSlateBlue" BorderThickness="2"
CornerRadius="2" Padding="5" Margin="5" Height="35" >
<Grid HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width=" 50*" />
<ColumnDefinition Width=" 40" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="{Binding Path=Name}" HorizontalAlignment="Stretch" />
<!--ProgressBar Grid.Row="0" Grid.Column="1" Height="10" Value="0" HorizontalAlignment="Stretch" MinWidth="200" /-->
<Button Grid.Column=" 1" Grid.Row="0" HorizontalAlignment="Stretch" Tag="{Binding}" Click="Button_Click" >下载</Button>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="DownTemplate">
<Border Name="border" Background="Azure" BorderBrush="DarkSlateBlue" BorderThickness="2"
CornerRadius="2" Padding="5" Margin="5" Height="35" >
<Grid HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width=" 150" />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="{Binding Path=Name}" />
<ProgressBar Grid.Row=" 0" Grid.Column=" 1" Value="{Binding Path=DownLoadRate,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></ProgressBar>
<TextBlock Grid.Row=" 0" Grid.Column=" 2" Name="lbState"/>
<!--ProgressBar Grid.Row="0" Grid.Column="1" Height="10" Value="0" HorizontalAlignment="Stretch" MinWidth="200" /-->
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="GetUrl">
<Setter TargetName="lbState" Property="Text" Value="获取下载地址"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="DownLoading">
<Setter TargetName="lbState" Property="Text" Value="正在下载"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="Suspand">
<Setter TargetName="lbState" Property="Text" Value="暂停"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="Success">
<Setter TargetName="lbState" Property="Text" Value="下载完成"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="Queue">
<Setter TargetName="lbState" Property="Text" Value="排队中"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=DownloadState}" Value="Failed">
<Setter TargetName="lbState" Property="Text" Value="失败"></Setter>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Grid.Resources>
<ListBox
ItemTemplate="{StaticResource myTaskTemplate}" Grid.Row="1" Grid.RowSpan=" 2" Grid.Column=" 0" Name="ArtistList" HorizontalContentAlignment="Stretch" MouseDoubleClick="ArtistList_MouseDoubleClick">
</ListBox>
<!-- Data template is specified by the ItemTemplate attribute -->
<Grid Grid.Column="0" Grid.Row=" 0">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="58*"></ColumnDefinition>
<ColumnDefinition Width="92*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0">地区:</Label>
<Label Grid.Column="0" Grid.Row="1">类别:</Label>
<ComboBox Name="RegType" Grid.Column=" 1" Margin="0,1,0,1" Grid.Row=" 0"></ComboBox>
<ComboBox Name="ArtType" Grid.Column=" 1" Margin="0,1,0,1" Grid.Row=" 1"></ComboBox>
</Grid>
<Button Grid.Column="1" Margin="29,14,0,6" Name="button1" Click="button1_Click" HorizontalAlignment="Left" Width="75">获歌手列表</Button>
<ListBox Name="AlumList" Width="Auto" ItemTemplate="{StaticResource AlbumDataTemplate}" Grid.Column="1" Grid.Row="1" HorizontalContentAlignment="Stretch" MouseDoubleClick="AlumList_MouseDoubleClick" />
<ListBox Name="SongList" Width=" Auto" ItemTemplate="{StaticResource SongDataTemplate}" Grid.Column="2" Grid.Row="1" HorizontalContentAlignment="Stretch" />
<ListBox Name="DonwLoadList" Width=" Auto" ItemTemplate="{StaticResource DownTemplate}" Grid.Column=" 1" Grid.Row=" 2" Grid.ColumnSpan=" 2" HorizontalContentAlignment="Stretch" ></ListBox>
<Grid Grid.Column="2" Grid.RowSpan="1" Grid.Row=" 0" Name="grid1">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row=" 0" Grid.Column=" 0" Name="label1">保存路径</Label>
<TextBox Grid.Row=" 0" Grid.Column=" 1" Name="PathBox"></TextBox>
<Button Grid.Row=" 0" Grid.Column=" 2" Click="Button_Click_1" Name="BtnFile">浏览</Button>
</Grid>
</Grid>
</Window>
界面代码
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace GMusic
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
this.RegType.ItemsSource = SFTech.GMusic.Region.Regions;
this.ArtType.ItemsSource = SFTech.GMusic.ArtistClass.ArtistClasses;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
this.ArtistList.ItemsSource = SFTech.GMusic.Artist.GetArtist(
this.RegType.SelectedItem as SFTech.GMusic.Region,
this.ArtType.SelectedItem as SFTech.GMusic.ArtistClass);
}
private void ArtistList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (this.ArtistList.SelectedItem != null)
{
var Artist = this.ArtistList.SelectedItem as SFTech.GMusic.Artist;
if(Artist !=null)
this.AlumList.ItemsSource = Artist.Albums;
}
}
private void AlumList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (this.AlumList.SelectedItem != null)
{
var album = this.AlumList.SelectedItem as SFTech.GMusic.Album;
if (album != null)
this.SongList.ItemsSource = album.Songs;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Button i = sender as Button;
if (i == null)
MessageBox.Show(sender.GetType().ToString());
else
{
var s = i.Tag as SFTech.GMusic.Song;
SFTech.GMusic.SongDownloader dowloader = new SFTech.GMusic.SongDownloader(s);
this.DonwLoadList.Items.Add(dowloader);
string p = this.PathBox.Text;
if (p.EndsWith("\\") == false)
p += "\\";
try
{
dowloader.BeginDownLoadAs(p);
}
catch (Exception ex)
{
}
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var i = new System.Windows.Forms.FolderBrowserDialog();
if (i.ShowDialog() == System.Windows.Forms.DialogResult.OK )
{
this.PathBox.Text = i.SelectedPath;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace GMusic
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
this.RegType.ItemsSource = SFTech.GMusic.Region.Regions;
this.ArtType.ItemsSource = SFTech.GMusic.ArtistClass.ArtistClasses;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
this.ArtistList.ItemsSource = SFTech.GMusic.Artist.GetArtist(
this.RegType.SelectedItem as SFTech.GMusic.Region,
this.ArtType.SelectedItem as SFTech.GMusic.ArtistClass);
}
private void ArtistList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (this.ArtistList.SelectedItem != null)
{
var Artist = this.ArtistList.SelectedItem as SFTech.GMusic.Artist;
if(Artist !=null)
this.AlumList.ItemsSource = Artist.Albums;
}
}
private void AlumList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (this.AlumList.SelectedItem != null)
{
var album = this.AlumList.SelectedItem as SFTech.GMusic.Album;
if (album != null)
this.SongList.ItemsSource = album.Songs;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Button i = sender as Button;
if (i == null)
MessageBox.Show(sender.GetType().ToString());
else
{
var s = i.Tag as SFTech.GMusic.Song;
SFTech.GMusic.SongDownloader dowloader = new SFTech.GMusic.SongDownloader(s);
this.DonwLoadList.Items.Add(dowloader);
string p = this.PathBox.Text;
if (p.EndsWith("\\") == false)
p += "\\";
try
{
dowloader.BeginDownLoadAs(p);
}
catch (Exception ex)
{
}
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var i = new System.Windows.Forms.FolderBrowserDialog();
if (i.ShowDialog() == System.Windows.Forms.DialogResult.OK )
{
this.PathBox.Text = i.SelectedPath;
}
}
}
}