这次抓取的为QQ音乐排行榜,我们通过浏览器抓包,直接找m4a文件,这个是音乐文件:

QQ音乐这个url下载地址需要一个参数vkey
,然后还需要构造URL,观察URL发现,基本每个url都是以http://isure.stream.qqmusic.qq.com/C400
开头,后面的值可以在这个页面找到:

那么现在就剩vkey这个参数了。通过浏览器不断的刷新请求观察发现,vkey参数存在于js文件中,我们可以使用json格式工具查看一下,是否有我们寻找的vkey。
json格式工具推荐:http://www.bejson.com
这里略过寻找的步骤,在以:https://u.y.qq.com/cgi-bin/musicu.fcg?callback
,这个url开头的plain文件中找到了vkey的存在,那么现在就是如何构造这个url请求,还需要知道这个url的参数,观察参数变化的有data和jsonpCallback,callback是变化的,data里面变化的就是songmid,就是我们前面找出来C400后面的参数。参考代码:
import requests,json,re,os
from lxml import etree
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
class QQMusic():
def __init__(self):
self.headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
}
self.url='https://y.qq.com/n/yqq/toplist/4.html'
def down_music(self,c4,music_name):
"""
参数不是固定的,可根据自身情况粘贴浏览器中的参数音乐播放页面:https://u.y.qq.com/cgi-bin/musicu.fcg?
songmid最重要
:param c4:
:param music_name:
:return:
"""
self.data=json.dumps({"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"2891348329","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"2891348329","songmid":[c4],"songtype":[0],"uin":"1552797557","loginflag":1,"platform":"20"}},"comm":{"uin":1552797557,"format":"json","ct":24,"cv":0}})
self.params={
"callback":"getplaysongvkey6354954596402418",
"g_tk":"1368429410",
"jsonpCallback":"getplaysongvkey6354954596402418",
"loginUin":"1552797557",
"hostUin":"0",
"format":"jsonp",
"inCharset":"utf8",
"outCharset":"utf-8",
"notice":"0",
"platform":"yqq",
"needNewCode":"0",
"data":self.data
}
url = 'https://u.y.qq.com/cgi-bin/musicu.fcg?'
try:
html = requests.get(url,headers=self.headers,params=self.params)
# html.text开始的参数我们需要提取出来,不然会报错,转不了json字典格式的
s = re.compile('.*?\((.*?)\)', re.S)
data = re.findall(s, html.text)[0]
music = json.loads(data)
purl = music['req_0']['data']['midurlinfo'][0]['purl']
down_url = f'http://111.6.166.23/amobile.music.tc.qq.com/{purl}'
# print(down_url)
self.download(down_url,music_name)
except Exception as e:
return None
def download(self,down_url,music_name):
print('正在下载歌曲:%s' % music_name)
file_path = '{0}/{1}.{2}'.format(os.getcwd(), music_name, 'm4a')
if not os.path.exists(file_path):
with open(file_path, 'wb') as f:
f.write(requests.get(down_url).content)
def get_music(self):
"""
提取所有的排行榜页面
:return: 排行榜url
"""
try:
html=requests.get(self.url,self.headers).content
tree=etree.HTML(html)
for i in tree.xpath('//dd[@class="toplist_nav__item"]'):
href='https:'+i.xpath('./a/@href')[0]
yield href
except Exception as e:
return None
def get_detail(self,url):
"""
由于排行榜页面的数据没有在源代码中,所以使用selenium获取
:param url:
:return:
"""
# option = webdriver.ChromeOptions()
# option.add_argument('headless')
# driver = webdriver.Chrome(options=option)
try:
option = webdriver.FirefoxOptions() # 设置首选项,无头浏览器,就是看不到浏览器的操作,后台进行
option.add_argument('-headless') #火狐无头模式
driver =webdriver.Firefox(options=option) #这里使用火狐浏览器
driver.get(url)
# 等待所有的class="songlist__songname_txt"都加载出来,这个是歌曲的名字
WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, "songlist__songname_txt")))
# 然后我们提取这个歌曲的相关属性,C400
lis = driver.find_elements_by_class_name('songlist__songname_txt')
#href="https://y.qq.com/n/yqq/song/000OjsEW0QrPAd.html"
pattern = re.compile(r'https://y.qq.com/n/yqq/song/(.*?).html') #通过正则提取C400后面的值
for i in range(lis.__len__()):
li = lis.__getitem__(i)
# 找到class="js_song",这个才是我们需要的
a = li.find_element_by_class_name('js_song')
href = a.get_attribute('href')
music_name = a.get_attribute('title')
c4 = re.match(pattern, href).group(1)
yield c4,music_name
except TimeoutException as e:
return None
def start(self):
for url in self.get_music():
for k,v in self.get_detail(url):
self.down_music(k, v)
if __name__=='__main__':
qq=QQMusic()
qq.start()
音乐保存在当前目录下,可以自行修改,参数也不是固定的可能随时都会失效,同样参数的位置我们已经找到了,就没什么难度了。使用的是selenium抓取排行榜的歌曲信息,比较慢,可以借鉴修改一下。
声明:1. 本站所有资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!