自己喜欢在上班的途中听点有声书,所以经常在喜马拉雅上找资源,要找到一个好听的节目不容易,虽然在喜马拉雅官网上可以按分类来看,但是却不能按点赞数或者评论内容排序找,不是很方便,于是就用Python写了个爬虫,把所有声音的相关信息、评论内容都抓取下来,然后放到数据库来分析,这样喜欢什么样的资源,直接根据声音或评论的内容来汇总分析,结果就一目了然了。
流程实现图
Urllib,request, selenium
Web的访问使用urllib和urllib2,相比request、selenium来说,效率更高些,感觉也稳定些,之前使用request的遇到https的网址处理起来有点问题。而selenium呢,自动化操作可以不用分析具体页面的处理逻辑,不过对于这种海量数据,处理起来速度就会慢很多。
多线程和队列
使用了2个threading.Thread的继承类,Ximalaya类用来解析声音专辑,分析提取专辑内的声音信息,解析出评论地址;CommentDown类专门用来提取保存评论内容信息;一般一个声音会有多条评论,多的上千条评论,所以CommentDown分配了10个线程来提取评论,Ximalaya分配了3个线程来分析专辑的声音信息。
使用了2个队列,1个用来保存专辑url,大小100,1个用来保存评论url,大小设置为200;这样在超过队列最大值的时候就会停下来,等待前面队列里处理了再继续,可以有效控制整个爬虫速度,以免访问太过频繁被网站给屏蔽了。
数据保存
使用了Mongodb数据库,Nosql处理高并发的,相比SQL速度和效率要高得多。Mongodb里在music下保存声音的相关信息(比如声音的专辑名、专辑地址、声音的地址、声音的时长、点赞数等等),bookcomment下保存声音的评论内容。
断点续传、重复处理
遇到中途中断后要继续执行,还得考虑下断点续传,这里处理得比较简单粗暴,在Ximalaya处理声音的时候,会先判断数据库是否有声音的地址,如果存在就是跳过不再处理,在CommentDown处理评论的时候,判断判断数据库是否有声音的地址,如果存在就是跳过不再处理,这样对于后面比较费时处理部分都可以直接跳过,也不会存在有重复的数据会影响最后的分析的问题。
异常处理
程序在解析页面的时候,可能会有超时之类的异常情况,增加了对应的异常处理,socket.setdefaulttimeout(20)设置全局超时为20秒,超过20秒就会超时报错,这样再通过异常捕获来处理,设置了异常处理记数器,对于异常页面重复处理指定次数后不再处理,避免部分声音页面被删除一直访问异常的情况。
数据分析
最后对保存到数据库的数据进行分析,做分析的时候Nosql做关联分析太痛苦了,完全不如sql查询方便,于是把数据导入到Oracle来进行的分析,根据评论内容中的关键字来标识判断(例如:“点赞”,“好听”,“太棒“之类的都判断成受欢迎),最后再用汇总统计出结果。
评论最受欢迎的TOP20有声书:
评论最受欢迎的TOP10综艺节目:
评论最受欢迎的TOP20音乐:
评论普通话说得最好的节目:
最后源代码也附上了,有兴趣的朋友可以自己看看: