Python無(wú)損音樂(lè)搜索引擎實(shí)現(xiàn)代碼
研究了一段時(shí)間酷狗音樂(lè)的接口,完美破解了其vip音樂(lè)下載方式,想著能更好的追求開(kāi)源,故寫(xiě)下此篇文章,本文僅供學(xué)習(xí)參考。雖然沒(méi)什么技術(shù)含量,但都是自己一點(diǎn)一點(diǎn)碼出來(lái),一點(diǎn)一點(diǎn)抓出來(lái)的。
一、綜述:
根據(jù)酷狗的搜索接口以及無(wú)損音樂(lè)下載接口,做出爬蟲(chóng)系統(tǒng)。采用flask框架,前端提取搜索關(guān)鍵字,后端調(diào)用爬蟲(chóng)系統(tǒng)采集數(shù)據(jù),并將數(shù)據(jù)前端呈現(xiàn);
運(yùn)行環(huán)境:windows/linux python2.7
二、爬蟲(chóng)開(kāi)發(fā):
通過(guò)抓包的方式對(duì)酷狗客戶端進(jìn)行抓包,抓到兩個(gè)接口:
1、搜索接口:
http://songsearch.kugou.com/song_search_v2?keyword={關(guān)鍵字}page=1
這個(gè)接口通過(guò)傳遞關(guān)鍵字,其返回的是一段json數(shù)據(jù),數(shù)據(jù)包含音樂(lè)名稱、歌手、專輯、總數(shù)據(jù)量等信息,當(dāng)然最重要的是數(shù)據(jù)包含音樂(lè)各個(gè)品質(zhì)的hash。
默認(rèn)接口返回的數(shù)據(jù)只包含30首音樂(lè),為了能拿到所有的數(shù)據(jù),只需要把pagesize更改就可以,所以我提取了總數(shù)據(jù)數(shù)量,然后再次發(fā)動(dòng)一次數(shù)據(jù)請(qǐng)求,拿到全部的數(shù)據(jù)。當(dāng)然,這個(gè)總數(shù)據(jù)量也就是json中的total也是作為搜索結(jié)果的依據(jù),如果total == 0 則判斷無(wú)法搜索到數(shù)據(jù)。
搜索到數(shù)據(jù)后,我就要提取無(wú)損音樂(lè)的hash,這個(gè)hash是音樂(lè)下載的關(guān)鍵,無(wú)損音樂(lè)hash鍵名:SQFileHash,提取到無(wú)損hash(如果是32個(gè)0就表示None),我把他的名稱、歌手、hash以字典形式傳遞給下一個(gè)模塊。
代碼實(shí)現(xiàn):
a.請(qǐng)求模塊(復(fù)用率高):
# coding=utf-8 import requests import json headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'max-age=0', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/63.0.3239.132 Safari/537.36', } def parse(url): ret = json.loads(requests.get(url, headers=headers, timeout=5).text) # 返回的是已經(jīng)轉(zhuǎn)換過(guò)后的字典數(shù)據(jù) return ret if __name__ == '__main__': parse()
b.搜索模塊
# coding=utf-8 import copy import MusicParse def search(keyword): search_url = 'http://songsearch.kugou.com/song_search_v2?keyword={}page=1'.format(keyword) # 這里需要判斷一下,ip與搜索字段可能會(huì)限制搜索,total進(jìn)行判斷 total = MusicParse.parse(search_url)['data']['total'] if total != 0: search_total_url = search_url + '&pagesize=%d' % total music_list = MusicParse.parse(search_total_url)['data']['lists'] item, items = {}, [] for music in music_list: if music['SQFileHash'] != '0'*32: item['Song'] = music['SongName'] # 歌名 item['Singer'] = music['SingerName'] # 歌手 item['Hash'] = music['SQFileHash'] # 歌曲無(wú)損hash items.append(copy.deepcopy(item)) return items else: return None if __name__ == '__main__': search()
到這步,音樂(lè)搜索接口以及利用完了,下面就是無(wú)損音樂(lè)搜索了。
2、音樂(lè)下載接口:
# V2版系統(tǒng),pc版 Music_api_1 = 'http://trackercdnbj.kugou.com/i/v2/?cmd=23&pid=1&behavior=download' # V2版系統(tǒng),手機(jī)版(備用) Music_api_2 = 'http://trackercdn.kugou.com/i/v2/?appid=1005&pid=2&cmd=25&behavior=play' # 老版系統(tǒng)(備用) Music_api_3 = 'http://trackercdn.kugou.com/i/?cmd=4&pid=1&forceDown=0&vip=1'
我這里準(zhǔn)備三個(gè)接口,根據(jù)酷狗系統(tǒng)版本不同,采用不同加密方式,酷狗音樂(lè)下載的關(guān)鍵就是音樂(lè)接口處提交的key的加密方式,key是由hash加密生成的,不同的酷狗版本,加密方式不同:
酷狗v2版key的生成:md5(hash +”kgcloudv2″)
酷狗老版key的生成:md5(hash +”kgcloud”)
只要將音樂(lè)的hash+key添加到api_url ,get提交過(guò)去,就能返回一段json數(shù)據(jù),數(shù)據(jù)中就包括了音樂(lè)的下載鏈接,然后在提取其download_url。下面我將采用酷狗的第一個(gè)接口完成代碼的實(shí)現(xiàn),當(dāng)然,酷狗存在地區(qū)的限制,接口有效性也帶檢測(cè),如果第一個(gè)不行就換一個(gè),你懂得?。?!然后我把數(shù)據(jù)做成字典進(jìn)行傳遞。
代碼實(shí)現(xiàn):
# coding=utf-8 import copy import hashlib import MusicParse import MusicSearch # V2版系統(tǒng),pc版,加密方式為md5(hash +"kgcloudv2") Music_api_1 = 'http://trackercdnbj.kugou.com/i/v2/?cmd=23&pid=1&behavior=download' # V2版系統(tǒng),手機(jī)版,加密方式為md5(hash +"kgcloudv2") (備用) Music_api_2 = 'http://trackercdn.kugou.com/i/v2/?appid=1005&pid=2&cmd=25&behavior=play' # 老版系統(tǒng),加密方式為md5(hash +"kgcloud")(備用) Music_api_3 = 'http://trackercdn.kugou.com/i/?cmd=4&pid=1&forceDown=0&vip=1' def V2Md5(Hash): # 用于生成key,適用于V2版酷狗系統(tǒng) return hashlib.md5((Hash + 'kgcloudv2').encode('utf-8')).hexdigest() def Md5(Hash): # 用于老版酷狗系統(tǒng) return hashlib.md5((Hash + 'kgcloud').encode('utf-8')).hexdigest() def HighSearch(keyword): music_list = MusicSearch.search(keyword) if music_list is not None: item, items = {}, [] for music in music_list: Hash = str.lower(music['Hash'].encode('utf-8')) key_new = V2Md5(Hash) # 生成v2系統(tǒng)key try: DownUrl = MusicParse.parse(Music_api_1 + '&hash=%s&key=%s' % (Hash, key_new))['url'] item['Song'] = music['Song'].encode('utf-8') # 歌名 item['Singer'] = music['Singer'].encode('utf-8') # 歌手 item['url'] = DownUrl items.append(copy.deepcopy(item)) except KeyError: pass return items if __name__ == '__main__': HighSearch()
酷狗的爬蟲(chóng)系統(tǒng)就設(shè)計(jì)完畢了,下面開(kāi)始使用flask框架搭建前后端了。
三、引擎搭建
這個(gè)搜索引擎是基于flask框架的,設(shè)計(jì)思路比較簡(jiǎn)單,就是前端傳遞post數(shù)據(jù)(keyword)傳遞到后端,后端拿著這個(gè)keyword傳遞給爬蟲(chóng),爬蟲(chóng)把數(shù)據(jù)返回給系統(tǒng),系統(tǒng)在前端渲染出來(lái)。
代碼實(shí)現(xiàn):
# coding=utf-8 import sys from flask import Flask from flask import request, render_template from KgSpider import HighMusicSearch reload(sys) sys.setdefaultencoding('utf-8') app = Flask(__name__) @app.route('/', methods=['GET', 'POST']) def search(): if request.method == 'GET': return render_template('index.html') elif request.method == 'POST': keyword = request.form.get('keyword') items = HighMusicSearch.HighSearch(keyword) if items != None: return render_template('list.html', list=items) else: return '找不到?。?!不支持英文' else: return render_template('404.html') if __name__ == '__main__': app.run(debug=True)
四、調(diào)試
整改引擎系統(tǒng),也就設(shè)計(jì)完畢,然我們?cè)囋囆Ч?/p>
1.啟動(dòng)腳本:python run.py
2.輸入關(guān)鍵字進(jìn)行搜索
五、總結(jié)
引擎搭建完畢,也能正常的運(yùn)行了,但是這只是一個(gè)模型,完全沒(méi)有考慮,多用戶訪問(wèn)帶來(lái)的壓力,很容易崩潰,當(dāng)然經(jīng)過(guò)我的測(cè)試,發(fā)現(xiàn)只能搜索中文,英文完全無(wú)效,why?別問(wèn)我,我也不知道?。?!當(dāng)然在這里我也想說(shuō)一下,請(qǐng)尊重版權(quán)?。?!雖然我是口是心非?。。。?!
項(xiàng)目地址: 碼云項(xiàng)目地址
總結(jié)
以上所述是小編給大家介紹的Python無(wú)損音樂(lè)搜索引擎實(shí)現(xiàn)代碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- 10分鐘用Python快速搭建全文搜索引擎詳解流程
- python基于搜索引擎實(shí)現(xiàn)文章查重功能
- Python實(shí)戰(zhàn)之手寫(xiě)一個(gè)搜索引擎
- Python大批量搜索引擎圖像爬蟲(chóng)工具詳解
- 淺談?dòng)肞ython實(shí)現(xiàn)一個(gè)大數(shù)據(jù)搜索引擎
- Python搜索引擎實(shí)現(xiàn)原理和方法
- Python中使用haystack實(shí)現(xiàn)django全文檢索搜索引擎功能
- 用python做一個(gè)搜索引擎(Pylucene)的實(shí)例代碼
- 以Python的Pyspider為例剖析搜索引擎的網(wǎng)絡(luò)爬蟲(chóng)實(shí)現(xiàn)方法
- python做圖片搜索引擎并保存到本地詳情
相關(guān)文章
使用icecream實(shí)現(xiàn)優(yōu)雅調(diào)試Python代碼
在大型項(xiàng)目中,使用print()調(diào)試代碼可能導(dǎo)致終端輸出過(guò)多,難以分辨輸出結(jié)果與代碼的對(duì)應(yīng)關(guān)系,為了更清晰地調(diào)試,可以采用Icecream庫(kù),本文介紹了如何使用icecream實(shí)現(xiàn)優(yōu)雅調(diào)試Python代碼,需要的朋友可以參考下2024-08-08Python使用pandas實(shí)現(xiàn)對(duì)數(shù)據(jù)進(jìn)行特定排序
在數(shù)據(jù)分析和處理過(guò)程中,排序是一項(xiàng)常見(jiàn)而重要的操作,本文將詳細(xì)介紹如何利用pandas對(duì)數(shù)據(jù)進(jìn)行特定排序,包括基本排序、多列排序、自定義排序規(guī)則等方面的內(nèi)容,需要的可以了解下2024-03-03Python 讀寫(xiě)文件和file對(duì)象的方法(推薦)
下面小編就為大家?guī)?lái)一篇Python 讀寫(xiě)文件和file對(duì)象的方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09python?Ajenti控制面板輕松地管理所有服務(wù)器網(wǎng)站
Ajenti是一個(gè)值得擁有的管理面板,免費(fèi)開(kāi)源的管理面板工具,可以幫助你集中管理多個(gè)服務(wù)器和網(wǎng)站,Ajenti?支持?Linux、BSD、Mac?OS?X和Windows?等多個(gè)操作系統(tǒng),并且可以通過(guò)一個(gè)直觀的?Web?界面來(lái)完成各種系統(tǒng)管理任務(wù)2024-01-01Pandas實(shí)現(xiàn)在線文件和剪貼板數(shù)據(jù)讀取詳解
這篇文章主要為大家介紹的是Pandas兩種少用的讀取文件方式:讀取在線文件的數(shù)據(jù)和讀取剪貼板的數(shù)據(jù),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-06-06三個(gè)Python常用的數(shù)據(jù)清洗處理方式總結(jié)
這篇文章主要為大家詳細(xì)介紹了python數(shù)據(jù)處理過(guò)程中三個(gè)主要的數(shù)據(jù)清洗說(shuō)明,分別是缺失值/空格/重復(fù)值的數(shù)據(jù)清洗,感興趣的小伙伴可以了解一下2022-12-12Python操作RabbitMQ服務(wù)器實(shí)現(xiàn)消息隊(duì)列的路由功能
RabbitMQ是一個(gè)消息隊(duì)列服務(wù)器,這里我們針對(duì)Python+Pika+RabbitMQ的服務(wù)器端環(huán)境,來(lái)看一下如何使用Python操作RabbitMQ服務(wù)器實(shí)現(xiàn)消息隊(duì)列的路由功能2016-06-06django 數(shù)據(jù)庫(kù)返回queryset實(shí)現(xiàn)封裝為字典
這篇文章主要介紹了django 數(shù)據(jù)庫(kù)返回queryset實(shí)現(xiàn)封裝為字典,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-05-05