1 """
2
3 用selenium+PhantomJS配合,不需要进行逆向工程4 python 3下的selenium不能默认安装,需要指定版本2.48.05 """
6 from selenium importwebdriver7 importos,requests8
9
10
11 url = 'https://music.163.com/#/playlist?id=884698131'#网易云音乐歌单
12 headers ={13 'User-Agent':'User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',14 }15 driver =webdriver.PhantomJS()16 driver.get(url)17 driver.implicitly_wait(20)#隐式等待20s
18 #pprint.pprint(driver.page_source)#查看源代码
19
20 defis_chinese(uchar):21 """
22 判断一个unicode是否是汉字23 :param uchar: 字符24 :return: 25 """
26 if uchar >= u'\u4e00' and uchar <= u'\u9fa5':27 returnTrue28 else:29 returnFalse30
31 defis_number(uchar):32 """
33 判断一个unicode是否是数字34 :param uchar: 字符35 :return: 36 """
37 if uchar >= u'\u0030' and uchar <= u'\u0039':38 returnTrue39 else:40 returnFalse41
42
43 defis_alphabet(uchar):44 """
45 判断一个unicode是否是英文字母46 :param uchar: 字符47 :return: 48 """
49 if (uchar >= u'\u0041' and uchar <= u'\u005a') or (uchar >= u'\u0061' and uchar <= u'\u007a'):50 returnTrue51 else:52 returnFalse53 defis_filename(uchar):54 """
55 排除文件名不可用的字符,这里请注意都是在英文输入法下的,若是中文输入法下的例如?“等是可以用来生成文件名的56 \/:*?"<>|57 :param uchar:58 :return:59 """
60 if uchar == u'\u005c' or uchar == u'\u002f' or uchar == u'\u003a' or uchar == u'\u002a' or uchar == u'\u003f' or uchar == u'\u007c'\61 or uchar == u'\u003c' or uchar == u'\u003e' or uchar == u'\u007c':62 returnFalse63 else:64 returnTrue65
66 defformat_str(content):67 """
68 将字符串content中的字符逐个判断69 :param content: 输入文本70 :return: 输出只包含中文、数字及英文字母的字符串71 """
72 content_str = ''
73 for i incontent:74 if is_chinese(i) or is_alphabet(i) oris_number(i):75 content_str = content_str+i76 print('处理后的content:',content_str)77 returncontent_str78
79 defformat_str2(content):80
81 content_str = ''
82 for i incontent:83 ifis_filename(i):84 content_str = content_str+i85 print('处理后的content:',content_str)86 returncontent_str87
88
89 driver.switch_to.frame('g_iframe')#跳转到id为g_iframe的iframe框架下
90
91
92 list_name = driver.find_element_by_class_name('f-ff2').text #歌单名称
93 #大坑,源代码中是class=“f-ff2 f-brk”,属性值中间有空格,全写上报错
94 ##list_name2 = driver.find_element_by_xpath('//div[@class=\"m-info\"]/div[2]')
95 print(list_name)96
97 #list_path = os.getcwd()+ '/网易云音乐歌单-' + format_str(list_name)
98 list_path = os.getcwd()+ '/网易云音乐歌单-' +format_str2(list_name)99
100 ifos.path.exists(list_path):101 pass
102 else:103 os.mkdir(list_path)#若文件夹不存在,则新建
104
105 ids = driver.find_elements_by_xpath('//a[starts-with(@href,"/song?id=")]')106 names = driver.find_elements_by_xpath('//a[starts-with(@href,"/song?id=")]/b')107 for i inrange(0,len(ids)):108 #id = ids[i].get_attribute('href').strip('https://music.163.com/song?id=')#有问题,获取的某些歌曲id不全,原因未知
109 id = ids[i].get_attribute('href').replace('https://music.163.com/song?id=','')110 name = format_str2(names[i].get_attribute('title').strip().replace('/',''))111
112 print(id,name)113 link = 'http://music.163.com/song/media/outer/url?id=' + id + '.mp3'
114 #urllib.request.urlretrieve(link,'E:/'+id+'.mp3')#有时候下载下来的歌曲只有几十kb
115
116 if os.path.exists(list_path + '/' + str(i + 1) + '_' + name + '.mp3') \117 and (os.path.getsize(list_path + '/' + str(i + 1) + '_' + name + '.mp3')) >= 102400:118 #若歌曲存在且能正常播放(此处判断为大于100kb)则不再下载
119 pass
120
121 else:122 with open(list_path + '/' + str(i + 1) + '_' + name + '.mp3', 'wb') as f:123 f.write(requests.get(link, headers=headers).content)124
125 #有些歌曲能下载下来但是只有67kb左右,也无法播放,也就是网易云上显示但是无法在线听的音乐
126 if os.path.getsize(list_path + '/' + str(i + 1) + '_' + name + '.mp3') < 102400:127 os.remove(list_path + '/' + str(i + 1) + '_' + name + '.mp3')128 else:129 pass
130
131 driver.switch_to.default_content()#返回主文档