AHA

目录

前言

一、分析

二、构想实现

三、代码实现

1.引入jar包(使用工具来简化开发)

2.写入代码

3.完成

总结


前言

最近表姐想让我帮她U盘下载几首车载音乐,感觉挺简单的,直接打开谷歌浏览器搜索酷狗音乐(表姐要的歌单是酷狗),播放一首歌页面跳转到播放器,然后老规矩F12+Ctrl+F,搜索audio标签得到src链接,点进去就能下载了,可是她要的可不止一首啊,要整个歌单,那只能采用爬虫来获取我们想要的东西了。


一、分析

爬虫之前我们需要熟悉爬虫的基本流程:

1.发起请求:通过url向服务器发起request请求,请求可以包含额外的header信息。

2.获取响应内容:如果服务器正常响应,那我们将会收到一个response,response即为我们所请求的网页内容,或许包含HTML,Json字符串或者二进制的数据(视频、图片)等。

3.解析内容:如果是HTML代码,则可以使用网页解析器进行解析,如果是Json数据,则可以转换成Json对象进行解析,如果是二进制的数据,则可以保存到文件进行进一步处理。

4.保存数据:可以保存到本地文件,也可以保存到数据库


附上歌单链接:https://www.kugou.com/yy/special/single/3337103.html


首先我们要的是歌单里面的每一首歌曲,从上面可以发现每一首歌都有一个a标签,而且这个a标签都有一个data值,而href指向的不是一个具体的地址,所以可以判定的采用JS代码控制来跳转的,再看看下面的图片是新跳转的播放器页面的URL,可知每一首歌对应的hash的值和歌单页面的歌曲a标签的data值一致,这就可以知道hash了,但是这个album_id是怎么来的呢?

        我们再点开一首歌曲,可以看出变化的只是hash和album_id


        也就是说这个hash和album_id是从歌单页面跳转到播放页面的,那要找这个album_id也得从歌单页面找,作者在歌单页面里的JS文件找到了album_id的出处,其实在页面加载时就已经从后端接口请求这个歌单的所有歌曲信息,后来找到了这个data变量藏在了head标签里

光有这些参数其实还不行,还得找到对应的后端请求接口,就像水管漏水了,空有一身修水管的功夫但是找不到哪个地方漏水也是虚劳的。因为我们的点击音乐会跳到播放页面,所以可以断定获取歌曲的请求是在播放页面上的,我们简单地抓一下包,打开F12,点击Network,Ctrl+R键刷新一下(因为页面在我们调试器打开之前就已经加载好了),一堆数据包我们只要其中的JS或者PHP文件,最终我们找到了我们的请求接口。

而这个接口里面变化的只有hash和album_id,所以我们可以拿取歌单的data变量里的hash和album_id去请求这个接口获取我们要的数据了

打开这个接口,往下翻可以找到这个资源就是我们要下载的东西


二、构想实现

每一个程序的功能的诞生离不开程序猿(媛)们的奇妙构想,所以我们也得先把总的实现思路构建起来才来进行下一步。

1.获取歌单所有的hash和album_id值。    既然我们要的是歌单所有的歌曲,而歌曲的获取唯一判别他们的可不是歌名,就像你的名字叫张三,他的名字也叫张三,那要是他犯法了抓不到,抓到了你这个张三那肯定不行,所以歌曲也一样,不能以歌名区分,只能用album_id来区分,和身份证号是一个道理,那我们就可以先获取歌单页的data变量,再把他们储存起来,匹配的话我们统一采用正则表达式。

2.接口地址拼接hash和album_id。   我们将获取到的歌曲请求接口按照我们匹配出来的hash和album_id拼接起来再去请求就能得到我们所要的数据。

3.下载到本地。   到了这一步已经是完成了,借助JavaIO流把数据传输到本地文件或者数据库上。(这边是准备上传到U盘里面所以就没必要放入数据库了)

三、代码实现

1.引入jar包(使用工具来简化开发)

<dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.13.1</version>
</dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version>
</dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.9.0</version>
</dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.11.4</version>
</dependency>

Jsoup:一款Java 的HTML解析器,它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

HttpComponents:是专门设计来简化HTTP客户端与服务器进行各种通讯编程,主要是提供对http服务器的访问功能。

Commons-io:使用Java原生的IO流操作比较繁琐,可以利用IO工具库来简化。

Jackson:用来解析序列化和反序列化Json数据。

关于上面的工具库不再赘述了,有兴趣的小伙伴可以自行了解

2.写入代码

/*** @author Ember*/
public class SpiderKugou {/*** 1.歌曲的hash值 [正则匹配]* 2.歌曲的album_id [正则匹配]* 3.歌名 [正则匹配]* 4.歌曲下载地址 [正则匹配]* 5.unicode转中文 [正则匹配]*/private static final String hashRegex = ",\"hash\":\"(.*?)\",\"brief\":";private static final String albumIdRegex = "\"album_id\":(.*?),\"hash\"";private static final String audioNameRegex = "\"audio_name\":\"(.*?)\",\"have_album\"";private static final String playUrlRegex = "\"play_url\":\"(.*?)\",\"authors\":";private static final String unicodeRegex = "(\\\\u(\\p{XDigit}{4}))";private static String baseUrl = "https://www.kugou.com/yy/special/single/3953033.html";private static String downloadSrc = "E:/2021-8-8酷狗歌曲/download/";public static void main(String[] args) throws Exception {System.out.println("下载中...");parameter(baseUrl);System.out.println("歌单下载已完成!");}/*** 爬取歌单的每一首歌曲* @param baseUrl 酷狗歌单链接地址* @throws Exception*/public static void parameter(String baseUrl) throws Exception {//JSON工具ObjectMapper mapper = new ObjectMapper();//获取歌单的DocumentDocument musicList = Jsoup.connect(baseUrl).get();//正则表达式匹配出歌单所有hash和album_id对应的值List<String> musicHash = myRegexpList(musicList.toString(), hashRegex);List<String> musicId = myRegexpList(musicList.toString(), albumIdRegex);for (int i = 0;i < musicId.size();i++) {//调出歌单每首歌的接口String mp3 = "https://wwwapi.kugou.com/yy/index.php?r=play/getdata&callback=jQuery191043744424319789976_1628418579111" +"&hash="+musicHash.get(i)+"&dfid=08yAMj3R2Rtq2vHAnv0NSCKV&mid=94bf13b027c6ce8289bdfa422f5e783e&platid=4" +"&album_id="+musicId.get(i)+"&_=1628418579112";//获取歌曲的docDocument musicPlayer = parsUrl(mp3);//获取歌曲的歌名String unicodeName = myRegexpOne(musicPlayer.toString(), audioNameRegex);//将unicode编码的歌名转换为中文String musicName= unicodeToString(unicodeName);//将接口的数据转为JSON对象String mp3Doc = mapper.writeValueAsString(musicPlayer.body().text());//转JSON有反斜杠,将反斜杠替换掉即可mp3Doc = mp3Doc.replaceAll("\\\\", "");//得到歌曲下载地址String playUrl = myRegexpOne(mp3Doc, playUrlRegex);//下载downLoadMusic(playUrl,musicName);System.out.println((i+1) + "--->【" + musicName + "】 >ω< 下载完成");Thread.sleep(1000);}}
public static void downLoadMusic(String musicUrl,String musicName){try {System.out.println("\n" + musicName + "源地址->" + musicUrl);Connection.Response response = Jsoup.connect(musicUrl)//忽略ContentType.ignoreContentType(true)//解除最大字节限制.maxBodySize(0)//模拟浏览器用户代理.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")//执行.execute();ByteArrayInputStream stream = new ByteArrayInputStream(response.bodyAsBytes());FileUtils.copyInputStreamToFile(stream,new File(downloadSrc + musicName + ".mp3"));} catch (Exception e) {System.out.println("链接->"+musicUrl+" >﹏< 下载失败");e.printStackTrace();}}/*** 获取Doc工具类* @param url* @return* @throws Exception*/public static Document parsUrl(String url) throws Exception {try {Document document = Jsoup.connect(url).userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36").timeout(2000).get();return document;}catch (Exception e){e.printStackTrace();return null;}}/*** 正则匹配字符串集合工具类* @param str* @param keyWords* @return*/public static List<String> myRegexpList(String str,String keyWords){List<String> list = new ArrayList<>();Pattern compile = compile(keyWords);Matcher matcher = compile.matcher(str);while (matcher.find()) {list.add(matcher.group(1));}return list;}/*** 正则匹配单个字符串工具类* @param str* @param keyWords* @return*/public static String myRegexpOne(String str,String keyWords){String result = "";Pattern compile = compile(keyWords);Matcher matcher = compile.matcher(str);while (matcher.find()) {result = matcher.group(1);}return result;}/*** unicode转码中文字符* @param str* @return*/public static String unicodeToString(String str) {Pattern pattern = compile(unicodeRegex);Matcher matcher = pattern.matcher(str);char ch;while (matcher.find()) {ch = (char) Integer.parseInt(matcher.group(2), 16);str = str.replace(matcher.group(1), ch+"" );}return str;}
}

3.完成

        可以看到我们下载成功了


总结

为什么使用Java爬虫来抓取酷狗资源呢,一个是目前大多都是Python教程,Java爬取酷狗比较少,也有一些小伙伴可能只接触到Java这门编程语言或者就没接触Python的,想要了解了解如何使用Java进行抓取。二是作者也是刚接触到Java爬虫,Python并没了解过,但Java和Python都能做到相同的东西,只是工程量的事,还有表姐突如其来的要求也让我萌生了使用Java练手一下。
        以上就是今天要讲的内容,本文仅仅简单介绍了Java如何爬取网页数据的使用,还有如何使用第三方类库更加方便地进行开发。有需要的小伙伴可供参考,如果觉得本文对你有一定的帮助的话不妨帮我点个赞,收藏一下~感谢!

Java爬取酷狗音乐歌单相关推荐

  1. 4步实现Java爬取酷狗音乐,so easy。

    jar包:包括:jsoup.HttpClient.net.sf.json大家可以自行去下载 1.分析是否能获得TOP500歌单 首先,打开酷狗首页查看酷狗TOP500, 是真的只让看这些还是能找到其余 ...

  2. PHP爬虫音乐,PHP 爬虫———爬取网易云音乐歌单

    爬取网易云音乐歌单 PHP + QueryList + Puppeteer + Nodejs 使用 Composer 安装库 如果你之前没有接触过Composer,强烈建议你学习一下.Composer ...

  3. java爬取酷狗榜单歌曲信息并存入数据库

    这里只解析一下代码,所需工具jsoup.HttpClient httpCLient获取html后,用jsoup解析html,再用java来获取所需要的信息. 之前写的有点问题,今天改了一下.因为通过h ...

  4. python爬取酷狗付费音乐_python爬蟲教程:爬取酷狗音樂

    在常見的幾個音樂網站里,酷狗可以說是最好爬取的啦,什么彎都沒有,也沒加密啥的,所以最適合小白入門爬蟲 本篇針對爬蟲零基礎的小白,所以每一步驟我都截圖並詳細解釋了,其實我自己看着都啰嗦,歸根到底就是兩個 ...

  5. python爬取网易云音乐歌单

    获取网易云音乐的某个分类下的歌单的详细页地址.歌单标题.歌单播放量.歌单贡献者.歌单索引信息等.并保存到csv文件中去. 用到的模块:requests.time.BeautifulSoup 选择不同类 ...

  6. 如何用 Python 爬取网易云音乐歌单

    点击⬆️方"逆锋起笔",公众号回复 编程资源领取大佬们推荐的学习资料 作者:我不是秃头哆唻咪 (侵删) https://blog.csdn.net/weixin_44864260/ ...

  7. 如何用Python爬取网易云音乐歌单

    此货很干,跟上脚步!!! Cookie cookie是什么东西? 小饼干?能吃吗? 简单来说就是你第一次用账号密码访问服务器 服务器在你本机硬盘上设置一个身份识别的会员卡(cookie) 下次再去访问 ...

  8. 看我如何用 Python 爬取网易云音乐歌单

    此货很干,跟上脚步!!! Cookie cookie是什么东西? 小饼干?能吃吗? 简单来说就是你第一次用账号密码访问服务器 服务器在你本机硬盘上设置一个身份识别的会员卡(cookie) 下次再去访问 ...

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

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

  10. Python疫起学习·万丈高楼平地起Day09(精简版|浓缩就是精华)爬虫知识附上案例爬取北京地区短租房信息、爬取酷狗TOP500的数据以及爬取网易云音乐热歌榜单

    爬虫知识 Requests库 部分运行结果如下: 有时爬虫需要加入请求头来伪装成浏览器,以便更好地抓取数据.在Chrome浏览器中按F12键打开Chrome开发者工具,刷新网页后找到User-Agen ...

最新文章

  1. linux ssh和sftp区别,使用 SSH 和 SFTP 协议
  2. HTML5怎么让图片和文字重叠,利用HTML5实现全屏图片文字过渡切换特效
  3. 数据中心布线系统构成及不同规模范例
  4. SpringMvc 事务的注解配置、实现、挂起
  5. jQuery 仿淘宝 鼠标悬停显示大图效果
  6. 译: 3. RabbitMQ Spring AMQP 之 Publish/Subscribe 发布和订阅
  7. ik分词和jieba分词哪个好_Python 中文 文本分析 实战:jieba分词+自定义词典补充+停用词词库补充+词频统计...
  8. Redis ZSet 的几种使用场景
  9. 深度学习入门:Day-12
  10. ibatis调用mysql带OUT类型参数的存储过程并获取返回值
  11. iphonex屏幕出现一条绿线_关于对 iPhone 11、iPhone X? 采用的 Liquid 视网膜显示屏的误区,在此说明。...
  12. C++ 从入门到入土(English Version)Section5: Real numbers + bitwise operations
  13. 编译nanopi neo 或者M1 uboot 启动SylixOS系统
  14. netbeans运行KEmulator
  15. 细数国内外的哪些数学建模竞赛
  16. 2022年全球市场光学软件总体规模、主要企业、主要地区、产品和应用细分研究报告
  17. 矩阵的初等变换与线性方程组
  18. android如何编译lame,ndk编译android的lame库
  19. mt管理器怎么运行HTML文件,MT管理器怎么修改游戏数据 MT管理器修改内购教程
  20. 事件clientX、pageX、screenX、offsetX

热门文章

  1. 模型调参:概述【weight_decay、base_lr、lr_policy、clip_norm】【超参数调优方式:网格搜索(尝试所有可能组合)、随机搜索(在所有可能组合中随机选取参数组合)】
  2. C语言自学笔记(16)
  3. 加权移动平均线(Weigted Moving Average,WMA)
  4. 视频教程-【企业定制课】AI软件illustratorCC应用与平面印刷视频教程-UI
  5. 【Java 8 新特性】Java LocalDate 详解
  6. 超实用的工具、素材、学习网站分享
  7. html+css实现天猫官网
  8. VS2012下载网址
  9. Win10系统,ColorPix取色位置偏移如何解决?
  10. python 报表打印预览_python学习笔记之wxpython打印预览