""" 用selenium+PhantomJS配合,不需要进行逆向工程
python 3下的selenium不能默认安装,需要指定版本2.48.0
"""
from selenium import webdriver
import os,requests url = 'https://music.163.com/#/playlist?id=884698131'#网易云音乐歌单
headers = {
'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',
}
driver = webdriver.PhantomJS()
driver.get(url)
driver.implicitly_wait(20)#隐式等待20s
#pprint.pprint(driver.page_source)#查看源代码 def is_chinese(uchar):
"""
判断一个unicode是否是汉字
:param uchar: <char>字符
:return: <boolean>
"""
if uchar >= u'\u4e00' and uchar <= u'\u9fa5':
return True
else:
return False def is_number(uchar):
"""
判断一个unicode是否是数字
:param uchar: <char>字符
:return: <boolean>
"""
if uchar >= u'\u0030' and uchar <= u'\u0039':
return True
else:
return False def is_alphabet(uchar):
"""
判断一个unicode是否是英文字母
:param uchar: <char>字符
:return: <boolean>
"""
if (uchar >= u'\u0041' and uchar <= u'\u005a') or (uchar >= u'\u0061' and uchar <= u'\u007a'):
return True
else:
return False
def is_filename(uchar):
"""
排除文件名不可用的字符,这里请注意都是在英文输入法下的,若是中文输入法下的例如?“等是可以用来生成文件名的
\/:*?"<>|
:param uchar:
:return:
"""
if uchar == u'\u005c' or uchar == u'\u002f' or uchar == u'\u003a' or uchar == u'\u002a' or uchar == u'\u003f' or uchar == u'\u007c' \
or uchar == u'\u003c' or uchar == u'\u003e' or uchar == u'\u007c':
return False
else:
return True def format_str(content):
"""
将字符串content中的字符逐个判断
:param content: <str>输入文本
:return: <str>输出只包含中文、数字及英文字母的字符串
"""
content_str = ''
for i in content:
if is_chinese(i) or is_alphabet(i) or is_number(i):
content_str = content_str+i
print('处理后的content:',content_str)
return content_str def format_str2(content): content_str = ''
for i in content:
if is_filename(i):
content_str = content_str+i
print('处理后的content:',content_str)
return content_str driver.switch_to.frame('g_iframe')#跳转到id为g_iframe的iframe框架下 list_name = driver.find_element_by_class_name('f-ff2').text #歌单名称
#大坑,源代码中是class=“f-ff2 f-brk”,属性值中间有空格,全写上报错
# #list_name2 = driver.find_element_by_xpath('//div[@class=\"m-info\"]/div[2]')
print(list_name) #list_path = os.getcwd()+ '/网易云音乐歌单-' + format_str(list_name)
list_path = os.getcwd()+ '/网易云音乐歌单-' + format_str2(list_name) if os.path.exists(list_path):
pass
else:
os.mkdir(list_path)#若文件夹不存在,则新建 ids = driver.find_elements_by_xpath('//a[starts-with(@href,"/song?id=")]')
names = driver.find_elements_by_xpath('//a[starts-with(@href,"/song?id=")]/b')
for i in range(0,len(ids)):
#id = ids[i].get_attribute('href').strip('https://music.163.com/song?id=')#有问题,获取的某些歌曲id不全,原因未知
id = ids[i].get_attribute('href').replace('https://music.163.com/song?id=','')
name = format_str2(names[i].get_attribute('title').strip().replace('/','')) print(id,name)
link = 'http://music.163.com/song/media/outer/url?id=' + id + '.mp3'
#urllib.request.urlretrieve(link,'E:/'+id+'.mp3')#有时候下载下来的歌曲只有几十kb if os.path.exists(list_path + '/' + str(i + 1) + '_' + name + '.mp3') \
and (os.path.getsize(list_path + '/' + str(i + 1) + '_' + name + '.mp3')) >= 102400:
# 若歌曲存在且能正常播放(此处判断为大于100kb)则不再下载
pass else:
with open(list_path + '/' + str(i + 1) + '_' + name + '.mp3', 'wb') as f:
f.write(requests.get(link, headers=headers).content) #有些歌曲能下载下来但是只有67kb左右,也无法播放,也就是网易云上显示但是无法在线听的音乐
if os.path.getsize(list_path + '/' + str(i + 1) + '_' + name + '.mp3') < 102400:
os.remove(list_path + '/' + str(i + 1) + '_' + name + '.mp3')
else:
pass driver.switch_to.default_content()#返回主文档