首先明确要爬取的项目:网易云音乐及评论
目标:将项目中的热门评论进行分词生成图片
应该具备的功能:1.抓取单曲2.抓取评论3.分词
使用API获取歌手的歌单信息,每个歌手均对应一个id
歌手的信息:API+ID
需要构建歌单和歌曲两个关键模型
由此来设计相关接口和实现类
项目依赖:okhttp3
非常适合移动端的开发,但是对于web端的Java应用开发也是同样的强大。
请求过程:使用GET请求
构造OkHttpClient(可以通过new或者Builder)->构造Request->newCall->Call#execute或者Call#enqueue。最后一步操作就是同步或者异步请求的区别。
设计歌手歌曲两个实例对象及其属性
核心服务:爬取
首先第一步应该构建歌单url,进行组装
由于各个各个歌单的url只有后面歌手的参数不同
因此将前面的api定义为一个final变量,方便调用
private static final String ARTIEST_API_PREFIX
一、调用okhttp3来进行爬取:
// 首先创建okHttpClient 实例
private OkHttpClient okHttpClient;
//初始化操作
private void init() {
//1. 构建 okHttpClient 实例
okHttpClient = new OkHttpClient();
artists = new HashMap<>();
}
public void start(String artistId) {
// 参数判断,未输入参数则直接返回
if (artistId == null || artistId.equals("")) {
return;
}
// 执行初始化
init();
// 取得整体数据对象。
Map returnData = getArtistObj(artistId);
}
private Map getArtistObj(String artistId) {
// 构建歌单url
String aUrl = ARTIEST_API_PREFIX + artistId;
// 调用 okhttp3 获取返回数据
String content = getPageContentSync(aUrl);
// 反序列化成 Map 对象
Map returnData = JSON.parseObject(content, Map.class);
return returnData;
}
/**
* 根据输入的url,读取页面内容并返回
*/
private String getPageContentSync(String url) {
//2.定义一个request
Request request = new Request.Builder().url(url).build();
//3.使用client去请求
Call call = okHttpClient.newCall(request);
String result = null;
try {
//4.获得返回结果
result = call.execute().body().string();
System.out.println("call " + url + " , content's size=" + result.length());
} catch (IOException e) {
System.out.println("request " + url + " error . ");
e.printStackTrace();
}
return result;
}
二、将返回的数据进行处理,获取填充属性的artist实例
private Artist buildArtist(Map returnData) {
// 从 Map 对象中取得 歌单 数据。歌单也是一个子 Map 对象。
Map artistData = (Map) returnData.get("artist");
Artist artist = new Artist();
artist.setId(artistData.get("id").toString());
if (artistData.get("picUrl") != null) {
artist.setPicUrl(artistData.get("picUrl").toString());
}
artist.setBriefDesc(artistData.get("briefDesc").toString());
artist.setImg1v1Url(artistData.get("img1v1Url").toString());
artist.setName(artistData.get("name").toString());
artist.setAlias((List) artistData.get("alias"));
return artist;
}
使用builArtist方法进行填充,具体思路是从完整返回数据中取出artist字段
然后创建artist实例,分别对其id等属性进行填充
三、获取填充了数据的song实例
private List<Song> buildSongs(Map returnData) {
// 从 Map 对象中取得一组 歌曲 数据
List songsData = (List) returnData.get("hotSongs");
List<Song> songs = new ArrayList<>();
for (int i = 0; i < songsData.size(); i++) {
Map songData = (Map) songsData.get(i);
Song songObj = new Song();
songObj.setId(songData.get("id").toString());
songObj.setName(songData.get("name").toString());
songs.add(songObj);
}
四、最后将获取的歌曲存入歌单
// 歌曲填入歌单
artist.setSongList(songs);
// 存入本地
artists.put(artist.getId(), artist);