本工具可以查看你和她在网易云上喜欢音乐的重合率,以及哪些歌是你们都喜欢的。

起因

在某首歌的评论里看到说想要网易云提供一个这种功能?仔细一想,其实获取到歌单后做一个简单的计算重合率的应该还是挺简单的。一方面想试试简单的爬取两个界面,另外一方面想利用下自己的服务器。经过几天时间,虽说初步实现了,但是……后面会详细说遇到的问题。

如何使用

可以直接关注我公众号:BrainZou 或者 扫描下方的二维码关注

公众号界面底部菜单有个“小工具”菜单 > “网易云歌单重合率” 子菜单

实现功能

功能实现分为三步:

  1. 得根据歌单id获取到歌单内的歌名列表,即哪些歌。

  2. 根据用户名获取到每个用户都有的那个喜欢的歌单,再通过第一步获取到歌名,即哪个用户。

  3. 部署到网络,用户自己输入用户名,自动返回结果。

获取歌名列表

爬取比如发姐的歌单: http://music.163.com/playlist?id=17281445。注意比网页显示的少了一个#号。

用BeautifulSoup处理,先得到Class名叫‘f-hide’的ul,再在ul下找到所以a标签的文本。得到这部分歌名存储在列表里,部分代码如下:

#link1是链接,header是构造的s1 = requests.session()s1 = BeautifulSoup(s1.get(link1,headers=headers).content,'lxml')main = s1.find('ul', {'class': 'f-hide'})for music in main.find_all('a'):lists1.append(music.text)

照这个方法,再获取到另外一个歌名列表,再来处理,计算重合率。相关代码如下:

#用到了正则,是用来替换叼Unicode前的U替换为<br>一是为了转换编码显示,二是为了后面换行显示歌名。
#decode('unicode-escape')也是为了显示,将unicode编码解码。
myset1 = set(lists1)
myset2 = set(lists2)
pattern = re.compile('\Wu\'')
intersectionset = re.sub(pattern,'<br>\'',str(myset1 & myset2))
length = len(myset1 | myset2)
print intersectionset
return(u"你们的歌单重合率为:%f%%<br><br>重复歌曲共%d首
如下:%s"%(len(myset1 & myset2)*100/length,len(myset1&myset2),intersectionset.decode('unicode-escape')))

根据用户名获取到歌单链接

先提下歌单是有一个id对应的,用户也有一个userid对应。
前面我们看到http://music.163.com/playlist?id=17281445歌单就是带唯一id,前面都是固定的,那么这个如何获取?可以先通过爬网易云的搜索界面获取到该用户id,及主页。爬主页即可得到这个歌单的连接了。
发现是js加载的,没找到合适的方法,所以用的是PhantomJS和selenium加载。
注意下构造的搜索网页。s是搜索的内容,type=1002表示搜索用户。

def get_playlist_by_name(username):#指定contentFrame 获取"ttc"class,再获取"a"tag,最后获取到用户主页链接,图见搜索界面图。#quote转码中文try:driver = webdriver.PhantomJS(executable_path="/usr/local/phantomjs/bin/phantomjs")driver.get('http://music.163.com/#/search/m/?s={}&type=1002'.format(quote(username.encode('utf8'))))#WebDriverWait(driver, 5, 0.3).until(EC.presence_of_element_located(locatorttc))driver.switch_to.frame("contentFrame")sleep(1)tr = driver.find_element_by_class_name('ttc')user = tr.find_element_by_tag_name('a')#加载用户主页 获取到私人最喜欢的歌单的链接并返回,图见下方的用户主页图。driver.get(user.get_attribute('href'))#WebDriverWait(driver, 5, 0.3).until(EC.presence_of_element_located(locatordec))driver.switch_to.frame("contentFrame")sleep(1)dec = driver.find_element_by_class_name('dec')#print(dec.page_source)playlist = dec.find_element_by_tag_name('a')return playlist.get_attribute('href')except Exception as e:print ereturn ""finally:driver.close()

部署到网络

80端口在我的服务器上已经被使用了,我也不想在链接上加上端口号,所以需要先在nginx进行配置,将子域名的80端口转到服务器的8081端口。

server {listen       80;server_name  api.brainzou.com;location / {proxy_pass   http://xxx.xxx.xxx.xxx:8081/;}location /buy {proxy_pass   http://xxx.xxx.xxx.xxx:8081/;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}

然后看真正的部署网络的部分,这里用的是web.py,是在官方的简单的form的例子下修改的。通过获取到form里的值传递到get_playlist_by_name方法。最后把数据返回。

# -*- coding: utf-8 -*-
# filename: main.py
import web
from web import form
import Music163RepetitiveRate
render = web.template.render('templates/')
urls = ('/music163', 'index')
app = web.application(urls, globals())myform = form.Form(form.Textbox("fname",form.notnull, description=u"用户名1"),form.Textbox("sname",form.notnull, description=u"用户名2"))
class index:def GET(self):web.header('Content-Type','text/html;charset=UTF-8')form = myform()print(form.render())return render.formtest(form)def POST(self):web.header('Content-Type','text/html;charset=UTF-8')form = myform()if not form.validates():print(form.render())return render.formtest(form)else:print "begin"playlist1=Music163RepetitiveRate.get_playlist_by_name(form.d.fname)print playlist1playlist2=Music163RepetitiveRate.get_playlist_by_name(form.d.sname)print playlist2content = Music163RepetitiveRate.repetitive_rate_by_playlistlink(playlist1,playlist2)return content
if __name__ == "__main__":web.config.debug = Falseweb.internalerror = web.debugerrorapp.run()

然后fortest.xml放置到templates下。

$def with (form)
<div class="center">
<form name="main" method="post">
$if not form.valid: <p class="error">请重试!</p>
$:form.render()
<input class="input"type="submit" />
</form>
<a>提交后,大概需要20s来取歌单数据和分析,请耐心等待!</a>
<div>
<style>
.center {width:500px;height: 500px;position: absolute;left:50%;top:50%;margin-left:-100px;margin-top:-100px;
}
.input{width:100px;margin-left:100px;
}
</style>  

最后,手动指明python使用utf-8编码。后台运行加上指明端口8081。记得服务器开放8081端口。

遇到的问题

  1. PhantomJS用完没有关闭,导致后面很多不可描述的问题。

  2. 编码问题。可以再详细的上去看下,有很多地方,从get post,到set返回。
    甚至最后后台运行main.py都需要先指明utf-8,而直接python main.py 8081却不用( 因为Python 2 的默认编码就是 ASCII,在正常情况下,Python 2 在 print unicode 时用来转换的编码并不是 Python 的默认编码sys.getdefaultencoding(),而是 sys.stdout.encoding 所设的编码)。

3.服务器(我的是在腾讯)上需要开放8081端口,默认是没开启的。然后要关闭防火墙。

  1. 一开始想直接接入微信公众号的消息接口,直到全部接入完后才发现很难得到数据,才发现需要5s内返回消息给微信接口,否则需要使用客服接口异步返回数据,但是是个人的公众号不能接入客服,于是放弃。改为网页形式。

5.音乐数目过多比如1000-2000条,通常情况下重合率是相对更低的,想从算法上提高一些,但是暂时没有想到什么好的算法。

使用

个人对比多次,发现10%左右就比较高了,而且歌单里音乐数目越多,一般这个重合率都偏低。

微信公众号:BrainZou
欢迎关注,一起学习。
回复“资料”,有本人精心收集的Python,Java,Android,小程序,后端,算法等等近1T的网盘资源免费分享给你。

想知道你和她在网易云喜欢的音乐的重合率?相关推荐

  1. 中国有嘻哈:网易云、虾米音乐歌词爬虫项目分享

    <中国有嘻哈>这款综艺带火了中国的嘻哈音乐,大家问好也都变成了:你有freestyle吗? 相信大家都是因为这篇高大上的微信推送文章来的. 没看到也不要紧,传送带在这里–>爱票子也爱 ...

  2. 怎么在网易云或者QQ音乐上上传自己翻唱的歌

    假期无聊,在全民K歌上唱了几首歌,有朋友想下载来听,我就找了一下怎么将翻唱的歌曲上传到网易云或者QQ音乐.就弄了一下,发现目前只能做到自己听,其他人搜索不到(可以直接把音频发给其他人下载保存)看看以后 ...

  3. 网易云与QQ音乐共享了99%乐库,那么这个工具解决剩下的百分之一--SDMUSIC(开源命令行音乐搜索下载软件)...

    4-17 修复qq音乐平台无法下载的BUG 4-15 修改了部分BUG,美化了结果输出.非常感谢raawaa. 新增(3-5) 批量下载UK榜,美国Billboard周榜,Beatport全球电子舞曲 ...

  4. 仿网易云网页版音乐播放器,实现歌词随歌曲进行滚动高亮

    引言 前几天在使用网易云网页版听歌时,看着那个页面的歌词随歌曲进行高亮,突然也想自己手动地去实现一下,于是呢,就仿照了网易云音乐的网页自己也写了个页面.效果图如下: 当然了,此处不做css的样式介绍, ...

  5. 网易云,QQ音乐,Apple music 网页端下载音乐方法摸索

    下载付费音乐必须是会员 一.网易云音乐 二 . QQ音乐 然后呢,跟网易云一样,只不过双击后不会弹出下载框,而是跳转到新的标签页 三 . Apple music 经过尝试之后,最终结论就是  不可能, ...

  6. 网易云10万+音乐竟然能用Python一键下载!

    如果你常听音乐的话,肯定绕不开网易云,作为一款有情怀的音乐 App,我对网易云也是喜爱有加.虽然说现在都已经是 5G 时代了,大家的手机流量都绰绰有余,但在线播放还是不如本地存着音乐文件靠谱,今天我们 ...

  7. Java爬虫——爬取网易云歌单音乐添加到QQ音乐

    此博客仅为学习交流,如触及第三方利益,请及时联系本人删除 一.前言 看标题大家可能会有点疑惑,为什么要写这个看起来没什么作用的爬虫,两个音乐软件换着用不香吗?     基于此问题,我以我个人感受罗列了 ...

  8. 网易云助力云音乐短视频功能快速上线

    和传统的内容创业模式相比,短视频的直观性.软性植入.内容灵活.互动性高以及更加丰富多元化的营销服务,吸引了很多人投身.除此之外,短视频往往依托于网红而诞生.网红自身所带有的高转化率.低成本和强大的粉丝 ...

  9. 虾米播播音乐墙html,WordPress音乐播放器插件Hermit X(支持网易云、QQ音乐、虾米等)...

    Hermit X,使用 APlayer 前端播放器,Meting Framework & LWL API 后端支持的全新 WordPress 播放器 现已问世! 特性 支持直接调用网易云音乐. ...

  10. java电脑桌面网易云界面,Javafx音乐播放器

    Javafx音乐播放器 介绍 这是款由纯java语言开发的在线音乐播放器,当然也支持播放本地的音乐,在本地音乐模块主要采用目前java最主流的音频标记库Jaudiotagger,可解析MP3文件头信息 ...

最新文章

  1. pandas使用pad函数向dataframe特定数据列的每个字符串添加后置(后缀)补齐字符或者字符串、向所有字符串的右侧填充、直到宽度达到指定要求(right padding)
  2. 分享Windows Vista Beta1下载
  3. LVS峰会 | 阿里云李刚:下一代低延时的直播CDN
  4. python学习笔记四一列表元组字典等
  5. Leetcode--141. 环形链表
  6. 日常 Python 编程优雅之道
  7. ./mysql-bin.index_MySQL 启动报错:File ./mysql-bin.index not found (Errcode: 13)
  8. C/C++网络编程工作笔记0002---网络编程流程
  9. Jquery------三种选择器(基本选择器、过滤选择器、表单过滤选择器)
  10. 关于java的回调方法
  11. telnet怎么算成功_有机肥发酵剂有的作用,怎么才算发酵成功?
  12. 李宏毅机器学习——深度学习入门
  13. mysql 6.17,mysql小结篇2(17.6.27)
  14. 人工智能的未来-揭示人类思维的奥秘How to create a mind - Ray Kurzweil
  15. 【移动开发趋势】2022 年移动应用程序开发的主要趋势
  16. Django models Fild详解
  17. 自动生成小程序的智能建站系统,项目分享
  18. vue实现用户登录验证 + 权限验证 + 动态路由(左侧菜单栏)
  19. 文科类文献综述怎么写?
  20. 幸福婚姻和睦家庭秘籍---包容与感恩

热门文章

  1. 408计算机组成原理学习笔记——存储系统
  2. /etc/mtab 文件
  3. 编译一个java源程序文件,会产生多少个字节码文件
  4. 软工中级实训——实训总结报告
  5. 绘制中国象棋棋盘 - CSS Pseudo Elements 的使用
  6. 教学设计-饭后百步走
  7. 传奇服务器脚本文件在哪个文件夹,传奇服务端目录文件详细说明
  8. js获取明天的年月日和计时器
  9. vue 通过 Ctrl 、Shift 键 + 点击鼠标实现 div 多选操作
  10. 老九学堂 学习 C++