本文方法及代码仅供学习,仅供学习。

案例:

  下载酷狗TOP500歌曲,代码用到的代码库包含:Jsoup、HttpClient、fastJson等。

正文:

  1、分析是否可以获取到TOP500歌单

打开酷狗首页,查看TOP500,发现存在分页,每页显示22条歌曲,

发现酷狗的链接如下:

  1. https://www.kugou.com/yy/rank/home/1-8888.html?from=homepage

通过更改链接中的1可以进行分页,所以我们可以通过更改链接地址获取其余的歌曲。

2、分析找到正真的mp3下载地址

点一个歌曲进入播放页面,使用谷歌浏览器的控制台的Elements,搜一下mp3,很轻松就定位到了MP3的位置。

但是使用java访问的时候爬取的html里却没有该mp3的文件地址,那么这肯定是在该页面的位置使用了js来加载mp3,那么刷新下网页,看网页加载了哪些东西,加载的东西有点多,着重看一下js、php的请求,主要是看里面有没有mp3的地址。

最终在列表中找到:

  1. https://wwwapi.kugou.com/yy/index.php?r=play/getdata&callback=jQuery191044492686523157987_1559446927765&hash=458E9B9F362277AC37E9EEF1CB80B535&album_id=18712576&dfid=1ZxQbe0MiP8J09j5tR0Np9IA&mid=9393340fecff864a4d6c4e95099b2be1&platid=4&_=1559446927766

这个请求结果中发现了mp3的完整地址:

那这个js是怎么判断是哪首歌的呢,那么只可能是hash这个参数来决定歌曲的,然后到播放页面里找到这个hash的位置,是在下面的js里:

  1. var dataFromSmarty = [{"hash":"667939C6E784265D541DEEE65AE4F2F8","timelength":"237051","audio_name":"\u767d\u5c0f\u767d - \u6700\u7f8e\u5a5a\u793c","author_name":"\u767d\u5c0f\u767d","song_name":"\u6700\u7f8e\u5a5a\u793c","album_id":0}],//当前页面歌曲信息
  2. playType = "search_single";//当前播放
  3. </script>

在去java爬取该网页,查看能否爬到这个hash,果然,爬取的html里有这段js,到现在mp3的地址也找到了,歌单也找到了,那么下一步就用程序实现就可以了。

3、代码实现

  1. SpiderKugou.java
  1. package com.billy.test;
  2.  
  3. import com.alibaba.fastjson.JSON;
  4. import com.alibaba.fastjson.JSONObject;
  5. import org.jsoup.nodes.Document;
  6. import org.jsoup.nodes.Element;
  7. import org.jsoup.select.Elements;
  8.  
  9. import java.io.IOException;
  10. import java.util.regex.Matcher;
  11. import java.util.regex.Pattern;
  12.  
  13. /**
  14. * 爬取并下载酷狗的歌曲
  15. */
  16. public class SpiderKugou {
  17.  
  18. private static String filePath;
  19.  
  20. //酷狗地址
  21. private static String LINK;
  22.  
  23. //mp3地址
  24. private static String mp3;
  25.  
  26. static {
  27. filePath = "F:/music/";
  28. LINK = "https://www.kugou.com/yy/rank/home/PAGE-8888.html?from=rank";
  29. mp3 = "https://wwwapi.kugou.com/yy/index.php?r=play/getdata&callback=jQuery19103632090130122796_1558800325111&"
  30. + "hash=HASH&_=TIME";
  31. }
  32.  
  33. public static void main(String[] args) throws Exception {
  34.  
  35. for(int i = 5 ; i < 23 ; i++){
  36.  
  37. String url = LINK.replace("PAGE", i + "");
  38. downSong(url);
  39. }
  40. }
  41.  
  42. /**
  43. * 下载歌曲
  44. * @param url
  45. * @throws Exception
  46. */
  47. private static void downSong(String url) throws Exception{
  48.  
  49. HttpGetConnect connect = new HttpGetConnect();
  50. String content = connect.connect(url, "utf-8");
  51. HtmlManage html = new HtmlManage();
  52. Document doc = html.manage(content);
  53. Element ele = doc.getElementsByClass("pc_temp_songlist").get(0);
  54. Elements elements = ele.getElementsByTag("li");
  55. for(int i = 0 ; i < elements.size() ; i++){
  56.  
  57. Element item = elements.get(i);
  58. String title = item.attr("title").trim();
  59. String link = item.getElementsByTag("a").first().attr("href");
  60. downLoad(link,title);
  61. Thread.sleep(1000);
  62. }
  63. }
  64.  
  65. /**
  66. * 下载
  67. * @param url
  68. * @param name
  69. * @throws IOException
  70. */
  71. private static void downLoad(String url,String name) throws IOException{
  72.  
  73. String hash = "";
  74. HttpGetConnect connect = new HttpGetConnect();
  75. String content = connect.connect(url, "utf-8");
  76.  
  77. String regEx = "\"hash\":\"[0-9A-Z]+\"";
  78. // 编译正则表达式
  79. Pattern pattern = Pattern.compile(regEx);
  80. Matcher matcher = pattern.matcher(content);
  81. if (matcher.find()) {
  82. hash = matcher.group();
  83. hash = hash.replace("\"hash\":\"", "");
  84. hash = hash.replace("\"", "");
  85. }
  86.  
  87. String item = mp3.replace("HASH", hash);
  88. item = item.replace("TIME", System.currentTimeMillis() + "");
  89. System.out.println("item:" + item);
  90.  
  91. String mp = connect.connect(item, "utf-8");
  92. mp = mp.substring(mp.indexOf("(") + 1, mp.length() - 3);
  93.  
  94. JSONObject json = JSON.parseObject(mp);
  95. if(Integer.parseInt(json.get("status") + "") != 0){
  96.  
  97. String playUrl = json.getJSONObject("data").getString("play_url");
  98. FileDownload down = new FileDownload();
  99. down.download(playUrl, filePath + name + ".mp3");
  100. }
  101.  
  102. }
  103.  
  104. }
  1. HttpGetConnect.java
  1. package com.billy.test;
  2.  
  3. import org.apache.commons.logging.Log;
  4. import org.apache.commons.logging.LogFactory;
  5. import org.apache.http.HttpEntity;
  6. import org.apache.http.client.config.RequestConfig;
  7. import org.apache.http.client.methods.CloseableHttpResponse;
  8. import org.apache.http.client.methods.HttpGet;
  9. import org.apache.http.impl.client.CloseableHttpClient;
  10. import org.apache.http.impl.client.HttpClients;
  11. import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
  12.  
  13. import java.io.BufferedReader;
  14. import java.io.IOException;
  15. import java.io.InputStream;
  16. import java.io.InputStreamReader;
  17.  
  18. /**
  19. * httpclient 工具类
  20. */
  21. public class HttpGetConnect {
  22.  
  23. /**
  24. * 获取html内容
  25. * @param url
  26. * @param charsetName UTF-8、GB2312
  27. * @return
  28. * @throws IOException
  29. */
  30. public static String connect(String url,String charsetName) throws IOException{
  31. BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager();
  32.  
  33. CloseableHttpClient httpclient = HttpClients.custom()
  34. .setConnectionManager(connManager)
  35. .build();
  36. String content = "";
  37.  
  38. try{
  39. HttpGet httpget = new HttpGet(url);
  40.  
  41. RequestConfig requestConfig = RequestConfig.custom()
  42. .setSocketTimeout(5000)
  43. .setConnectTimeout(50000)
  44. .setConnectionRequestTimeout(50000)
  45. .build();
  46. httpget.setConfig(requestConfig);
  47. httpget.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
  48. httpget.setHeader("Accept-Encoding", "gzip,deflate,sdch");
  49. httpget.setHeader("Accept-Language", "zh-CN,zh;q=0.8");
  50. httpget.setHeader("Connection", "keep-alive");
  51. httpget.setHeader("Upgrade-Insecure-Requests", "1");
  52. httpget.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36");
  53. httpget.setHeader("cache-control", "max-age=0");
  54.  
  55. httpget.setHeader("Referer","https://www.kugou.com/song/");
  56.  
  57. //设置cookie
  58. httpget.setHeader("Cookie", "kg_mid=9393340fecff864a4d6c4e95099b2be1;");
  59.  
  60. CloseableHttpResponse response = httpclient.execute(httpget);
  61.  
  62. int status = response.getStatusLine().getStatusCode();
  63. if (status >= 200 && status < 300) {
  64.  
  65. HttpEntity entity = response.getEntity();
  66. InputStream instream = entity.getContent();
  67. BufferedReader br = new BufferedReader(new InputStreamReader(instream,charsetName));
  68. StringBuffer sbf = new StringBuffer();
  69. String line = null;
  70. while ((line = br.readLine()) != null){
  71. sbf.append(line + "\n");
  72. }
  73.  
  74. br.close();
  75. content = sbf.toString();
  76. } else {
  77. content = "";
  78. }
  79.  
  80. }catch(Exception e){
  81. e.printStackTrace();
  82. }finally{
  83. httpclient.close();
  84. }
  85. log.info("content is " + content);
  86. return content;
  87. }
  88.  
  89. private static Log log = LogFactory.getLog(HttpGetConnect.class);
  90. }
  1. HtmlManage.java
  1. package com.billy.test;
  2.  
  3. import org.apache.commons.logging.Log;
  4. import org.apache.commons.logging.LogFactory;
  5. import org.jsoup.Jsoup;
  6. import org.jsoup.nodes.Document;
  7. import org.jsoup.select.Elements;
  8.  
  9. import java.io.IOException;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12.  
  13. /**
  14. * html manage 工具类
  15. */
  16. public class HtmlManage {
  17.  
  18. public Document manage(String html) {
  19. Document doc = Jsoup.parse(html);
  20. return doc;
  21. }
  22.  
  23. public Document manageDirect(String url) throws IOException {
  24. Document doc = Jsoup.connect(url).get();
  25. return doc;
  26. }
  27.  
  28. public List<String> manageHtmlTag(Document doc, String tag) {
  29. List<String> list = new ArrayList<String>();
  30.  
  31. Elements elements = doc.getElementsByTag(tag);
  32. for (int i = 0; i < elements.size(); i++) {
  33. String str = elements.get(i).html();
  34. list.add(str);
  35. }
  36. return list;
  37. }
  38.  
  39. public List<String> manageHtmlClass(Document doc, String clas) {
  40. List<String> list = new ArrayList<String>();
  41.  
  42. Elements elements = doc.getElementsByClass(clas);
  43. for (int i = 0; i < elements.size(); i++) {
  44. String str = elements.get(i).html();
  45. list.add(str);
  46. }
  47. return list;
  48. }
  49.  
  50. public List<String> manageHtmlKey(Document doc, String key, String value) {
  51. List<String> list = new ArrayList<String>();
  52.  
  53. Elements elements = doc.getElementsByAttributeValue(key, value);
  54. for (int i = 0; i < elements.size(); i++) {
  55. String str = elements.get(i).html();
  56. list.add(str);
  57. }
  58. return list;
  59. }
  60.  
  61. private static Log log = LogFactory.getLog(HtmlManage.class);
  62. }
  1. FileDownload.java
  1. package com.billy.test;
  2.  
  3. import java.io.BufferedInputStream;
  4. import java.io.BufferedOutputStream;
  5. import java.io.File;
  6. import java.io.FileOutputStream;
  7.  
  8. import org.apache.commons.logging.Log;
  9. import org.apache.commons.logging.LogFactory;
  10. import org.apache.http.client.config.RequestConfig;
  11. import org.apache.http.client.methods.CloseableHttpResponse;
  12. import org.apache.http.client.methods.HttpGet;
  13. import org.apache.http.impl.client.CloseableHttpClient;
  14. import org.apache.http.impl.client.HttpClients;
  15.  
  16. /**
  17. * 文件下载工具类
  18. */
  19. public class FileDownload {
  20.  
  21. /**
  22. * 文件下载
  23. *
  24. * @param url 链接地址
  25. * @param path 要保存的路径及文件名
  26. * @return
  27. */
  28. public static boolean download(String url, String path) {
  29.  
  30. boolean flag = false;
  31.  
  32. CloseableHttpClient httpclient = HttpClients.createDefault();
  33. RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(2000)
  34. .setConnectTimeout(2000).build();
  35.  
  36. HttpGet get = new HttpGet(url);
  37. get.setConfig(requestConfig);
  38.  
  39. BufferedInputStream in = null;
  40. BufferedOutputStream out = null;
  41. try {
  42. for (int i = 0; i < 3; i++) {
  43. CloseableHttpResponse result = httpclient.execute(get);
  44. System.out.println(result.getStatusLine());
  45. if (result.getStatusLine().getStatusCode() == 200) {
  46. in = new BufferedInputStream(result.getEntity().getContent());
  47. File file = new File(path);
  48. out = new BufferedOutputStream(new FileOutputStream(file));
  49. byte[] buffer = new byte[1024];
  50. int len = -1;
  51. while ((len = in.read(buffer, 0, 1024)) > -1) {
  52. out.write(buffer, 0, len);
  53. }
  54. flag = true;
  55. break;
  56. } else if (result.getStatusLine().getStatusCode() == 500) {
  57. continue;
  58. }
  59. }
  60.  
  61. } catch (Exception e) {
  62. e.printStackTrace();
  63. flag = false;
  64. } finally {
  65. get.releaseConnection();
  66. try {
  67. if (in != null) {
  68. in.close();
  69. }
  70. if (out != null) {
  71. out.close();
  72. }
  73. } catch (Exception e) {
  74. e.printStackTrace();
  75. flag = false;
  76. }
  77. }
  78. return flag;
  79. }
  80.  
  81. private static Log log = LogFactory.getLog(FileDownload.class);
  82. }
  1.  
  1.  
  1.  
  1.  

Java爬取并下载酷狗音乐的更多相关文章

  1. java爬取并下载酷狗TOP500歌曲

    是这样的,之前买车送的垃圾记录仪不能用了,这两天狠心买了好点的记录仪,带导航.音乐.蓝牙.4G等功能,寻思,既然有这些功能就利用起来,用4G听歌有点奢侈,就准备去酷狗下点歌听,居然都是需要办会员才能下 ...

  2. Python 应用爬虫下载酷狗音乐

    应用爬虫下载酷狗音乐 首先我们需要进入到这个界面 想要爬取这些歌曲链接,然而这个是一个假的网站,虽然单机右键进行检查能看到这些歌曲的链接,可进行爬取时,却爬取不到这些信息. 这个时候我们就应该换一种思 ...

  3. Python爬虫下载酷狗音乐

    目录 1.Python下载酷狗音乐 1.1.前期准备 1.2.分析 1.2.1.第一步 1.2.2.第二步 1.2.3.第三步 1.2.4.第四步 1.3.代码实现 1.4.运行结果 1.Python ...

  4. 【Python3爬虫】下载酷狗音乐上的歌曲

    经过测试,可以下载要付费下载的歌曲(n_n) 准备工作:Python3.5+Pycharm 使用到的库:requests,re,json,time,fakeuseragent 步骤: 打开酷狗音乐的官 ...

  5. Python代码搜索并下载酷狗音乐

    运行环境: Python3.5+Pycharm 实例代码: import requests,re keyword = input("请输入想要听的歌曲:") url = " ...

  6. Java爬虫系列之实战:爬取酷狗音乐网 TOP500 的歌曲(附源码)

    在前面分享的两篇随笔中分别介绍了HttpClient和Jsoup以及简单的代码案例: Java爬虫系列二:使用HttpClient抓取页面HTML Java爬虫系列三:使用Jsoup解析HTML 今天 ...

  7. htmlunit+fastjson抓取酷狗音乐 qq音乐链接及下载

    上次学了jsoup之后,发现一些动态生成的网页内容是无法抓取的,于是又学习了htmlunit,下面是抓取酷狗音乐与qq音乐链接的例子: 酷狗音乐: import java.io.BufferedInp ...

  8. python使用beautifulsoup4爬取酷狗音乐

    声明:本文仅为技术交流,请勿用于它处. 小编经常在网上听一些音乐但是有一些网站好多音乐都是付费下载的正好我会点爬虫技术,空闲时间写了一份,截止4月底没有问题的,会下载到当前目录,只要按照bs4库就好, ...

  9. python爬取酷狗音乐排行榜

    本文为大家分享了python爬取酷狗音乐排行榜的具体代码,供大家参考,具体内容如下  

随机推荐

  1. 六、Jmeter中自动提取Http请求参数,并put到Map,然后进行MD5加密

    1.BeanShell PerOrocessor中的脚本 import src.com.csjin.qa.MD5.*;//个人jar包 import java.util.*; import java. ...

  2. [笔记] Delphi使用DUnitX做单元测试的简单例子

    Delphi XE 提供了对DUnitX的支持,记录一个最简例子. 首先创建项目A,然后创建单元untCalc,代码如下: unit untCalc; interface type TCalc = c ...

  3. 利用java执行shell脚本

    BPMN中存在由系统执行的脚本任务,shell脚本任务也是该系统任务脚本中的一种,利用的也是由java执行shell脚本. 代码中的ProcessBuilder类,为java.lang.Process ...

  4. web站点放在nginx其他目录下

    web站点放在nginx其他目录下 .查看主配置文件 [root@bogon mysql]# cat /etc/nginx/nginx.conf user root root; worker_proc ...

  5. 运行python manage.py 出现mportError: No module named django.core.management when using manage.py

    1 . linux下用virtualenv 创建虚拟空间环境没有安装djang,即使主机装了,否则运行python manage.py 出现mportError: No module named dj ...

  6. Git本地初始化并推送到远程仓库

    git常用命令 1.全局配置git用户名邮箱 git config --global user.name '你的名字' git config --global user.email '你的邮箱地址' ...

  7. 系统 --- Linux系统环境搭建

    Linux命令介绍 软硬链接 作用:建立连接文件,linux下的连接文件类似于windows下的快捷方式 分类: 软链接:软链接不占用磁盘空间,源文件删除则软链接失效 硬链接:硬链接只能链接不同文件, ...

  8. 人工智能06 能计划的agent

    能计划的agent 存储与计算 响应agent的动作功能几乎没有做任何计算.从本质上讲,这些agent执行的动作或者由他们的设计者.或者通过学习.或者通过演化过程.或者由以上几方面的组合来选择给他们的 ...

  9. SpringMVC必备知识点汇总

    1.参数接收 1.1 数组 1.2 文件上传 1.2.1 单个文件上传 1.2.2 多个文件上传 1.2.3 文件上传时,携带其他数据 2.参数校验 参数校验:https://www.cnblogs. ...

  10. Elasticsearch-日期类型

    Elasticsearch-日期类型 date类型用于存储日期和时间.它是这样运作的:通常提供一个表示日期的字符串,例如2019-06-25T22:47.然后,ES解析这个字符串,然后将其作为long ...