来源:NanCheung`s Blog
链接:https://blog.nancheung.com
/archives/8354688
商业转载请联系作者获得授权,非商业转载请注明出处。
引
偶尔在微博上看到,要是歌单里谁的歌超过30首,那肯定是真爱吧。
我看了连忙打开网易云音乐我的歌单,结果1000多首歌。。。这让我自己数得数到猴年马月呀.
于是萌生出了写一段小爬虫来统计的想法。
刚开始想直接解析网页元素,后发现很麻烦,很多信息不能一次抓取到,于是找到网页请求的接口,结果接口有加密参数,看了一下js加密参数的方法,头都晕了。没法子,我在网上查资料,终于找到一个api(原文:http://moonlib.com/606.html ):
http://music.163.com/api/playlist/detail?id=歌单ID
比如我喜欢的歌单:https://music.163.com/#/playlist?id=40882617那么歌单id就是 40882617 。
组合一下就知道了我们需要请求的接口地址:http://music.163.com/api/playlist/detail?id=40882617
我们可以先用浏览器或者postman等工具得到接口返回的json,利用Gson等工具生成对应的Bean。
我生成一个PlayListVo 来接收歌单详情信息,此处不详述。
等生成Bean之后,现在我们就需要写一段代码,来请求这个接口了。
由于这个接口有请求头的验证,我们需要添加一些信息
以下代码抛砖引玉:
@Test
public void test1() {
//定义请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "*/*");
headers.set("Accept-Language", "zh-CN,zh;q=0.8");
headers.set("Host", "music.163.com");
headers.set("Referer", "http://music.163.com/");
headers.set("cookies", "appver=2.0.2");
headers.setConnection("keep-alive");
headers.set("User-Agent",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36");
// 执行HTTP请求
String post = new RestTemplate().exchange("http://music.163.com/api/playlist/detail?id=40882617",
HttpMethod.POST, new HttpEntity<>(headers, headers), String.class).getBody();
System.out.println(post + "\n\n\n\n\n\n\n\n\n");
PlayListVo playListVo = JSON.parseObject(post, PlayListVo.class);
//统计每位歌手的歌曲数量
Map<String, Integer> map = new TreeMap<>();
Objects.requireNonNull(playListVo).getResult().getTracks()
.forEach(tracksBean -> tracksBean.getAlbum().getArtists().forEach(artistsBean -> {
String name = artistsBean.getName();
map.put(name, map.get(name) == null ? 1 : map.get(name) + 1);
}));
List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
list.stream().sorted(Comparator.comparing(Map.Entry::getValue)).forEach(System.out::print);
}
代码只提供思路吧,如需详细源码,请戳:https://github.com/nancheung97/music163reptile