├── README.md ├── ScreenShot ├── Screen Shot 2017-03-23 at 9.33.53 PM.jpg └── Screen Shot 2017-03-23 at 9.35.42 PM.jpg ├── compare.py └── compare2.py /README.md: -------------------------------------------------------------------------------- 1 | # NeteaseMusic 2 | 3 | # 此项目不再更新, 抱歉 4 | 5 | ## 用户歌单碰撞 6 | 7 | 8 | ### 用法 9 | 10 | * python compare.py #获取单用户听歌top100榜单 11 | * python compare.py -ai #俩用户歌单对比 12 | 13 | ### 环境 14 | 15 | > macOS / python2.7 16 | 17 | ### Requirements 18 | 19 | * requests 20 | * bs4 21 | * selenium 22 | * gb2260 23 | 24 | 25 | ![歌单对比](https://raw.githubusercontent.com/mashaz/NeteaseMusic/master/ScreenShot/Screen%20Shot%202017-03-23%20at%209.33.53%20PM.jpg) 26 | 27 | ![top100](https://raw.githubusercontent.com/mashaz/NeteaseMusic/master/ScreenShot/Screen%20Shot%202017-03-23%20at%209.35.42%20PM.jpg) -------------------------------------------------------------------------------- /ScreenShot/Screen Shot 2017-03-23 at 9.33.53 PM.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mashaz/NeteaseMusic/8af6361e14da1d277fe5541ccf57cd0c486fe9d3/ScreenShot/Screen Shot 2017-03-23 at 9.33.53 PM.jpg -------------------------------------------------------------------------------- /ScreenShot/Screen Shot 2017-03-23 at 9.35.42 PM.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mashaz/NeteaseMusic/8af6361e14da1d277fe5541ccf57cd0c486fe9d3/ScreenShot/Screen Shot 2017-03-23 at 9.35.42 PM.jpg -------------------------------------------------------------------------------- /compare.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | #!/usr/bin/env python 3 | 4 | __auther__ = 'xiaohuahu94@gmail.com' 5 | 6 | ''' 7 | todo 8 | 在所有歌单对比中加入用户top100的对比 9 | ''' 10 | 11 | import requests 12 | import re 13 | import os 14 | import sys 15 | import time 16 | import random 17 | import json 18 | import gb2260 19 | from bs4 import BeautifulSoup 20 | from collections import Counter 21 | from selenium import webdriver 22 | from selenium.webdriver.common.by import By 23 | 24 | global wname 25 | global tname 26 | 27 | reload(sys) 28 | sys.setdefaultencoding('utf-8') # note 29 | requests.adapters.DEFAULT_RETRIES = 5 30 | 31 | STYLE = { 32 | 'fore': 33 | { # 前景色 34 | 'black' : 30, # 黑色 35 | 'red' : 31, # 红色 36 | 'green' : 32, # 绿色 37 | 'yellow' : 33, # 黄色 38 | 'blue' : 34, # 蓝色 39 | 'purple' : 35, # 紫红色 40 | 'cyan' : 36, # 青蓝色 41 | 'white' : 37, # 白色 42 | }, 43 | 'back' : 44 | { # 背景 45 | 'black' : 40, # 黑色 46 | 'red' : 41, # 红色 47 | 'green' : 42, # 绿色 48 | 'yellow' : 43, # 黄色 49 | 'blue' : 44, # 蓝色 50 | 'purple' : 45, # 紫红色 51 | 'cyan' : 46, # 青蓝色 52 | 'white' : 47, # 白色 53 | }, 54 | 'mode' : 55 | { # 显示模式 56 | 'mormal' : 0, # 终端默认设置 57 | 'bold' : 1, # 高亮显示 58 | 'underline' : 4, # 使用下划线 59 | 'blink' : 5, # 闪烁 60 | 'invert' : 7, # 反白显示 61 | 'hide' : 8, # 不可见 62 | }, 63 | 'default' : 64 | { 65 | 'end' : 0, 66 | }, 67 | } 68 | '''带Style输出''' 69 | def UseStyle(string, mode = '', fore = '', back = ''): 70 | 71 | mode = '%s' % STYLE['mode'][mode] if STYLE['mode'].has_key(mode) else '' 72 | fore = '%s' % STYLE['fore'][fore] if STYLE['fore'].has_key(fore) else '' 73 | back = '%s' % STYLE['back'][back] if STYLE['back'].has_key(back) else '' 74 | style = ';'.join([s for s in [mode, fore, back] if s]) 75 | style = '\033[%sm' % style if style else '' 76 | end = '\033[%sm' % STYLE['default']['end'] if style else '' 77 | return '%s%s%s' % (style, string, end) 78 | 79 | 80 | class People: 81 | def __init__(self,username,uid,gender,birthday,province,city): 82 | self.username = username 83 | self.uid = uid 84 | self.gender = gender 85 | self.birthday = birthday 86 | self.province = province 87 | self.city = city 88 | self.datetime = str(time.strftime('%Y-%m-%d',time.localtime(time.time()))) 89 | #people = People(myname,myid,gender,birthday,province,city) 90 | 91 | def GetCookies(): 92 | 93 | f = open('cookies.txt','r') 94 | cookies = {} 95 | for line in f.read().split(';'): 96 | name,value = line.strip().split('=',1) 97 | cookies[name] = value 98 | return cookies 99 | 100 | '''获得所有时间听歌次数Top100''' 101 | def GetTopAllTime(uid): 102 | songNameList = [] 103 | singerList = [] 104 | url = 'http://music.163.com/user/songs/rank?id=' + str(uid) 105 | browser = webdriver.PhantomJS(executable_path='/Users/Mashaz/phantomjs-2.1.1-macosx/bin/phantomjs') 106 | #browser = webdriver.Chrome(executable_path='/Users/Mashaz/chromedriver') 107 | 108 | try: 109 | browser.get(url) 110 | browser.implicitly_wait(30) 111 | browser.switch_to_frame('g_iframe') 112 | browser.find_element_by_id('songsall').click() 113 | browser.implicitly_wait(30) 114 | time.sleep(3) # !!! 115 | 116 | soup = BeautifulSoup(browser.page_source) 117 | page_content = soup.findAll('div',attrs={'id','m-record'})[0] #weekly top100歌单div 118 | soupSingerList = soup.findAll('div',attrs={'class','ttc'}) 119 | for i in range(0,len(soupSingerList)): 120 | singerList.append(soupSingerList[i].contents[0].contents[1].contents[2].contents[0].contents[0]) 121 | 122 | songslist = soup.findAll('b') 123 | 124 | for i in range(0,len(songslist)): 125 | songNameList.append(songslist[i].contents[0]+' - '+singerList[i]) 126 | browser.close() 127 | return songNameList 128 | except: 129 | browser.close() 130 | return [] 131 | 132 | '''获得上周Top100''' 133 | def GetTopLastWk(uid): 134 | songNameList = [] 135 | singerList = [] 136 | url = 'http://music.163.com/user/songs/rank?id=' + str(uid) 137 | browser = webdriver.PhantomJS(executable_path='/Users/Mashaz/phantomjs-2.1.1-macosx/bin/phantomjs') 138 | #browser = webdriver.Chrome(executable_path='/Users/Mashaz/chromedriver') 139 | 140 | 141 | try: 142 | browser.get(url) 143 | browser.implicitly_wait(30) 144 | time.sleep(3) 145 | browser.switch_to_frame('g_iframe') 146 | soup = BeautifulSoup(browser.page_source) 147 | page_content = soup.findAll('div',attrs={'id','m-record'})[0] #weekly top100歌单div 148 | 149 | soupSingerList = soup.findAll('div',attrs={'class','ttc'}) 150 | for i in range(0,len(soupSingerList)): 151 | singerList.append(soupSingerList[i].contents[0].contents[1].contents[2].contents[0].contents[0]) 152 | 153 | songslist = soup.findAll('b') 154 | 155 | no = 1 156 | for i in range(0,len(songslist)): 157 | songNameList.append(songslist[i].contents[0]+' - '+singerList[i]) 158 | browser.close() 159 | return songNameList 160 | except: 161 | #print 'Ooooops,该用户隐藏了该动态' 162 | browser.close() 163 | return [] 164 | 165 | def CompareTopWeekly(mylist,ulist): 166 | if mylist!=[] and ulist!=[]: 167 | print wname, 168 | print '******************' 169 | print tname 170 | for i in range(0,10): 171 | print '*******************听歌排行-上周最多********************' 172 | print i, 173 | print mylist[i], 174 | print ':', 175 | print ulist[i] 176 | else: 177 | print 'Ooooops' 178 | 179 | def CompareTopAllTime(mylist,ulist): 180 | if mylist!=[] and ulist!=[]: 181 | print wname, 182 | print '******************' 183 | print tname 184 | for i in range(0,10): 185 | print '*******************听歌排行-所有时间********************' 186 | print i, 187 | print mylist[i], 188 | print ':', 189 | print ulist[i] 190 | 191 | else: 192 | print 'Ooooops' 193 | 194 | def GetPlayListDetail(plid): 195 | 196 | songList = [] 197 | singerList = [] 198 | url = 'http://music.163.com/playlist?id='+str(plid) 199 | headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'} 200 | respo = requests.get(url,headers=headers) 201 | soup = BeautifulSoup(respo.content) 202 | main = soup.find('ul',{'class':'f-hide'}) 203 | 204 | for music in main.findAll('a'): 205 | songList.append(music.text) 206 | #print music.text 207 | 208 | singermain = soup.find('textarea',{'style':'display:none;'}) 209 | xxx = str(singermain.contents[0]).lstrip("u'").rstrip("'") 210 | try: 211 | d = json.loads(xxx) 212 | for i in range(0,len(d)): 213 | singerList.append(d[i]['artists'][0]['name']) 214 | except: 215 | for i in range(0,len(songList)): 216 | singerList.append("unknown") 217 | 218 | 219 | return songList,singerList 220 | 221 | 222 | #print data.artists 223 | 224 | def GetAllListId(uid): 225 | 226 | url = 'http://music.163.com/user/home?id='+str(uid) 227 | respo = requests.get(url) 228 | re_count = re.compile(r'cCount:[0-9]{1,3},') 229 | ccount = int(re.findall(re_count,respo.content)[0].lstrip('cCount:').rstrip(',')) #创建的歌单数 230 | 231 | offset=0 232 | limit=100 233 | url = 'http://music.163.com/api/user/playlist/?offset={}&limit={}&uid={}'.format(offset,limit,uid) 234 | ''' 235 | 为csrf_token搞了大半天,感谢github上的musicbox项目,上了api,但api次数太少会被ban 236 | ''' 237 | respo = requests.get(url) 238 | print '获得歌单list,解析中...' 239 | re_id = re.compile(r'\"id\":[0-9]{6,9}\D') 240 | #re_name = re.compile(r'\"name\":[a-zA-Z0-9]{1,50}\"') 把歌单名取出来json 241 | idlist = re.findall(re_id,respo.content) 242 | #namelist = re.findall(re_name,respo.content) 243 | for i in range(0,len(idlist)): 244 | idlist[i] = idlist[i].lstrip('"id":').rstrip('}').rstrip(',') 245 | idlist = idlist[0:ccount] 246 | print '解析完毕' 247 | return idlist #创建的所有的歌单id列表 248 | 249 | def singerAnalysis(singerList,flag): 250 | 251 | word_counts = Counter(singerList) 252 | top_three = word_counts.most_common(3) 253 | try: 254 | x1 = top_three.pop() 255 | x2 = top_three.pop() 256 | x3 = top_three.pop() 257 | print UseStyle('收藏最多的歌手:%s(%s次)'%(x3[0],x3[1]),fore="purple") 258 | print UseStyle('收藏第二多的歌手:%s(%s次)'%(x2[0],x2[1]),fore="blue") 259 | print UseStyle('收藏第三多的歌手:%s(%s次)'%(x1[0],x1[1]),fore="white") 260 | except: 261 | print '看来你收藏的不够多哦!' 262 | def SingleListAnlyasis(people): 263 | 264 | print '爬取所有时间Top100中...' 265 | myAllList = GetTopAllTime(people.uid) 266 | time.sleep(2) 267 | print '爬取完毕' 268 | print '爬取上周Top100中...' 269 | myWeekList = GetTopLastWk(people.uid) 270 | print '爬取完毕' 271 | if myAllList == []: 272 | print 'Ooooops,该用户隐藏了动态' 273 | else : 274 | 275 | myAllSongList = [] 276 | myAllSingerList = [] 277 | for song in myAllList: 278 | s = song.split('-') 279 | myAllSongList.append(s[0].strip()) 280 | myAllSingerList.append(s[1].strip()) 281 | print UseStyle('所有时间Top10' ,fore= 'cyan' ) #自行修改输出数 282 | if len(myAllList)>9: 283 | for i in range(0,10): 284 | print myAllList[i] 285 | print UseStyle('上周Top10' ,fore = 'cyan') 286 | try: 287 | for i in range(0,10): 288 | print myWeekList[i] 289 | except: 290 | for song in myWeekList: 291 | print song 292 | print UseStyle('----------------所有时间Top100分析结果-----------------' ,fore = "cyan") 293 | 294 | singers_counts = Counter(myAllSingerList) 295 | top_three = singers_counts.most_common(3) 296 | try: 297 | x1 = top_three.pop() 298 | x2 = top_three.pop() 299 | x3 = top_three.pop() 300 | print UseStyle('Top100听的最多的歌手:%s(%s次)'%(x3[0],x3[1]),fore="purple") 301 | print UseStyle('Top100听的第二多的歌手:%s(%s次)'%(x2[0],x2[1]),fore="blue") 302 | print UseStyle('Top100听的第三多的歌手:%s(%s次)'%(x1[0],x1[1]),fore="white") 303 | except: 304 | print '看来你听的不够多哦!' 305 | if myWeekList == []: 306 | print 'Ta上周没有听歌哦' 307 | else: 308 | myWeekSongList = [] 309 | myWeekSingerList = [] 310 | for song in myWeekList: 311 | s = song.split('-') 312 | myWeekSongList.append(s[0].strip()) 313 | myWeekSingerList.append(s[1].strip()) 314 | 315 | print UseStyle('----------------上周Top100分析结果-----------------' ,fore = "cyan") 316 | 317 | singers_counts = Counter(myWeekSingerList) 318 | top_three = singers_counts.most_common(3) 319 | try: 320 | x1 = top_three.pop() 321 | x2 = top_three.pop() 322 | x3 = top_three.pop() 323 | print UseStyle('上周Top100听的最多的歌手:%s(%s次)'%(x3[0],x3[1]),fore="purple") 324 | print UseStyle('上周Top100听的第二多的歌手:%s(%s次)'%(x2[0],x2[1]),fore="blue") 325 | print UseStyle('上周Top100听的第三多的歌手:%s(%s次)'%(x1[0],x1[1]),fore="white") 326 | except: 327 | print '看来你上周听的不够多哦!' 328 | # print '输入X(X为1-100内的数字)+Enter输出详细TopX榜单,直接Enter退出' 329 | # flag_print_detail = raw_input() 330 | # if flag_print_detail < 101 and flag_print_detail > 0 : 331 | # if(flag_print_detail