一般项目流程

《实战网易云音乐评论分析》总结 - 图1

项目需求

将一首音乐的热门评论和最新评论制作成一个词云,例如:
《实战网易云音乐评论分析》总结 - 图2

功能描述

  • 抓取单曲 爬虫+数据分析,抓取指定歌手的热门单曲
  • 抓取评论 抓取热门单曲的的热门评论
  • 分词 对评论用工具进行分词

    技术方案

    对需求进行梳理,整合成技术方案:
  1. 自动查询某个歌手的所有热门歌曲
  2. 自动获取每一首歌的基础信息,专辑信息
  3. 自动获取每一首歌的热门评论,最新评论
  4. 对所有的热门评论进行统计形成词云

    用到的技术点和知识点

    API

    | 查询某个歌手歌单信息的API | http://neteaseapi.youkeda.com:3000/artists?id=xxxx | id - 歌手id | | —- | —- | —- | | 获取每首歌详细信息的API | http://neteaseapi.youkeda.com:3000/song/detail?ids=xxxx,xxxx | ids - 歌曲id,查询多个歌曲用逗号分开 | | 获取每首歌评论的API | http://neteaseapi.youkeda.com:3000/comment/music?id=xxxx&limit=xxxx | id - 歌曲id,limit - 评论条数 | | 获取每首歌的音乐文件地址 | http://neteaseapi.youkeda.com:3000/song/url?id=xxxx,xxxx | id - 歌曲id,查询多个用逗号隔开 |

模型设计和服务设计

模型设计是在通过API获取到JSON格式的数据后,分析确定字段,完成(POJO)模型设计。
服务设计是确定完成某个功能技术所需要的方法,都是接口+实现。在实现类里,往往需要一个初始化实例变量的方法,这样扩展性较好。

maven依赖

项目需要用到的maven依赖有

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.squareup.okhttp3</groupId>
  4. <artifactId>okhttp</artifactId>
  5. <version>4.1.0</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>com.alibaba</groupId>
  9. <artifactId>fastjson</artifactId>
  10. <version>1.2.62</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>com.kennycason</groupId>
  14. <artifactId>kumo-core</artifactId>
  15. <version>1.17</version>
  16. </dependency>
  17. <!-- 下面tokenizers是为了中文分词引入 -->
  18. <dependency>
  19. <groupId>com.kennycason</groupId>
  20. <artifactId>kumo-tokenizers</artifactId>
  21. <version>1.17</version>
  22. </dependency>
  23. </dependencies>

JSON数据格式的解析

解析JSON对象
JSON在线视图查看器

get请求API获取数据(爬取)

get请求

反序列化对象

JSON与FastJSON

代码重构

  1. 重构的含义

在不改变代码接口的情况下,对代码作出修改,以改进程序的内部结构。简单说就是在代码写好之后改进其方法体内的实现,对其他调用者是透明的。

  1. 重构的目的

提高代码质量(性能、可读性、可重用性)
修改bug
增加新功能

Map

概念

《实战网易云音乐评论分析》总结 - 图3

map接口中常用集合

  • HashMap 存储数据采用的哈希表结构,元素的存取顺序不能保证一致,由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
  • LinkedHashMap HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。

    map接口中的常用方法

    | 方法 | 解释 | | —- | —- | | get(Object key) | 返回key映射的value,如果此映射不包含key的映射关系,则返回null | | put( k key,V value) | 将key与value 形成映射关系,添加到集合中 | | remove(Object key) | 如果存在一个键的映射关系,则将其从此映射中移除 |

遍历

《实战网易云音乐评论分析》总结 - 图4

  1. public class MapDemo {
  2. public static void main(String[] args) {
  3. //创建Map对象
  4. Map<String, String> map = new HashMap<String,String>();
  5. //给map中添加元素
  6. map.put("邓超", "孙俪");
  7. map.put("李晨", "范冰冰");
  8. map.put("刘德华", "柳岩");
  9. //获取Map中的所有key
  10. Set<String> keySet = map.keySet();
  11. //遍历存放所有key的Set集合
  12. Iterator<String> it =keySet.iterator();
  13. while(it.hasNext()){ //利用了Iterator迭代器
  14. //得到每一个key
  15. String key = it.next();
  16. //通过key获取对应的value
  17. String value = map.get(key);
  18. System.out.println(key+"="+value);
  19. }
  20. }
  21. }
  1. //for each简单写法
  2. for(String item:map.keySet()){
  3. String value = map.get(item);
  4. }

《实战网易云音乐评论分析》总结 - 图5

  1. public class MapDemo {
  2. public static void main(String[] args) {
  3. //创建Map对象
  4. Map<String, String> map = new HashMap<String,String>();
  5. //给map中添加元素
  6. map.put("邓超", "孙俪");
  7. map.put("李晨", "范冰冰");
  8. map.put("刘德华", "柳岩");
  9. //获取Map中的所有key与value的对应关系
  10. Set<Map.Entry<String,String>> entrySet = map.entrySet();
  11. //遍历Set集合
  12. Iterator<Map.Entry<String,String>> it =entrySet.iterator();
  13. while(it.hasNext()){
  14. //得到每一对对应关系
  15. Map.Entry<String,String> entry = it.next();
  16. //通过每一对对应关系获取对应的key
  17. String key = entry.getKey();
  18. //通过每一对对应关系获取对应的value
  19. String value = entry.getValue();
  20. System.out.println(key+"="+value);
  21. }
  22. }
  23. }
  1. //同样的for each写法
  2. for (Entry<String, String> entry: map.entrySet()) {
  3. int key = entry.getKey();
  4. String value = entry.getValue();
  5. }

词云库

最常用的词云库为 Kumo ,github地址为https://github.com/kennycason/kumo

UML图

4-1-1.svg