基于Kotlin(可转Java)开发的网易云音乐爬虫项目

简介
基于kotlin环境开发,但转Java是可以的,只是多写点代码而已。直奔主题,我是朝着云音乐的评论去的,在接口没有暗改前这个还是可以使用的,具体代码参见:CloudMusic

先说一下使用方法,一个简单的示例:
这里写图片描述

输出就不贴了,下边逐个来说一下使用需要知道的事项:
音乐搜索

 /**
     * 音乐搜索,返回SongResult
     * @Param name 搜索名
     * @param type 搜索类型 1-> 单曲  10->专辑 100->歌手 1000->歌单 1002->用户
     * @param count 搜索结果数目
     * @param page 显示页数
     */
    fun songSearch(name:String,type:Int,count:Int,page:Int):SongsResult{
        val song = SongsResult::class
        val map = mutableMapOf<String,String>()
        map["s"] = name
        map["limit"] = count.toString()
        map["type"] = type.toString()
        map["offset"] = page.toString()

        val temp = client.requestPostSyn(BASE_URL_163, ACTION_URL_SEARCH,map)
        val json = JsonParser().parse(temp).asJsonObject["result"].toString()
        return Gson().fromJson(json,song.javaObjectType)
    }

音乐搜索是根据搜索关键词,搜索类型,搜索数目,和搜索的页数来发起请求的,数据未加密,返回json数据格式:
这里写图片描述
搜索这个 其实可以分裂出好多功能,比如歌曲、歌单、专辑、用户的获取,关键点都是关键词的模糊匹配,本数据返回封装:(data class等价于JavaBean)

data class SongsResult(val songs:List<Song>,val songCount:Int)
data class Song(val id:Long, val name:String, val artists: List<Artist>, val album: Album, val duration:Int, val status:Int, val mvId:Int, val fee:Int)

返回的是List集合,需要使用Song数据的话可直接自行提取。例如:

val songs = api.songSearch("好久不见",1,20,1)
    val song = songs.songs
    for (num in 0 until song.size) println("歌曲:"+song[num].name + ",专辑:"+song[num].album)

结果:当然这里的专辑又可以是另一个Javabean对象
这里写图片描述

扩展功能如需实现,可自行尝试。

歌单歌曲

/**
     * 获取歌单歌曲,地址已内置,引用 类TopList.变量名 即可,如(TopList.MUSIC_HOT)
     * 当然也可以自定义地址,如自己创建的歌单id
     * @param id 歌曲id
     */
    fun TracksMusic(id:String):TracksResult{
        val tracks = TracksResult::class

        val map = mutableMapOf<String,String>()
        map["id"] = id
        val temp =  client.requestGetSyn(BASE_URL_163, ACTION_URL_TOP,map)
        val json = JsonParser().parse(temp).asJsonObject["result"].toString()

        return Gson().fromJson(json,tracks.javaObjectType)
    }

歌单歌曲只需要传入歌单ID即可,至于歌单id的获取,并未加密,可直接搜索到。
直接上例子吧:

//    歌单歌曲
    val tracks = api.TracksMusic("832569787")
    val tracks_name = tracks.name
    val t = tracks.tracks
    println("歌单名:"+tracks_name+"包含歌曲名:")
    for (num in 0 until t.size) println(t[num].name)

结果:
这里写图片描述

Javabean里边的数据内容非常丰富,我自己设计的只是常用到的,如有需要定制个性化内容请自行修改Javabean里的内容。

热门评论
哈哈,这个是我的初衷,就是想要爬这个数据,歌曲是一笔财富,评论更是一笔财富,闲着没事看评论也是入了迷呢。我不相信你没有故事,评论有的搞笑、有的深情、有的自己明白就好不用向任何人说起。来看看效果吧:

//    热门评论
    val hot = api.hotComments("65538")
    val comments = hot.hotComments
    for (num in 0 until comments.size) println(comments[num].content)

结果:
这里写图片描述

需要注意的是热评数量少,其他的都是最新评论,而评论数据加密了,采用和密码加密的方式相同只是少了MD5加密,下边是其他评论:

  /**
     * 评论获取,第一页comments为最新评论,hotComments为热门评论,第二页之后不再有hotComments
     * @param musicId 目标评论的音乐Id
     * @param page 页数
     * @param count 获取评论数量
     */
    fun comments(musicId: String,page: Int,count:Int):CommentResult{
        val commentBean = CommentResult::class

        val action_url = ACTION_URL_COMMENTS + musicId
        val map = encrypted_comments(musicId,page,count)
        val result = client.requestPostSyn(BASE_URL_163, action_url,map)
        println(result)
        return Gson().fromJson(result, commentBean.javaObjectType)
    }

测试代码:(这里我测试了第10页,数量爬了100条)

//最新评论
    val comment = api.comments("65538",10,100)
    val cs = comment.comments
    for (num in 0 until cs.size) println(cs[num].content)

结果:(爬的是100条,屏幕太小未显示完)
这里写图片描述

我们如果要查找评论信息的话也只能是在这里爬取成千上万的评论了,如果需要的话。

手机登录
(手机登录暂时没有发现有请求头身份认证的问题,但是有多次登录暂时封IP的保护,可以考虑实现cookie登陆或者代理服务)

//    手机登陆(账号密码我匿名了)
    val phone = api.loginPhone("xxxxxxxx","xxxxxxx")
    val res = phone.profile
    println("用户名:"+res.nickname+",生日:"+ timeStamp2Date(res.birthday.toString())+",个性签名:"+res.signature)

结果:
这里写图片描述

这里网易所有的时间使用的都是unix时间戳类型,我自己封装了方法可直接转一下就是了:


/**
 * 返回指定格式时间 如"yyyy-MM-dd"
 */
fun timeStamp2Date(timeString:String,format:String): String {
    val timeStamp = timeString.toLong()
    return SimpleDateFormat(format).format(Date(timeStamp))
}

/**
 * 返回默认yyyy-MM-dd HH:mm:ss格式时间
 */
fun timeStamp2Date(timeString: String):String{
    val timeStamp = timeString.toLong()
    val format = "yyyy-MM-dd HH:mm:ss"
    return SimpleDateFormat(format).format(Date(timeStamp))
}

/**
 * 返回指定时间时间戳 pattern为指定格式 如"yyyy-MM-dd HH:mm:ss"
 */
fun date2TimeStamp(date:String,pattern:String):Long{
    val simpleDateFormat = SimpleDateFormat(pattern)
    val res = simpleDateFormat.parse(date)
    return (simpleDateFormat.parse(simpleDateFormat.format(res))).time /1000
}

/**
 * 返回当前时间时间戳
 */
fun date2TimeStamp():Long{
    return Date().time

其他的province和city属性也是地区的数字代码,这个未做相应处理,如有需要请自行转换。

以上就是基本的使用方式了,其他如有想扩展功能,比如热门榜单评论获取,可在此基础上进一步封装下,如果有特殊需求比如想爬取百万级评论的话,就需要考虑网络请求的异步处理了,至于邮箱登录,暂时处理不了,好像是网易附加了自己的三方动态身份验证–网易云盾,这个我看了下价格不菲,所以就暂时不处理了,而且邮箱业务也是网易的杀手锏,没有理由不做足防范的,手机登录指不定那一天也要被进一步加密,如果有互相学习的地方,欢迎交流,kotlin编写的项目比较简洁,转成java的话需要多加点班,代码原理是一样的

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值