import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import object.Album;
import object.Dicover;
import object.JsonObj.MusicJsonObj;
import object.Work;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* date : 2020/2/13 22:27
* author : 老逼的电脑
*/
public class MainApp {
public static void main(String[] args) throws IOException {
MainApp mainApp = new MainApp();
//获取所有大分类
List<String> strings = mainApp.getCates();
System.out.println("所有大分类" + strings.size());
//获取所有大分类下的歌手分类
List<String> discoverCatePaths = mainApp.getDiscoverCatePaths(strings);
//获取歌手分类下的歌手链接
List<String> dicoverPath = mainApp.getDicoverPath(discoverCatePaths);
System.out.println("总共有" + dicoverPath.size() + "个歌手");
//获取歌手信息
for (String s : dicoverPath) {
Dicover dicoverInfo = mainApp.getDicoverInfo(s);
System.out.println("作者:" + dicoverInfo.getName());
System.out.println("专辑数量:" + dicoverInfo.getAlbumList().size());
System.out.println("热门单曲:" + dicoverInfo.getHotWorkList());
}
}
private String index = "https://music.163.com";
private String path = "/discover/artist";
private final String musicPath = "http://music.163.com/song/media/outer/url?id={id}.mp3";
/**
* 获取所有分类信息
*
* @return
* @throws IOException
*/
public List<String> getCates() throws IOException {
Elements doc = Jsoup.connect(index + path).get().getElementsByClass("cat-flag");
return doc.stream()
.filter(element -> element.attr("href")
.startsWith("/discover/artist/cat?"))
.map(element -> index + element.attr("href"))
.collect(Collectors.toList());
}
/**
* 获取歌手分类下的链接
*/
public List<String> getDiscoverCatePaths(List<String> cates) throws IOException {
List<String> strings = new ArrayList<>();
for (String cate : cates) {
Document document = Jsoup.connect(cate).get();
Element element = document.getElementById("initial-selector");
Elements a = element.getElementsByTag("a");
List<String> href = a.stream()
.map(element1 -> index + (element1.attr("href")
.replace("&", "&")))
.filter(s -> !s.endsWith("=-1"))
.collect(Collectors.toList());
strings.addAll(href);
}
return strings;
}
/**
* 获取歌手的链接
*/
public List<String> getDicoverPath(List<String> dicoverCatePaths) throws IOException {
List<String> dicoverPaths = new ArrayList<>();
for (String dicoverCatePath : dicoverCatePaths) {
Element element = Jsoup.connect(dicoverCatePath).get().getElementById("m-artist-box");
Elements a = element.getElementsByTag("a");
List<String> href = a.stream().map(element1 -> index + element1.attr("href")).collect(Collectors.toList());
//TODO 需要对链接进行去重复和排查
dicoverPaths.addAll(href);
}
return dicoverPaths.stream().filter(s -> !s.contains(" ")).filter(s -> !s.contains("user")).collect(Collectors.toList());
}
/**
* 获取歌手信息
*/
public Dicover getDicoverInfo(String dicoverPath) throws IOException {
Document document = Jsoup.connect(dicoverPath).get();
//获取作者名字
String dicoverName = document.getElementById("artist-name").text();
//获取作者头像
Elements select1 = document.getElementsByTag("img");
String avatar = select1.get(0).attr("src");
//获取热门单曲
String json = document.getElementById("song-list-pre-data").text();
List<MusicJsonObj> musicJsonObjs = parseMucsicList(json);
List<String> hotmusic = musicJsonObjs.stream().map(musicJsonObj -> musicJsonObj.getName()).collect(Collectors.toList());
//获取作者介绍
Document doc = Jsoup.connect(dicoverPath.replace("artist", "artist/desc")).get();
String introduction = doc.getElementsByClass("n-artdesc").html();
Dicover dicover = new Dicover(dicoverName, avatar, null, introduction, hotmusic);
//获取作者专辑列表
String albumPath = document.getElementById("m_tabs").child(1).select("a").attr("href");
List<Album> albums = getAlbums(index + albumPath);
dicover.setAlbumList(albums);
return dicover;
}
/**
* 解析 json
*
* @return List<MusicJsonObj>
*/
private List<MusicJsonObj> parseMucsicList(String json) {
Gson gson = new Gson();
List<MusicJsonObj> hotMusicJsons = gson.fromJson(json, new TypeToken<ArrayList<MusicJsonObj>>() {
}.getType());
return hotMusicJsons;
}
private String parseMusicTime(int time) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss");
return simpleDateFormat.format(new Date(time));
}
public List<Album> getAlbums(String album) throws IOException {
List<Album> albumList = new ArrayList<>();
Document albumDoc = Jsoup.connect(album).get();
Element maxPage;
do {
Elements pages = albumDoc.getElementsByClass("u-page").select("a");
Elements liList;
try {
Element elementById = albumDoc.getElementById("m-song-module");
liList = elementById.getElementsByTag("li");
} catch (NullPointerException e) {
//如果没有专辑 跳出循环
break;
}
//获取所有专辑
for (Element element : liList) {
String albumName = element.child(0).attr("title");
String date = element.child(2).child(0).text();
//获取专辑下的歌曲
String albumPath = element.child(0).child(1).attr("href");
Document albumDetail = Jsoup.connect(index + albumPath).get();
List<MusicJsonObj> musicJsonObjs1 = parseMucsicList(albumDetail.getElementById("song-list-pre-data").text());
List<Work> workList = musicJsonObjs1.stream().map(musicJsonObj ->
new Work(musicJsonObj.getName(),
parseMusicTime(musicJsonObj.getDuration()),
musicPath.replace("{id}", musicJsonObj.getPrivilege().getId() + ""))
).collect(Collectors.toList());
albumList.add(new Album(albumName, date, workList));
}
//判定是不是最后一页 是的话跳出循环
try {
maxPage = pages.get(pages.size() - 1);
} catch (ArrayIndexOutOfBoundsException | NullPointerException n) {
break;
}
if (!maxPage.attr("href").equals("javascript:void(0)")) {
albumDoc = Jsoup.connect(index + maxPage.attr("href")).get();
} else {
break;
}
} while (!maxPage.attr("href").equals("javascript:void(0)"));
return albumList;
}
}
最近下载更多
shonga LV1
11月24日
wahahaCode LV1
2023年1月5日
好的好的 LV9
2022年7月7日
crosa_Don LV18
2022年6月14日
dhvdsgfggfjhfggfyu LV4
2022年1月10日
whmr_soft LV10
2021年9月27日
李疾风 LV1
2021年7月7日
许元宵 LV1
2021年5月17日
3090362054aaa LV1
2021年2月1日
1232136456 LV1
2020年12月7日
最近浏览更多
shonga LV1
11月24日
微信网友_7044194812350464 LV8
9月8日
2946489117 LV1
6月11日
TY0165 LV20
2024年6月24日
微信网友_7005760998215680 LV6
2024年6月4日
panqiuhong LV7
2024年2月24日
雨中纸鹤 LV1
2023年12月6日
内心向阳 LV4
2023年11月8日
tyyeng LV18
2023年10月10日
科技家 LV2
2023年3月15日

