android在线查询音乐,Android 数据抓取——在线音乐播放器的实现

前言: 相信很多同学学习android都开做过播放器一类的小玩意吧,但是苦于没有服务器提供数据,因而只能做个本地播放器,今天,这篇文章就是通过数据抓取,实现没有服务器,依然可以在线搜索和播放音乐!

首先,贴上我的最终实现效果:

0818b9ca8b590ca3270a3433284dd417.png

因为数据是从虾米搜索页抓过来的,所以我把虾米logo加上去了,请大家忽略,下面来讲基本思路,首先虾米有这样一个隐藏的API:

所以,我们只需要知道歌曲ID就能获得歌曲信息了,一切都成为可能了,那么问题来了! 我们怎么获取歌曲ID呢?————没错,今天的主角登场

——Jsoup 我们用它去虾米搜索结果抓歌曲ID!

首先我们看看虾米的搜索网址:

0818b9ca8b590ca3270a3433284dd417.png

然后我们对页面审查源代码,我们可以清楚的发现,所有搜索结果是放在一个 名为 track_list的 table中(也就是html表格中),如图所示:

0818b9ca8b590ca3270a3433284dd417.png

我们继续往里面看:

在一个chkbox的 标签里面发现了一串数字,测试之前的我们的接口,果然是相符的,id就是它了!

0818b9ca8b590ca3270a3433284dd417.png

接下来就是写代码了!

首先我们导入jsoup的jar包到我们的项目中 Jsoup下载地址:

Jsoup 需要添加网络权限

/** 搜索关键字地址 */

public static String KEY_SEARCH_URL = "http://www.xiami.com/search/song?key=";

/** ID接口地址 */

public static String ID_SEARCH_URL = "http://www.xiami.com/song/playlist/id/";

/** * 抓取歌曲id * *@param 搜索关键词 *@param listener * 完成监听 */

public static void getIds(String input, OnLoadSearchFinishListener listener) {

List allIds = new ArrayList();

String key = deCondeKey(input);// 解析用户输入关键字为 UTF-8

Document document = null;

try {

document = Jsoup.connect(KEY_SEARCH_URL + key).get();// jsoup连接最终拼接而成的请求字符串

Elements elements = document.getElementsByClass("track_list");// 选择类标签

if (elements.size() != 0) {

Elements all = elements.get(0).getElementsByClass("chkbox");

int size = all.size();

for (int i = 0; i < size; i++) {

String id = all.get(i).select("input").attr("value");

if (!StringUtils.isEmpty(id)) {

allIds.add(id);// 不为空的话加入id list中,便于初次抓取完以后统一请求

}

}

if (listener != null) {

if (allIds.size() == 0) {

listener.onLoadFiler();// id list大小为0 说明没有获取到数据,抓取失败

} else {

// 统一请求id接口地址进行再次抓取

listener.onLoadSucess(getOnlineSearchList(allIds));

}

}

}

} catch (IOException e) {

listener.onLoadFiler();

e.printStackTrace();

}

}

核心逻辑解释:

首先我们用Jsoup.connect(url).get()方法获得一个document对象,然后用document对象去筛选我们先分析的那个表也就是track_list 返回一个Elements对象,我们在此筛选 chkbox,依然返回一个Elements 对象,由于歌曲有很多首,我们需要遍历一下,再选择input 标签获得我们的id

Elements elements = document.getElementsByClass("track_list");// 选择类标签

Elements all = elements.get(0).getElementsByClass("chkbox");

int size = all.size();

for (int i = 0; i < size; i++) {

String id = all.get(i).select("input").attr("value");

}

上面方法就能获得我们的歌曲id,我们将它们封装在一个list中,在抓取id完成以后,我们依次取出list中的id去请求api 然后封装在一个list:中,便于在listview中展示:

Music.java实体类

import java.io.Serializable;

public class Music implements Serializable {

/** * */

private static final long serialVersionUID = 1L;

/** 歌名 */

private String musciName;

/** 歌手名 */

private String airtistName;

/** 歌曲路径 */

private String path;

/** 专辑名 */

private String albumName;

/** 小图URL */

private String smallAlumUrl;

/** 大图URL */

private String bigAlumUrl;

/** 歌曲id */

private String musicId;

/** 歌词地址 */

private String lrcUrl;

public String getMusciName() {

return musciName;

}

public void setMusciName(String musciName) {

this.musciName = musciName;

}

public String getAirtistName() {

return airtistName;

}

public void setAirtistName(String airtistName) {

this.airtistName = airtistName;

}

public String getPath() {

return path;

}

public void setPath(String path) {

this.path = path;

}

public String getAlbumName() {

return albumName;

}

public void setAlbumName(String albumName) {

this.albumName = albumName;

}

public String getSmallAlumUrl() {

return smallAlumUrl;

}

public void setSmallAlumUrl(String smallAlumUrl) {

this.smallAlumUrl = smallAlumUrl;

}

public String getBigAlumUrl() {

return bigAlumUrl;

}

public void setBigAlumUrl(String bigAlumUrl) {

this.bigAlumUrl = bigAlumUrl;

}

public String getMusicId() {

return musicId;

}

public void setMusicId(String musicId) {

this.musicId = musicId;

}

public String getLrcUrl() {

return lrcUrl;

}

public void setLrcUrl(String lrcUrl) {

this.lrcUrl = lrcUrl;

}

}

/** * 根据id 获取歌曲数据 * * @param ids 封装id 的list * * @return 封装好的list 用于listview展示 */

private static List getOnlineSearchList(List ids) {

List musicList = new ArrayList();

int idSize = ids.size();

for (int i = 0; i < idSize; i++) {

String postUrl = ID_SEARCH_URL + ids.get(i);

try {

Document d = Jsoup.connect(postUrl).get();// 连接相应ID的接口地址

Elements element = d.select("trackList");

for (Element e : element) {

Music music = new Music();

music.setMusicId(ids.get(i));

music.setMusciName(getSubString(e.select("title").text()));

music.setAirtistName(e.select("artist").text());

music.setSmallAlumUrl(e.select("pic").text());

music.setBigAlumUrl(e.select("album_pic").text());

music.setLrcUrl(e.select("lyric").text());

music.setAlbumName(e.select("album_name").text());

// 对加密过后的歌曲在线地址进行解密

music.setPath(StringUtils.decodeMusicUrl(e.select(

"location").text()));

musicList.add(music);// 数据获取成功 封装入list

}

} catch (IOException e) {

e.printStackTrace();

}

}

return musicList;

}

这边 歌曲地址是经过加密的,我们用的时候要先解密,算法在demo里面。

在抓取完数据获得list以后,我只需写一个adpter,将数据用listview展示即可,

效果如下:

0818b9ca8b590ca3270a3433284dd417.png

这里大功告成,在线搜索列表完成,要实现在线播放,只需要在listview点击的时候 使用 MediaPlayer.setDataSource(歌曲在线地址)即可,获得了在线地址,下载实现起来也很简单(自己写,或者借助第三方框架 xutils等均可)在这里本文主要讲核心抓取逻辑,这里就不做阐述了。

注意事项:

getIds()方法是网络访问,因此需要在子线程中调用,在主线程调用会报错,在数据获取完成以后,通过handler 再给listview设置adpter即可,具体代码大家请参考Demo.

数据抓取毕竟是拿别人网站上的数据,仅供学习使用,请不要用于任何商业用途!

有任何问题请留言或者私信!

点此Demo源码下载

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值