• 办事指南
  • 创业起步
  • 企业管理
  • 市场营销
  • 开店指南
  • 创业之路
  • 创业故事
  • 互联网创业
  • 工商知识
  • 财务知识
  • 税务知识
  • 会计知识
  • 其它创业知识
  • 当前位置: 工作范文网 > 创业 > 创业起步 > 正文

    Java实现网易云音乐爬虫实验报告

    时间:2020-09-21 12:45:33 来源:工作范文网 本文已影响 工作范文网手机站

    第 PAGE 2 页 共 NUMPAGES 2 页

    江南大学

    Java网络程序设计

    程序设计题目

    网易云音乐网站信息爬取

    班级

    Xxxx

    姓名

    山水不言

    学号

    Xxxxx

    2019 年 6 月

    课程设计内容

    网易云网站信息抓取:利用爬虫技术爬取网易云网站信息,统计分析出播放量前列的热门歌单,并且对歌单里的每一首歌曲页面进行爬取,分析歌曲的评论数量以及歌曲热评内容。对评论点赞量超过一万的所有热评人进行基础信息爬取和分析。

    具体内容:在爬取1301个歌单页面,57294个歌曲页面,21976个用户页面后分析出以下信息

    热门歌单的播放量,以此创建榜单

    热门歌单的歌单介绍,歌单的歌曲数目,歌单创建的日期,以此分析热门歌单形成的原因

    热门歌单里所有歌曲的歌手和评论数量,以此创建榜单

    平均每首歌曲的评论数在10万以上的歌手

    每首歌曲的前六条评论内容,分别统计评论获得的赞

    (6)获取点赞量在50万以上的评论和点赞量在100万以上的评论

    (7)歌曲前六位热评人的名字,id号

    (8)评论获赞在2万以上的热评人的年龄分布,地区分布,性别比例

    (9)评论获赞在2万以上的热评人使用网易云的时间,账号的等级,购买会员的情况

    背景知识

    网络爬虫(英语:web crawler),也叫网络蜘蛛(spider),是一种用来自动浏览 \o "万维网" 万维网的 网络机器人。

    网络爬虫始于一张被称作种子的统一资源地址(URL)列表。当网络爬虫访问这些统一资源定位器时,它们会甄别出页面上所有的超链接,并将它们写入一张“待访列表”,即所谓 爬行疆域。此疆域上的URL将会被按照一套策略循环来访问。

    爬虫在执行的过程中复制归档和保存网站上的信息,爬虫获取的资源一般有HTML类型和json类型 ,获取资源时有两种获取方式:Get请求和Post请求,用的最多的是Get请求,Post请求经常用于登录网,所传送的参数一般也加了密。

    爬虫爬取数据频率过高时会对目标网站的服务器带来异常访问频率,一般的中大型网站都会有反爬措施,相应地爬取网站可以设置休眠时间和使用代理ip。

    爬虫得到的数据有效性是有限的,网页的数据时刻在变化,有时候网页的框架也会发生变化,这可能导致数据过时或者爬虫程序无法运行成功。

    设计步骤与方法

    1.选定爬取网站

    网易云音乐是当下最火听歌软件之一,有很大的用户基数,里面有一些网易云独特的文化现象,比如用户听歌的时候喜欢看评论,每首歌曲的热评都有故事性或者趣味性,基于此种特性以及个人兴趣我选取了网易云音乐网站作为爬取的对象。

    2.爬取信息的初步确定

    网易云用户一般比较关注哪些歌单里面的歌比较好听,有哪些值得推荐的歌曲,有哪些评论值得一看,热评用户的信息等,因此,本爬虫项目会针对热门歌单,热门歌手,热门歌曲,热门评论,以及热评用户信息做一个基本获取并且分析结论。

    3.选取爬虫需要的工具

    经过上网查询资料,java爬虫工具使用的最多的是httpClient以及webmegic,其中webmegic实现则应用了httpclient、jsoup等java成熟的工具。它几乎使用Java原生的开发方式,只不过提供了一些模块化的约束,封装一些繁琐的操作,并且提供了一些便捷的功能。

    Webmegic的特点是:(1)简单的API,可快速上手;(2)模块化的结构,可轻松扩展;(3)提供多线程和分布式支持。

    由于后期分析有效数据的需要,搭配了正则表达式和Document类的使用。

    4.选择项目的类型

    由于采用了包含webmegic,jsoup,正则表达式等工具,需要在java项目里面导入多个外部的jar包,工作项目选用了方便管理包的项目框架:Maven项目,借助此项目框架可以用pom.xml文件灵活地下载包。

    5.熟悉爬虫工具

    爬虫工具的使用网上有较多的教程,其中webmegic有官方的中文文档,可以在里面方便地查询相关的知识。

    Webmegic有以下四大组件,Downloader负责从互联网上下载页面,PageProcessor负责解析页面,Scheduler负责管理待抓取的URL,Pipeline负责抽取结果的处理,包括计算、持久化到文件、数据库等。而Spider则将这几个组件组织起来,让它们可以互相交互,流程化的执行,可以认为Spider是一个大的容器,它也是WebMagic逻辑的核心。下图是四个组件以及Spider的关系表示:

    6.尝试爬取一个url地址的信息

    源代码以及注释如下

    public class SongCrawler implements PageProcessor{

    public static String url="/m/song? id=494152135"

    public void getSongInfo()

    {

    Spider.create(new SongCrawler())

    .addUrl(url)//种子页面的设定

    .run();//爬虫启动

    }

    public void process(Page page) {

    page.putField("网页内容",page.getHtml());

    //获取网页的源代码,默认输出到控制台,也可以定制pipeline

    //使其输出到数据库

    }

    private Site site=Site.me()//设置与网页交互的参数

    .setCharset("utf8")//设置目标网页的字符编码

    .setTimeOut(10000)//设置超时时间

    .setRetryTimes(3)//重试次数为3

    .setUserAgent("Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36");

    //使用代理,使得访问网页更像一个真实的浏览器

    public Site getSite() {

    return site;

    }

    }

    7.解析网页有用数据

    Webmegic里面的page提供了多种方便解析有用数据的方法,方法之间可以重复和交叉使用,使用的概览如下:

    除了webmegic已经提供的上述api接口,本程序结合需要还结合了类Document 来解析网页已达到目的,document除了可以方便地通过class,tag,id等元素来划分文本外,最重要的是可以用.text()方便的获取HTML文本里面的普通文本,这提高了提取这类信息的效率。

    8.数据持久化到数据库

    数据库选择了mysql,安装并且配置了可视化工具Nevicat,Nevicat可以方便地在数据库里面新建表,利用maven项目里面的pom.xml文件下载需要安装配置数据库驱动,新建操作数据库的类对数据库里面的表进操作。一共设计hot_playlist,playlist_info,song_info,user_info四个不同的表保存数据信息。

    9.设计爬取数据的步骤

    (1)爬取所有热门歌单,保存id和名称到数据库

    (2)爬取所有热门歌单的基本数据,保存每个歌单的创建时间,创建人,播放量以及里面包含的所有歌曲到数据库

    (3)爬取所有的歌曲页面,获取歌手

    (4)再次爬取所有歌曲页面,获取歌曲的评论信息,包括歌曲的总评论数目,热评前六的内容,获取的赞,热评人的id号和姓名,再次爬取的原因是网易云音乐的评论做了加密处理,只有通过另一个接口才能获取

    (5)对每一个热评点赞量在1万以上的用户进行爬取,获取该用户的年龄,性别,地区,用户等级,VIP等级,注册的时间。

    10.设计类,分配类的功能

    项目设计四个包,分别保管多个工具类,爬虫类,实体类,操纵数据库的类,爬虫类实现爬虫项目的启动,根据url地址下载页面,工具类接受已解析的数据,将信息还原为实体,并交给操纵数据库的类保存信息。

    11.爬取数据

    12.使用FineBI分析数据

    FineBI是一款分析数据的简单实用的工具,使用FineBI里面的多种形态的表格分析得出热门歌单,热门歌曲,热门歌手,热门评论,用户等的信息。使得数据更加直观且美观。

    实验环境

    操作系统:windows10 64位

    开发环境:eclipse,mysql

    步骤1: 爬取数据

    1.完成爬虫的基本过程,下面以实现爬取含多个热门歌单的页面为例具体说明实现过程。

    建立实现PageProcessor接口的HotPlaylistCrawler类,此类主要的工作是爬取网易云网站的所有热门歌单的id和名称。

    在类的调用函数里面使用Spider类,该类可协调webmegic的四个组件工作,使用Spider.create(new HotPlayListsCrawler())创建爬取热门歌单id的爬虫,在爬取时应该有一个种子页面地址,种子页面通过Spider.add()添加到爬虫请求。使用Sipder.run()便可以启动该爬虫。

    爬取时将所有的页面请求通过webmegic框架里面的page.addTargetRequest(“目标地址”)加入。

    HotPlaylistCrawler通过正则表达式,css等工具将页面的数据进行解析,并且将解析的结果通过page.putField(“关键字”,“信息”)传出。

    HotPlaylistCrawler类里面可以定制一个Site对象,用于设置请求参数。

    此外Spider类提供设置代理和添加线程的快捷方法。

    建立实体类HotPlaylistInfo,该类里面有两个变量一个用于保存歌单id号,一个用于保存歌单名称。

    建立实现Pipeline接口的HotPlaylistPipeline类,在默认情况下,爬虫类传送的信息会送到控制台Pipeline,而后直接由控制台输出。由于我需要保存到数据库所以需要定制保存到数据库的HotPlaylistPipeline类,Pipeline类的接口process方法里面有一个参数ResultItems resultItems,此ResultItems类相当于一个Map型的工具,可以通过关键字来获取内容。

    HotPlaylistPipeline类新建一个HotPlaylistInfo对象,接受关于此对象的信息之后给对象里面的变量赋值,最后调用HotPlaylistTable里面的.add()静态方法将对象放入数据库存起来。

    建立实现数据操作的HotPlaylistTable类,在该类里面添加数据库驱动,并且写上操作mysql数据库的语句:"INSERT INTO hot_playlist (id,name) VALUES (?,?)",实现向数据库里面添加一行数据,这个功能主要是statement工具类来完成,在插入数据后需要执行executeUpdate()进行数据库的更新。

    2.以上述基本流程建立其他的类

    建立爬取歌单详情页面的类PlaylistCrawler类爬取歌单的播放量,创建者,里面包含的歌曲id和名称等,对应创建接受信息的PlaylistPipeline类,实体信息playlistInfo类,操纵歌单表的类PlaylistTable。

    建立爬取歌曲详情页面的类SongCrawlerl类爬取歌曲的歌手,id,名称等,对应创建接受信息的SongPipeline类,实体信息SongInfo类,操纵歌曲表的类SongTable。

    建立爬取歌曲评论信息页面的类CommentCrawler,获取歌曲的评论信息,包括评论数量,top6条热评用户的id,姓名,获得的赞等。对应建立接受信息的CommentPipeline类,实体类和操纵数据库的类与SongCrawler共享。

    建立爬取用户信息页面的类UserInfoCrawler,爬取用户的id,姓名,年龄,地区,个签,用户等级,VIP等级,听歌量,注册时间等信息,对应建立的接受信息的类为UserInfoPipeline,实体类UserInfo,操纵用户表的类UserTable。

    3.完善爬虫过程

    添加去西刺网爬取代理的爬虫类,抓取代理ip地址和端口保存到数据库,在获取网易云网页前采用代理ip,防止因为请求全网页的频率过高被封ip。

    将数据驱动所需要的数据封装在一个工具类ConnectionInfo里面,其他类由该类获取信息。这样做的好处是一旦数据库信息发生变更只需要修改一处代码即可。

    建立去重类NoDuplicateSongs和NoDuplicateUsers,这两个类用于检查待爬取的目标是否在程序上次联网已经爬取并保存数据到数据库。这么做的主要原因是待爬取的页面数量众多,程序在爬取的过程中可能会发生异常而导致无法一次性爬完所有的请求地址,所以程序需要保证可以从程序上次请求中断的页面开始请求。

    4.建立其他工具类

    TimeStampToDate类,此类用于将在页面获取的时间戳转换为正常的日期。

    CityCodeCrawler类和CityCode类用于根据编码获取正确的城市,原因是在爬取用户信息的时候,得到的地区数据是编码,为了匹配城市存储到数据库,本程序先爬取了国家民政部城市编码公示网页,获取了编码和城市后,可以由编码获得城市名称。

    5.协调工作

    不同爬虫入口类和去重类的使用顺序都由WangyiyunCrawler类来控制,此类的工作是分发工作任务。

    步骤2: 分析数据

    1.建立fineBI和本地MySQL数据库的连接,在fineBI里面建立与数据库里面对应的表

    2.根据不同的数据分析,选用不用的维度、指标和图标样式,实现数据的可视化。下面是步骤,得出的表

    (1)在FineBI建立与mysql里面歌单信息表对应的表,对热门歌单按播放量进行排序,选用维度为歌单名称,选用的指标是播放量。

    (3)对比热门歌单的播放量和里面包含的歌曲数量,选取的图表样式是柱形图,其中横坐标是播放量和歌曲量两个指标。歌单的名称按播放量,大小排序。

    (4)在FineBI建立与mysql歌曲信息表对应的表,建立二维图形表统计得到评论最多的歌曲,横轴为歌曲名,纵轴是歌曲的评论数量。歌曲的名称按歌曲评论的数量倒序排序。

    (5)从歌曲表里面获取歌手和评论,统计平均每首歌曲的评论数量在10万以上的歌手,图表采用饼状图。

    (6)从歌曲表获取里面评论得赞的个数,统计得赞在50万以上和在100万以上的评论,利用FineBI生成词云。

    (7)在FineBI建立与mysql热评人信息表对应的表。分别以年龄,地区,性别等为约束条件,生成不同颜色的气泡图。

    (8)生成部分热评人的个人介绍,约束不同的粉丝个数,查看不同的个签。

    设计结果及分析

    歌单的播放量排行榜图,以及歌单的播放量与其包含的歌曲量对比图。排行榜前二的歌单“精选|网络热歌分享”和“2018年度最热新歌top100”的播放量远超其他歌单,他们包含的歌曲都没有超过100首,因此里面歌曲的歌曲的百分比应该是比较高的,在下面的表格中,不难发现,排名靠前的热门歌单名称多含有“热”,“新”,“好听”等关键词,并且热门歌单的歌曲数量在0-200首的居多。

    热门歌单的创建时间都在近几年(下面是歌单的创建日期升序排列)这说明最近用户歌曲欣赏标准同两年前的标准有所不同。

    评论数排行靠前的歌曲分析,下面列出一些单曲评论数极高的歌曲,其中许嵩的歌曲雅俗共赏以绝对优势获取榜单第一

    下图为评论数量top9歌曲榜,右边是演唱的歌手

    根据评论数据,得到推荐音乐榜单,下图展示部分榜单

    平均每首歌曲评论数在10万以上的歌手统计,分析他们都为实力较强的歌手,他们的歌曲值得推荐

    点赞量在50万以上的热评词云部分展示,可以看到评论都是比较有趣,抒情或者比较正能量的内容。一定程度上反应了大部分人的价值取向是有趣,善良,上进的。

    点赞量在100万以上的热评词云,一共三条内容,刚好反映了用户对自己的希望,对他人的照顾,对民族的自豪的情感。

    排除没有填写信息后热评用户后,得到用户的地区分布图,可以看到热评用户最多的城市是东城区,黄埔市,成都市,广州市,武汉市以及深圳市。

    分析热评用户的性别比例,除去没有填写信息的用户,在该图表中可以明显的看到热评人中男性占比比女性占比高,这可能与我国的男女比例有一定的关系。

    热评用户的年龄分布,其中热评获赞最多的基本上是95年出生的人,其余多是90后和2000年出生的用户,这个数据很可能与网易云音乐的受众有关。结合上面的地区分布图分析可知,热评用户所在地区多是发展较好的城市,很多都在北上广一带的经济带,可能正是这些用户工作和学习的地方。

    热评用户的个人介绍获取,这里截取了一张粉丝数量在5000到15000之间用户的个人介绍,

    如果提高粉丝量的话,截取到的用户基本上是音乐人,比较符合歌迷给歌手点赞而导致歌手评论得赞比较多的现实。下面一图是粉丝数降序排列的部分热评人信息。可以看到,个人介绍里面多是音乐人的联系方式。

    问题及心得体会

    1.在自己实际开发中遇到了不少问题,分别如下

    只会用工具得到网页源码,解析和分离有效数据困难

    解决办法:分离数据的时候,使用到了多种分离匹配工具,比如说正则表达式或者Jsoup等,因此应该学习相关知识,并且在实际解析中根据不同的数据需求可以将他们叠加使用。除此之外,一些方便的工具类的使用比如Elements类和Element类,List类和ArrayList类等,可将分离数据和传输数据变得简单起来。

    在爬取过多数据的时候被封ip,西刺网站上提供的免费ip代理可用率很低,如何设置代理ip成为问题

    解决办法:在获取到西刺网的代理ip信息后,不能立马存入数据库,应当对ip的可用性进行检查,使用每一个代理ip去请求网易云主页,能够请求成功的ip存入数据库表,不能成功的则舍弃,程序每次启动时应当先开始爬取代理ip,搭建代理ip池,这样可在爬取信息的过程中使用多线程爬取,获取信息的效率显著提高。

    在使用网易云在浏览器里面打开歌单的网页地址例如地/#/playlist?id请求数据时,得到的数据永远是网易云主页的数据。

    解决办法:观察得到的源码,上面有注释把所有的‘#’换成‘m’,在使用新地址 /m/playlist?id爬虫程序便可正常访问歌单页面。

    歌曲评论信息是js渲染的异步页面,并且经过加密,获取评论信息成为难题。

    解决办法:网上有许多解密的过程,但是由于个人能力的原因,几乎看不懂这些解密加密的算法,但是在寻找解决方法时找到了网易云获取评论信息的一个api接口: /api/v1/resource/comments/R_SO_4_516997458?limit=20&offset=40使用该接口获取的信息可以得到未经加密的评论详情。

    歌曲信息的获取和歌曲评论的获取不在同一个页面,歌曲信息页面

    没有歌曲的评论信息,而歌曲评论页面没有歌曲的id,名字等。

    解决办法:每首歌曲页面爬取两次,先爬一次基础页面保存id,名字和歌手,剩余的信息在爬取完评论信息后补充进歌曲信息表。

    爬取过程中突然中断后如何从上次爬取的位置开始运行

    解决办法:主要是HashSet的使用,例如爬取几万首歌曲时,首先从已经存在数据库歌曲表里面数据得到所有歌曲的id,并且把它们放入一个HashSet对象里面,然后从所有歌单里面提取歌曲id号,判断是否能够添加进hashSet对象,由于hashSet的特性,里面不会有重复的内容,所以一旦添加成功即说明这首歌并没有被爬取,应该把它放进待爬取的队列,最后得到的数据就是没有爬取过的内容。同样的方法可以对歌单,用户信息等进行上述过程的处理。

    网页的时间表达有时候不是生活中常见的日期表达,它采用时间戳格

    式,而且java里面的date类型和mysql里面的date类型不匹配。

    解决办法:在工具类里面将时间戳类型转换为日期类型,并且保存为字符串数据库保存的时候新建一个mysql里面的date类型的对象,用字符串初始化这个对象,将该对象的值保存到数据库即可。

    请求网页获取城市时只得到一串数字

    解决办法:网页在标志城市的时候很多时候不是采用文本,而是编号,查询可知每个编号对应一个城市的名称,所以在爬取用户信息之前需要对城市编码进行爬取,并且使用Map和HashMap工具,将编码(作为关键字)和城市(作为值)名称匹配起来,如此便可以方便地通过编码来查询城市名称。

    如何进行数据可视化

    解决办法:数据可视化的软件很多,有不少的软件需要使用编程语言来操作,这对于短时间内实现可视化的人来说并不是好的选择,思忖再三后我选择了FineBI这款对个人开放免费使用的软件,免去了编程语言的使用,操作比较友好,可供选择的图表也比较多。

    心得体会

    本次程序设计的内容与平时的编程作业有很大的差异,爬虫需要的一些知识是没有学过的,在开始设计这个项目的时候我只知道想要爬取的方向是什么,对于如何实现这个和过程一无所知,好在当今的网络发达,资源也比较丰富,遇到不会的事情,上网查询便可以得到不少有用的信息。

    最初的程序爬虫我没有使用爬虫架构webmegic,而是使用了httpclient,但是在开发程序的过程中,看了一篇webmegic架构爬虫的例子,觉得比较方便,便开始着手使用webmegic来爬取信息。有了这个框架,我可以方便的使用线程,添加请求,使用代理,传送数据等,Webmegic的逻辑性使得程序很好地被分块成各类

    在解析页面的时候,有很多匹配工具使用的不熟练,有些匹配需求的实现需要上网查询匹配方法。

    即使有些网站做了一些加密技术,但是由在网上查询资料时查到的一些数据解密的教程来看,网页上的信息并不安全,甚至有一些接口可以方便地获取到没有加密的数据,在今后保存信息到一些网站时也应该注意到这一点,很可能信息就会泄露。

    选取感兴趣的网站爬取很重要,爬取过程遇到的困难很多,主要是如何实现获取异步页面,解析所得数据的方面,但是因为有兴趣,遇到困难能够静下心来仔细查询相关资料,最后问题也解决得比较好。

    总之这次的程序设计收获颇丰,锻炼的自己的编程能力,最后的得到的数据结果也是令自己满意的。

    参考文献

    Webmegic中文文档:

    http://webmagic.io/docs/zh/

    网络爬虫的概念: /wiki/%E7%B6%B2%E8%B7%AF%E7%88%AC%E8%9F%B2

    正则表达式教程:

    /regexp/regexp-syntax.html

    有关的专题