因为这是我第一个独立实践的爬虫项目,所以这次把思路都放上来了

特别注意,用的是charles,可以拦截查看url

知识点:

·······利用charles分析网页,抓包,得出对应URL

·······json网页不是可以直接用json.load 直接转换json的

·······利用find_path快速找到所需内容的路径

······学会用try,预防程序中断

·······urltrieve下载文件可以添加回调函数

·······多进程使用

·······利用sys.stdout.write 记录进度

============先打开charles,再操作qq音乐

1.打开qq音乐页面,进入我的音乐

2.选择我创建的歌单

3.选择其中一个歌单

4.进入歌单,随便选一首歌,点击播放

5.最后就进入了这个页面,可以播放歌曲了

==========================================================

好了,现在可以看看charles上有哪些url

特喵的,这么多,怎么入手?

思路:

①不一定要跟着步骤去找url,可以反过来的嘛

先找歌曲文件mp3(原来是m4a格式)

找code是206的url,206一般是歌曲跟视频下载什么的

找到了,不过这个url好像有点儿复杂

我把这个url分析了下:

不同歌曲间,只需改变那2个变量即可下载!

②那么,如何得到那个m4a跟 vkey呢?

这时就是charles大显神威了,直接ctrl+f,搜索那2个变量,直接vkey就行了!

看,结果是2部分,分别是2个网址,下面那个就是歌曲的url了,复制的文本是在Request URL跟Header,那就是刚刚从这里赋值过来的,所以忽略,主要看上面那个

Response Body:206,,,对了,看来vkey就是出自这个网址了,点击进去

OK,看来找到vkey跟filename的出处了,那么下一步就是分析这个URL的组成了

PS:注意,如果进入这个网址,构造的时候需要在header加上referer:https://y.qq.com/portal/player.html

很明显,这个url也很鸡儿复杂,我还得分析:

③:看上去这个url很复杂,实际只需2个变量!songmid跟filename,不过仔细一看,这2个变量其实只需songmid就行了,

因为filename=C400+songmid,这时就继续利用charles,ctrl+F 看看这个songmid出自哪里

搜索结果如下:

包含songmid字串符的url有这么多,而我的目的页面是这个:

包含360多首歌的songmid,经过对比就是上面qzone跟splcloud这2个网址,我就选了qzone这个继续分析了

OK!所有歌曲的songmid都在里面了,剩下来就再分析这个URL的组成了             PS:referer:'https://y.qq.com/n/yqq/playlist/2986328419.html'

===============================================

所需的网址全部找出来了,现在把思路整理下:

1.进入包含所有songmid的歌单URL:得到songmid

https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg?type=1&json=1&utf8=1&onlysong=0&disstid=2986328419&format=jsonp&g_tk=1547190586&jsonpCallback=playlistinfoCallback&loginUin=2020197426&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0

referer:https://y.qq.com/n/yqq/playlist/2986328419.html

2.进入songmid的URL:得到对应的vkey

https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?g_tk=1547190586&jsonpCallback=MusicJsonCallback7615551634069047&loginUin=2020197426&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0&cid=205361747&callback=MusicJsonCallback7615551634069047&uin=2020197426&songmid=003EsQzm2RJPmv&filename=C400003EsQzm2RJPmv.m4a&guid=4670078301

referer:https://y.qq.com/portal/player.html

3.得到歌曲的URL,可以直接下载了

http://dl.stream.qqmusic.qq.com/C400003EsQzm2RJPmv.m4a?vkey=6569916EE22DF54C0EB5DFBFE390B426B6F97153BF510DF12D36C4E1A72EF04E528CE77655E19B1DC6F6533B893EC217BF440DA84363ED3B&guid=4670078301&uin=2020197426&fromtag=66

=========================================================

现在终于可以写代码了!

一、先搞歌单这部分

import requests,json,re,urllib,osurl='https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg?type=1&json=1&utf8=1&onlysong=0&disstid=2984189527&format=jsonp&g_tk=1547190586&jsonpCallback=playlistinfoCallback&loginUin=2020197426&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0'
header={}
header['user-agent']='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
header['referer']='https://y.qq.com/n/yqq/playlist/2984189527.html'

req=requests.get(url,headers=header)
req1=str(req.text).replace('playlistinfoCallback','').strip('()')#text不能直接json,要把头跟末尾去掉才行!
info=json.loads(req1)
print(info)

text的内容:

我去,好恐怖的字典,怎么找出我要的songmid位置?

当然可以自己手动找,不过我之前不是写了个find_path模块吗?正好派上用场

from find_path.find_path import find_path
d=find_path()
d.work(info,'004WJqnr0OlghO')

搜索结果:

OK!知道什么路径了,现在把songmid、歌手、歌曲名、都提取出来!

import requests,json,re,urllib,os
from find_path.find_path import find_path
playlist='2984189527'   ##指定歌单
url='https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg?type=1&json=1&utf8=1&onlysong=0&disstid={}\
&format=jsonp&g_tk=1547190586&jsonpCallback=playlistinfoCallback&loginUin=2020197426\
&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0'.format(playlist)
header={}
header['user-agent']='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
header['referer']='https://y.qq.com/n/yqq/playlist/{}.html'.format(playlist)req=requests.get(url,headers=header)
req1=str(req.text).replace('playlistinfoCallback','').strip('()')#text不能直接json,要把头跟末尾去掉才行!
info=json.loads(req1)
songinfo=info['cdlist'][0]['songlist']
songlist={}
for name in songinfo:
    songlist[name['songmid']]=name['singer'][0]['name']+'-'+name['songname']
print(songlist)    ##得到的字典就是'003gltCe0JUvCU': '雷安娜-停不了的爱'  各个歌曲组成

二、现在随便拿一首歌进行下载:

#求vkey
header1={}
header1['user-agent']='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
header1['referer']='https://y.qq.com/portal/player.html'
id='002pRyIY2kSvK1'   #要找的歌曲的songmid
url='https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?g_tk=1547190586&jsonpCallback=MusicJsonCallback8769319220381753&loginUin=2020197427&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0&cid=205361747&callback=MusicJsonCallback8769319220381753&uin=2020197427\
&songmid={}&filename=C400{}.m4a&guid=4670078301'.format(id,id)
keyreq=requests.get(url,headers=header1)
vkey=re.findall(r'vkey":"(.+)"}]}}',keyreq.text)[0]##下载歌曲
songurl='http://dl.stream.qqmusic.qq.com/C400{}.m4a?vkey={}\
&guid=4670078301&uin=2020197427&fromtag=66'.format(id,vkey)
urllib.request.urlretrieve(songurl,os.getcwd()+'\\'+songlist[id]+'.m4a')

终于搞定了!! 剩下就是自己把代码简化了!然后把歌单里的所有歌曲都下载,代码整合如下

import requests,json,re,urllib,os,time,sys
from find_path.find_path import find_path
from multiprocessing import Pool
import logginglogger = logging.getLogger(__name__)
class qqmusic_songs(object):
    def __init__(self,path):
        self.headers={'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}self.songdict={}                              #get_songdict会给它赋值
        self.path=path

    def get_songdict(self,playlist):
        '''得出所输入歌单每首歌songmid:歌名 组成的字典'''
        headers=self.headers.copy()headers['referer'] = 'https://y.qq.com/n/yqq/playlist/{}.html'.format(playlist)url='https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg?type=1&json=1&utf8=1&onlysong=0&disstid={}\
        &format=jsonp&g_tk=1547190586&jsonpCallback=playlistinfoCallback&loginUin=2020197426\
        &hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0'.format(playlist)req=requests.get(url,headers=headers)req1=str(req.text).replace('playlistinfoCallback','').strip('()')#text不能直接json,要把头跟末尾去掉才行!
        info=json.loads(req1)songinfo=info['cdlist'][0]['songlist']            #对应的歌单里每首歌的歌曲信息
        songdict={}for name in songinfo:
            songdict[name['songmid']]=name['singer'][0]['name']+'-'+name['songname']+'__['+name['albumname']+']'
        self.songdict=songdictreturn songdict    ##得到的字典就是'003gltCe0JUvCU': '雷安娜-停不了的爱'  各个歌曲组成


    def download_song(self,songmid):
        '''输入songmid,得出对应的vkey, 用urlretrieve下载歌曲'''
        headers=self.headers.copy()headers['referer']='https://y.qq.com/portal/player.html'
        url='https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?g_tk=1547190586&jsonpCallback=MusicJsonCallback8769319220381753&loginUin=2020197427&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq&needNewCode=0&cid=205361747&callback=MusicJsonCallback8769319220381753&uin=2020197427' \'&songmid={}&filename=C400{}.m4a&guid=4670078301'.format(songmid,songmid)try:                                                     #不知哪首歌有问题,用try安全
            keyreq=requests.get(url,headers=headers)vkey=re.findall(r'vkey":"(.+)"}]}}',keyreq.text)[0]   #得出vkey,就可以得出歌曲的url            ##下载歌曲
            songurl='http://dl.stream.qqmusic.qq.com/C400{}.m4a?vkey={}&guid=4670078301&uin=2020197427&' \'fromtag=66'.format(songmid,vkey)path=self.path+'\\'+self.songdict[songmid]+'.m4a'
            if (not os.path.exists(path)):                       #如果中断,已经有的文件就不用再下载了
                urllib.request.urlretrieve(songurl,path,reporthook=self.Schedule)time.sleep(0.8)except Exception as e:
            logger.warning(e)logger.warning("有问题的网址是%s,歌曲是%s"% (url,self.songdict[songmid]))def Schedule(self, a, b, c):
        '''urlretrieve的回调函数'''
        songscount=len(os.listdir(self.path))per=100.0 * songscount/len(self.songdict)if per > 100:
            per = 1
        sys.stdout.write("  " + "%.2f%% 已经下载%s首歌  共%s首歌" % (per, songscount,len(self.songdict)) + '\r')sys.stdout.flush()def work(self,playlist):
        '''多进程下载'''
        time1=time.time()songdict = self.get_songdict(playlist)print('正在下载歌单  %s 的歌曲'% playlist)pool=Pool(8)pool.map(self.download_song, songdict.keys())pool.close()pool.join()time2=time.time()usetime=time2-time1songscount = len(os.listdir(self.path))print('下载完成!  理论上共%s首歌,实际下载了%s首歌,耗时%.1fs'%(len(self.songdict),songscount,usetime))if __name__ == '__main__':
    path=r'C:\Users\Administrator\Desktop\歌曲'
    d=qqmusic_songs(path)d.work('2984189527')

不过话说sys.write这个记录进度的方法,只能在cmd利用,pycharm显示不了的,不过可以用它的terminal控制台运行

python利用charles爬虫爬取下载qq音乐歌单里的歌曲——多进程相关推荐

  1. Python爬取网易云音乐歌单内所有歌曲

    一.目标: 下载网易云音乐热门歌单 二.用到的模块: requests,multiprocessing,re. 三.步骤: (1)页面分析:首先打开网易云音乐,选择热门歌单,可以看到以下歌单列表,然后 ...

  2. selenium切换iframe框架案例——翻页爬取网易云音乐歌单作者和名称

    翻页爬取网易云音乐歌单作者和标题 案例目的: 通过翻页selenium操作网易云音乐,介绍如何切换iframe框架以及如何使用selenium定位数据所在的节点. 代码功能: 输入下载的数据页数,自动 ...

  3. python网络爬虫-爬虫实战-(爬取网易云薛之谦歌单里歌曲并下载)

    1.导入要用到的库 #导入库 import requests from fake_useragent import UserAgent from lxml import etree import re ...

  4. 用python爬取网易云音乐歌单列表

    本文分为两个部分:基础知识和正文,其中基础知识包括什么正则表达式以及Beautifulsoup4的使用. 一.正则表达式 正则表达式用于字符串查找.合法性检查以及作为程序员的工具箱使用. 字符串查找: ...

  5. python爬取网易云音乐歌单_【python】爬取并批量下载网易云歌单,嗨翻暑假!

    [Python] 纯文本查看 复制代码# 利用 Selenium 抓取淘宝商品并用 PyQuery 解析得到商品的图片.名称.价格.购买人数. # 店铺名称.店铺所在地信息,并将其保存到MongoDB ...

  6. python爬取音乐歌曲大全_Python爬取网易云音乐歌单歌曲

    # 从网易云音乐下载歌单歌曲 # 参考了这些网址 # https://blog.csdn.net/Ciiiiiing/article/details/62434438 # https://github ...

  7. python爬虫:利用多线程爬虫爬取下载进击的巨人图片

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理 本品文章来自腾讯云 作者:孤独的明月 文章目录 线程池 获取图片链接 下载图片 存 ...

  8. python爬虫爬取网易云音乐歌曲_如何用爬虫获取网易云音乐歌单中的歌曲?

    --------------------------------- 泻药,以我抓取了307835首网易云音乐的歌单歌曲的经验,讲一下这个问题. 喜欢用Github的可以直接看我的项目源码,代码简单.具 ...

  9. PHP爬虫音乐,PHP 爬虫———爬取网易云音乐歌单

    爬取网易云音乐歌单 PHP + QueryList + Puppeteer + Nodejs 使用 Composer 安装库 如果你之前没有接触过Composer,强烈建议你学习一下.Composer ...

最新文章

  1. Wannafly挑战赛21 E 未来城市规划
  2. 【错误记录】安卓 RecyclerView 报错 ( only use immediately and call holder.getAdapterPosition() to look it up )
  3. 数据结构_队列_mindmap
  4. RHEL6基础之八查找、文件内容查看类命令
  5. 深度学习导论(6)误差计算
  6. hook 与aspectj_将AspectJ与NetBeans平台开发集成
  7. ELF 动态链接 so的动态符号表(.dynsym)
  8. 解决一个驱动代码解耦合问题
  9. java中excel文件导入数据库中_〖JAVE经验〗java中Excel导入数据库里
  10. python动态方法_python中的动态方法生成
  11. SpringBoot+EHcache实现缓存
  12. linux编辑查看命令,Linux的文本编辑和文本内容查看命令
  13. jmeter性能测试实战_Jmeter接口测试实战篇:10分钟学会Jmeter的用法
  14. git代码比较,没有差异却显示出来
  15. 中国1:100万土壤数据处理
  16. 三维GIS+电力巡检,开启电缆通道数字化巡检新局面
  17. 医院计算机应用,解读计算机应用技术对医院信息化的影响
  18. linux 核显驱动程序,在Ubuntu系统上安装英特尔核显驱动安装器的方法
  19. 计算机图形学教程动画实验报告,计算机图形学画圆实验报告.doc
  20. UTON NFT的到来将为摄影师带来全新的未来!

热门文章

  1. [电脑]_开始着手做小软件站
  2. linux mac怎么看内存,mac下查看内存信息
  3. CentOS 搭建 WordPress 站点
  4. 王者荣耀4月14日服务器维护,《王者荣耀》4月14日更新了什么 4月14日更新更新内容一览...
  5. 【调剂】深圳大学大湾区国际创新学院2023年人工智能专业研究生预调剂信息
  6. Outlook邮箱无法自动存档的解决办法
  7. Excel表格中如何快速输入当前日期和时间
  8. Frame map does not exist
  9. 计算机在聚合物中的应用缩写,常用高分子聚合物的中英文名称缩写对照
  10. RK平台预置视频或者教育资源大文件到存储卡