想知道你和她在网易云喜欢的音乐的重合率?
本工具可以查看你和她在网易云上喜欢音乐的重合率,以及哪些歌是你们都喜欢的。
起因
在某首歌的评论里看到说想要网易云提供一个这种功能?仔细一想,其实获取到歌单后做一个简单的计算重合率的应该还是挺简单的。一方面想试试简单的爬取两个界面,另外一方面想利用下自己的服务器。经过几天时间,虽说初步实现了,但是……后面会详细说遇到的问题。
如何使用
可以直接关注我公众号:BrainZou 或者 扫描下方的二维码关注
公众号界面底部菜单有个“小工具”菜单 > “网易云歌单重合率” 子菜单
实现功能
功能实现分为三步:
得根据歌单id获取到歌单内的歌名列表,即哪些歌。
根据用户名获取到每个用户都有的那个喜欢的歌单,再通过第一步获取到歌名,即哪个用户。
部署到网络,用户自己输入用户名,自动返回结果。
获取歌名列表
爬取比如发姐的歌单: 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端口。
遇到的问题
PhantomJS用完没有关闭,导致后面很多不可描述的问题。
编码问题。可以再详细的上去看下,有很多地方,从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端口,默认是没开启的。然后要关闭防火墙。
- 一开始想直接接入微信公众号的消息接口,直到全部接入完后才发现很难得到数据,才发现需要5s内返回消息给微信接口,否则需要使用客服接口异步返回数据,但是是个人的公众号不能接入客服,于是放弃。改为网页形式。
5.音乐数目过多比如1000-2000条,通常情况下重合率是相对更低的,想从算法上提高一些,但是暂时没有想到什么好的算法。
使用
个人对比多次,发现10%左右就比较高了,而且歌单里音乐数目越多,一般这个重合率都偏低。
微信公众号:BrainZou
欢迎关注,一起学习。
回复“资料”,有本人精心收集的Python,Java,Android,小程序,后端,算法等等近1T的网盘资源免费分享给你。
想知道你和她在网易云喜欢的音乐的重合率?相关推荐
- 中国有嘻哈:网易云、虾米音乐歌词爬虫项目分享
<中国有嘻哈>这款综艺带火了中国的嘻哈音乐,大家问好也都变成了:你有freestyle吗? 相信大家都是因为这篇高大上的微信推送文章来的. 没看到也不要紧,传送带在这里–>爱票子也爱 ...
- 怎么在网易云或者QQ音乐上上传自己翻唱的歌
假期无聊,在全民K歌上唱了几首歌,有朋友想下载来听,我就找了一下怎么将翻唱的歌曲上传到网易云或者QQ音乐.就弄了一下,发现目前只能做到自己听,其他人搜索不到(可以直接把音频发给其他人下载保存)看看以后 ...
- 网易云与QQ音乐共享了99%乐库,那么这个工具解决剩下的百分之一--SDMUSIC(开源命令行音乐搜索下载软件)...
4-17 修复qq音乐平台无法下载的BUG 4-15 修改了部分BUG,美化了结果输出.非常感谢raawaa. 新增(3-5) 批量下载UK榜,美国Billboard周榜,Beatport全球电子舞曲 ...
- 仿网易云网页版音乐播放器,实现歌词随歌曲进行滚动高亮
引言 前几天在使用网易云网页版听歌时,看着那个页面的歌词随歌曲进行高亮,突然也想自己手动地去实现一下,于是呢,就仿照了网易云音乐的网页自己也写了个页面.效果图如下: 当然了,此处不做css的样式介绍, ...
- 网易云,QQ音乐,Apple music 网页端下载音乐方法摸索
下载付费音乐必须是会员 一.网易云音乐 二 . QQ音乐 然后呢,跟网易云一样,只不过双击后不会弹出下载框,而是跳转到新的标签页 三 . Apple music 经过尝试之后,最终结论就是 不可能, ...
- 网易云10万+音乐竟然能用Python一键下载!
如果你常听音乐的话,肯定绕不开网易云,作为一款有情怀的音乐 App,我对网易云也是喜爱有加.虽然说现在都已经是 5G 时代了,大家的手机流量都绰绰有余,但在线播放还是不如本地存着音乐文件靠谱,今天我们 ...
- Java爬虫——爬取网易云歌单音乐添加到QQ音乐
此博客仅为学习交流,如触及第三方利益,请及时联系本人删除 一.前言 看标题大家可能会有点疑惑,为什么要写这个看起来没什么作用的爬虫,两个音乐软件换着用不香吗? 基于此问题,我以我个人感受罗列了 ...
- 网易云助力云音乐短视频功能快速上线
和传统的内容创业模式相比,短视频的直观性.软性植入.内容灵活.互动性高以及更加丰富多元化的营销服务,吸引了很多人投身.除此之外,短视频往往依托于网红而诞生.网红自身所带有的高转化率.低成本和强大的粉丝 ...
- 虾米播播音乐墙html,WordPress音乐播放器插件Hermit X(支持网易云、QQ音乐、虾米等)...
Hermit X,使用 APlayer 前端播放器,Meting Framework & LWL API 后端支持的全新 WordPress 播放器 现已问世! 特性 支持直接调用网易云音乐. ...
- java电脑桌面网易云界面,Javafx音乐播放器
Javafx音乐播放器 介绍 这是款由纯java语言开发的在线音乐播放器,当然也支持播放本地的音乐,在本地音乐模块主要采用目前java最主流的音频标记库Jaudiotagger,可解析MP3文件头信息 ...
最新文章
- pandas使用pad函数向dataframe特定数据列的每个字符串添加后置(后缀)补齐字符或者字符串、向所有字符串的右侧填充、直到宽度达到指定要求(right padding)
- 分享Windows Vista Beta1下载
- LVS峰会 | 阿里云李刚:下一代低延时的直播CDN
- python学习笔记四一列表元组字典等
- Leetcode--141. 环形链表
- 日常 Python 编程优雅之道
- ./mysql-bin.index_MySQL 启动报错:File ./mysql-bin.index not found (Errcode: 13)
- C/C++网络编程工作笔记0002---网络编程流程
- Jquery------三种选择器(基本选择器、过滤选择器、表单过滤选择器)
- 关于java的回调方法
- telnet怎么算成功_有机肥发酵剂有的作用,怎么才算发酵成功?
- 李宏毅机器学习——深度学习入门
- mysql 6.17,mysql小结篇2(17.6.27)
- 人工智能的未来-揭示人类思维的奥秘How to create a mind - Ray Kurzweil
- 【移动开发趋势】2022 年移动应用程序开发的主要趋势
- Django models Fild详解
- 自动生成小程序的智能建站系统,项目分享
- vue实现用户登录验证 + 权限验证 + 动态路由(左侧菜单栏)
- 文科类文献综述怎么写?
- 幸福婚姻和睦家庭秘籍---包容与感恩