在常见的几个音乐网站里, 酷狗可以说是最好爬取的啦, 什么弯都没有, 也没加密啥的, 所以最适合小白入门爬虫
本篇针对爬虫零基础的小白, 所以每一步骤我都截图并详细解释了, 其实我自己看着都啰嗦, 归根到底就是两个步骤的请求, 还请大佬绕路勿喷.
打开酷狗官网, 可以看到搜索框, 我们要爬取的数据就是搜索歌曲后, 酷狗后台返回的歌曲列表以及每首歌的歌曲信息(歌词, 作者, url 等)
Xshot-0048.PNG
敲 F12 键进入开发者模式, 选择 Network - All (这里就是酷狗前后台交互的所有请求列表)
Xshot-0050.PNG
搜索框中输入搜索内容, 然后右侧就可以看到会出现很多列表, 搜索的列表数据其实就在这里面一条, 我已经红色框标注了(找出这个可以根据那个名字 song_search, 实在不行点开一个个看是不是所要找的内容)
Xshot-0052.PNG
点开这行, 上面切换到 Preview 发现就是搜索结果的 JSON 数据, lists 就是数据列表
Xshot-0053.PNG
点开一条歌曲, 里面就包含歌曲名字, 作者, AlbumID,FileHash 等歌曲信息
Xshot-0054.PNG
然后我们上面切换到 Headers, 可以看到 RequestURL(就是请求网址), 下面箭头可以看到是 GET 请求
Xshot-0055.PNG
往下滑, 可以看到 Requset Headers(这个后端会验证 heades, 一般请求时 user-agent 都需要写上, 有些还验证更偏的, 需要看情况处理, 酷狗倒是没有验证, 不写 headers 请求也可以)和请求参数(这就是请求的参数, 搜索关键词, 请求数目等信息)
Xshot-0056.PNG
话不多说, 我们直接用 python 的 requests 库 (这个直接百度装一下就行) 构造请求, 我的环境是 python2.7,python3 的注意一下版本差异
- #coding=utf-8
- import requests
- search = '喜欢你' #搜索内容
- pagesize = '10' #请求数目
- url = 'https://songsearch.kugou.com/song_search_v2?callback=jQuery11240251602301830425_1548735800928&keyword=%s&page=1&pagesize=%s&userid=-1&clientver=&platform=webFilter&tag=em&filter=2&iscorrection=1&privilege_filter=0&_=1548735800930' % (search,pagesize)
- res = requests.get(url) #requests 发起 get 请求
- print res.text #输出响应内容
输出结果就是这样, 可以看到返回 JSON 内容全部打印了出来, 这就是和刚才在浏览器开发者工具看到的信息一样
Xshot-0057.PNG
接着我们拿到列表后, 再转回浏览器, 拿到列表每一条歌曲的具体信息, 左侧选择第一条点击进入详情页
Xshot-0058.PNG
可以看到跳转到了播放页面, 刷新一下页面, 重新加载一遍
Xshot-0059.PNG
可以看到右侧红色框圈起来的就是歌曲信息(你可能问我怎么知道哪个才是包含歌曲信息的, 当然是观察法了, 写多了就有经验了, 实在不会一个个点进去看)
Xshot-0060.PNG
我用箭头标注的都是一般需要爬取的有用信息, 可以看到作者, 歌曲名, 歌词, 专辑图片, id,play_url 都在里面, 不信你把 play_url 复制到地址栏回车播放的肯定是这个歌曲, 拿到这个 url 我们就可以直接下载歌曲了
Xshot-0061.PNG
接着我们再从上方从 Preview 切换到 Headers, 可以看到和请求歌曲列表差不多, 还是 GET 请求
Xshot-0062.PNG
这里的 query 同样还是 GET 请求的参数, 其中 hash 和 album_id 就是一首歌曲的信息, 我们只需要请求不同歌曲时改这两个参数就行了(第一步请求搜索列表每一行单曲数据包含这个参数了)
Xshot-0063.PNG
直接刚才根据开发者模式里面的 RequestURL, 构造 get 请求, 请求每首歌曲时换上每首歌对应的 id 和 hash 值就行
- #coding=utf-8
- import requests
- # 在这里, 为了分步演示, 直接用刚才第一步搜索时开发者模式获取到的搜索列表第一条的 id 和 hash
- # 文章最后有整个连贯的代码
- id = '557512' #单曲 id
- hash = '41C2E4AB5660EAE04021C5893E055F50' #单曲 hash 值
- url = 'https://wwwapi.kugou.com/yy/index.php?r=play/getdata&callback=jQuery19107465224671418371_1555932632517&hash=%s&album_id=%s&_=1555932632518' % (hash,id)
- res = requests.get(url)
- print res.text
可以看到控制台打印了单曲信息, 因为是 JSON 数据没有转换, 直接输出打印现在看起来有点乱
Xshot-0064.PNG
注意, 酷狗返回数据并不直接就是 JSON 格式, 两端有一些无用字符串, 需用正则表达式去除, 只保留大括号 {} 里面 (包括大括号) 内容, 19 步骤代码里有说明
Xshot-0065.PNG
我们已经熟悉了上面的两步, 最后进行汇总写一个完整的 python 爬虫, 输入搜索歌曲, 拿到搜索列表并包括单曲信息
- # coding=utf-8
- import requests
- import JSON
- import re
- # 请求搜索列表数据
- search = raw_input('音乐名:') # 控制台输入搜索关键词
- pagesize = "10" # 请求数目
- url = 'https://songsearch.kugou.com/song_search_v2?callback=jQuery11240251602301830425_1548735800928&keyword=%s&page=1&pagesize=%s&userid=-1&clientver=&platform=WebFilter&tag=em&filter=2&iscorrection=1&privilege_filter=0&_=1548735800930' % (search, pagesize)
- res = requests.get(url) # 进行 get 请求
- # 需要注意一点, 返回的数据并不是真正的 JSON 格式, 前后有那个多余字符串需要用正则表达式去掉, 只要大括号 {} 包着的内容
- # JSON.loads 就是将 JSON 数据转为 python 字典的函数
- res = JSON.loads(re.match(".*?({.*}).*", res.text, re.S).group(1))
- list = res['data']['lists'] # 这个就是歌曲列表
- # 建立 List 存放歌曲列表信息, 将这个歌曲列表输出, 别的程序就可以直接调用
- musicList = []
- #for 循环遍历列表得到每首单曲的信息
- for item in list:
- #将列表每项的 item['FileHash'],item['AlnbumID']拼接请求 url2
- url2 = 'https://wwwapi.kugou.com/yy/index.php?r=play/getdata&callback=jQuery191010559973368921649_1548736071852&hash=%s&album_id=%s&_=1548736071853' % (
- item['FileHash'], item['AlbumID'])
- res2 = requests.get(url2)
- res2 = JSON.loads(re.match(".*?({.*}).*", res2.text).group(1))['data']# 同样需要用正则处理一下才为 JSON 格式, 再转为字典
- #打印一下
- print res2['song_name']+'-'+res2['author_name']
- print res2['play_url']
- print ''
- #将单曲信息存在一个字典里
- dict = {
- 'author': res2['author_name'],
- 'title': res2['song_name'],
- 'id': str(res2['album_id']),
- 'type': 'kugou',
- 'pic': res2['img'],
- 'url': res2['play_url'],
- 'lrc': res2['lyrics']
- }
- #将字典添加到歌曲列表
- musicList.append(dict)
最后控制台输出结果
Xshot-0066.PNG
来源: http://www.jianshu.com/p/0c7c7ebcc1a3