您好,登錄后才能下訂單哦!
這篇文章主要介紹“如何使用JS逆向方法”,在日常操作中,相信很多人在如何使用JS逆向方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何使用JS逆向方法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
就是一個 html 表格, 熟悉的應該就直接能看出來, 然后還有img標簽, a標簽之類的。
當我們用chrome瀏覽器 (推薦用谷歌) 進入網易云官網,找到一首你喜歡的歌。
打開 f12 功能, 點擊 XHR 過濾, 這個時候,我們點擊播放, 在右側就會重新捕獲到新的網絡請求,其中就包括我們需要的歌曲文件鏈接。就像這樣。
v1?csrf … 這個網址就是剛刷的, 在響應中可以看到,有個url,你復制打開,就可以直接播放, 我們點擊一下headers看看怎么發送的。
請求了request url , 用post發送, 下面有2個參數表單 params 和 encSecKey 貌似我們有下面2個參數就可以直接發送請求了, 所以直接就嘗試了一下。
def spider(self): """ 這是爬取一首歌的方式, 復制params就可以發送請求 """ r = requests.post(self.params_url, params=self.params) if r.status_code == 200: mp3 = r.json().get("data")[0].get("url") rmp3 = requests.get(mp3, headers={"user-agent": self.ua}) if rmp3.status_code == 200: with open("像魚.mp3", 'wb') as ;fw: ;fw.write(rmp3.content) print("下載成功")
最后成功下載。
也就是說,我們只需要知道這二個參數怎么來的,就可以自己構造了,那就想怎么就怎么了,這個時候,我們就可以打開瀏覽器自帶的調試功能了。要打斷點,要debug, 怎么打,怎么斷? 仔細點看我圖的注釋就可以了。
還是之前的包, 你點擊第四個 initiator 就會刷新出很多和他有關系的文件, 我們點擊第一個。
然后就來到這樣, 還記得之前的二個參數吧, 在這里我們直接 ctrl + f 找其中的一個參數。
這里可以看到 params , encSecKey 都是根據 bvz7s 來的, 而bvz7s 是根據 window.asrsea() 函數來的, 所以在這個 函數打一個斷點, 繼續看下一個搜索點
在這里,我們發現window.asrsea = d 所以就得看 d 函數,在d函數的語氣中,我們都可以打上斷點,以便觀察清楚。 打上斷電之后, 刷新頁面,等待一段時間。
之后就到第一個斷點處, 然后 f8 跳到下一個斷點
然后就可以發現 d 接受的4個參數是什么了, (d, e, f, g) 在右側我們也可以看到,多次測試發現,后面三個是加密參數,固定值,所以復制拿過來用就可以了, 對于第一個d = {“csrf_token”:"…"} 這個是用來記錄你是否登入賬號, 如果你沒有登陸, 那就是空。
繼續f8 跳轉到最后
發現就是把最開始接受的4個參數,然后經過a, b, b, c 函數處理就可以了,那待會我們就要看看每個函數有什么作用,這就涉及到他們的加密方式了,但是在這里,就要思考一個問題了,關于最開始的4個參數, 就一個d會變, 其他都沒變化, 而且d還是一個空或者亂七八糟的的數字, 那他是怎么知道我是哪一首歌? 哪個歌手,所以這個參數一定有問題, (后面經過加密測試,發現加密后參數長度少了很多) 所以在這里我就繼續 調試了一下, 一樣的操作。
調試一圈了,最后終于有一個靠譜的了,有歌曲的id 還有歌曲的音質, 其他的,如果不熟悉,可以每一個d都去試試,直到加密參數正確。
所以先確定d為
"{"ids":"[1459950258]","level":"standard","encodeType":"aac","csrf_token":"59098e191e8babbaef83f1b8bbbe5987"}"
姑且就用這個d參數去加密嘗試一次吧。
回到之前d函數的區域,就在d的上面,我們就可以看到a,b,c 函數的執行過程。
我們只需要一個個了解好,然后用python語言轉換一下就可以了。下面分模塊講這些。
function a(a) { var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = ""; for (d = 0; a > d; d += 1) e = Math.random() * b.length, e = Math.floor(e), c += b.charAt(e); return c }
熟悉的一看就知道, a函數接受一個a參數, 然后再一次循環中, 循環一次為a次, 然后從 b中 隨機的挑選一些字符, 最后用字符串的形式返回, 對于Javascript來說,隨機沒那么容易,他需要用 random 生成 (0, 1) 的數,然后放大,取整,取值,累加,但對于python來說, 如下:
def SimulateFunctionA(self, length=None): """ @JavaScript function a(a) { var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = ""; for (d = 0; a > d; d += 1) e = Math.random() * b.length, e = Math.floor(e), c += b.charAt(e); return c } length : 16 using the python get the c """ b = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' c = random.sample(b, length) return "".join(c)
簡單.
function b(a, b) { var c = CryptoJS.enc.Utf8.parse(b) , d = CryptoJS.enc.Utf8.parse("0102030405060708") , e = CryptoJS.enc.Utf8.parse(a) , f = CryptoJS.AES.encrypt(e, c, { iv: d, mode: CryptoJS.mode.CBC }); return f.toString() }
這是一個 AES 加密, 模式 CBC, 其實剛開始我也不知道AES加密是什么東西, 后面我查看了官網文檔,參考了其他的辦法,實現了。
觀察這個函數, 接受了a,b, 其中a,b 是什么可以再函數d中看到到。
根據之前的分析, g是固定值,我們已經復制下來, d 認為是一個字符字典
"{"ids":"[1459950258]","level":"standard","encodeType":"aac","csrf_token":"59098e191e8babbaef83f1b8bbbe5987"}"
這樣,我們用python語言加入這些參數,試著模擬一下。
def SimulateFunctionB(self, d, key): """ function b(a, b) { var c = CryptoJS.enc.Utf8.parse(b) , d = CryptoJS.enc.Utf8.parse("0102030405060708") , e = CryptoJS.enc.Utf8.parse(a) , f = CryptoJS.AES.encrypt(e, c, { iv: d, mode: CryptoJS.mode.CBC }); return f.toString() } a = `"{"ids":"[1459950258]","level":"standard","encodeType":"aac","csrf_token":"59098e191e8babbaef83f1b8bbbe5987"}"` b = key = self.g(first) = SimulateFunctionA()(second) """ key = key.encode() iv = self.iv.encode() aes = AES.new(key=key, mode=AES.MODE_CBC, iv=iv) text = pad(data_to_pad=d.encode(), block_size=AES.block_size) aes_text = aes.encrypt(plaintext=text) aes_texts = base64.b64encode(aes_text).decode() return aes_texts SimulateFunticonB(d=" `"{"ids":"[1459950258]","level":"standard","encodeType":"aac","csrf_token":"59098e191e8babbaef83f
這里也是成功實現了,截圖我忘記截了。 關于如何AES加密,可以直接看我的,有時間有興趣的也可以和我一樣看官網文檔。 都行, 實現就可以了。
function c(a, b, c) { var d, e; return setMaxDigits(131), d = new RSAKeyPair(b,"",c), e = encryptedString(d, a) }
一看很簡單,其實復雜, 用到了RSA加密算法,關于RSA加密算法,我找了一些資料。
大致原理如圖:
參考文檔
我們用python這樣實現;
def SimulateFunctionC(self, random16): """ a = 131 RSA加密原理 # num = pow(x, y) % z # 加密C=M^e mod n """ e = self.e f = self.f text = random16[::-1] num = pow(int(text.encode().hex(), 16), int(e, 16), int(f, 16)) return format(num, 'x').zfill(131) # TODO: last the num change the hex digit and left fill (131)
pow() 其實是可以接受三個參數的, 如果有第三個, 第三個就為取余值, 用上int(a, 16) 就可以直接將16進制轉換為10進制, 最后的format(num, ‘x’) 將值用16進制形式輸出, 然后zfill() 填充131 位數,, (根據函數C得知 位數為131)
分析了上面三個函數, 其實我們就可以直接編寫程序加密了, 我們把程序連起來。
# -*- coding : utf-8 -*- # @Time : 2020/9/15 15:45 # @author : 沙漏在下雨# @Software : PyCharm# @CSDN : https://me.csdn.net/qq_45906219import requestsfrom get_useragent import GetUserAgentCSimport randomfrom Crypto.Util.Padding import padfrom Crypto.Cipher import AESimport base64class GetParams(object): def __init__(self): self.ua = GetUserAgentCS().get_user() self.params_url = 'https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=' self.e = "010001" self.g = "0CoJUm6Qyw8W8jud" self.iv = '0102030405060708' self.f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a" \ "876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9" \ "d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e28" \ "9dc6935b3ece0462db0a22b8e7" self.params = None def SimulateFunctionA(self, length=None): """ @JavaScript function a(a) { var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = ""; for (d = 0; a > d; d += 1) e = Math.random() * b.length, e = Math.floor(e), c += b.charAt(e); return c } length : 16 using the python get the c """ b = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' c = random.sample(b, length) return "".join(c) def SimulateFunctionB(self, d, key): """ function b(a, b) { var c = CryptoJS.enc.Utf8.parse(b) , d = CryptoJS.enc.Utf8.parse("0102030405060708") , e = CryptoJS.enc.Utf8.parse(a) , f = CryptoJS.AES.encrypt(e, c, { iv: d, mode: CryptoJS.mode.CBC }); return f.toString() } a = "{"csrf_token":""}" b = key = self.g(first) = SimulateFunctionA()(second) """ key = key.encode() iv = self.iv.encode() aes = AES.new(key=key, mode=AES.MODE_CBC, iv=iv) text = pad(data_to_pad=d.encode(), block_size=AES.block_size) aes_text = aes.encrypt(plaintext=text) aes_texts = base64.b64encode(aes_text).decode() return aes_texts def SimulateFunctionC(self, random16): """ a = 131 RSA加密原理 # num = pow(x, y) % z # 加密C=M^e mod n """ e = self.e f = self.f text = random16[::-1] num = pow(int(text.encode().hex(), 16), int(e, 16), int(f, 16)) return format(num, 'x').zfill(131) # TODO: last the num change the hex digit and left fill (131) def spider(self): """ 這是爬取一首歌的方式, 復制params就可以發送請求 """ r = requests.post(self.params_url, params=self.params) if r.status_code == 200: mp3 = r.json().get("data")[0].get("url") rmp3 = requests.get(mp3, headers={"user-agent": self.ua}) if rmp3.status_code == 200: with open("像魚.mp3", 'wb') as ;fw: ;fw.write(rmp3.content) print("下載成功") def get_encrypt_params(self, d=None): """ The function can encrypt your params if you give me a d @params: d debug your chrome browser """ i = self.SimulateFunctionA(length=16) encText = self.SimulateFunctionB(d, self.g) encText = self.SimulateFunctionB(encText, i) encSecKey = self.SimulateFunctionC(random16=i) return { "params": encText, "encSecKey": encSecKey }# a = GetParams()# a.spider()
說到底,我們還是要歌曲的id, 怎么來的,就需要繼續看下去了。
直接這樣就可以了。
如果你是進入歌手表單在這個界面,你是找不到需要的id表單數據的,在這里就要用selenium 去爬取然后分析了,
如果你在下面的情況下,就可以找到id表單數據。
還有一樣的,在這個包,我們看到參數還是params 和 encSerKey 然后重復上面操作, 打斷點調試,甚至加密方式都是一樣,不斷的打斷點,最后發現d是這樣的
{"hlpretag":"","hlposttag":"","s":"許嵩","type":"1","offset":"0","total":"true","limit":"30","csrf_token":""}
我們更改一下s的值, 歌曲名稱 歌手 都可以, 構建好這個字典, 發送這個網址,就可以得到id了, 然后拿著id去繼續構造上面的d值, 就可以拿到歌曲url了。
如下:
# -*- coding : utf-8 -*- # @Time : 2020/9/17 14:59 # @author : 沙漏在下雨# @Software : PyCharm# @CSDN : https://me.csdn.net/qq_45906219from GetParams import GetParamsimport requestsfrom get_useragent import GetUserAgentCSimport randomimport keyringimport yagmailclass DownMp3(object): def __init__(self): self.GetIdUrl = "https://music.163.com/weapi/cloudsearch/get/web?csrf_token=" self.GetMP3Url = 'https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=' self.ua = GetUserAgentCS().get_user() self.headers = {"User-Agent": self.ua} self.MUSIC_LIST = [] # The singer music demo list self.Sented_qq_email = self.get_email() def get_email(self): email_list = input("輸入QQ郵箱 如果你有多個 請用空格隔開:").split() if len(email_list) == 1: if "@qq.com" not in email_list[0]: raise Exception("郵箱規格好像不合適,你輸入的是 ", email_list[0]) else: return email_list[0] elif len(email_list) >= 2: for i in email_list: if "@qq.com" not in i: raise Exception("郵箱規格好像不合適,你輸入的是 ", i) else: pass return email_list def my_request(self, url, model="get", params=None): if model == 'post': r = requests.post(url, headers=self.headers, params=params) if r.status_code == 200: r.encoding = r.apparent_encoding s = r.json() return s elif model == 'get': r = requests.get(url, headers=self.headers, params=params) if r.status_code == 200: return r.content else: raise Exception("method is error !") def get_mp3_id_demo(self, start=None): """ get the mp3 id {"hlpretag":"<span class=\"s-fc7\">","hlposttag":"</span>","s":"本兮","type":"1","offset":"0","total":"true","limit":"30","csrf_token":""} """ if start is None: raise Exception("You should enter a start name, but you enter start =", start) d = { "hlpretag": "<span class=\"s-fc7\">", "hlposttag": "</span>", "s": str(start), "type": "1", "offset": "0", "total": "true", "limit": "30", "csrf_token": "" } params = GetParams().get_encrypt_params(str(d)) return self.my_request(self.GetIdUrl, model="post", params=params)["result"]["songs"] def get_mp3_url(self, id): """ params: id the music of id fix the id into "{"ids":"[35440198]","level":"standard","encodeType":"aac","csrf_token":""}" so we can get the music the downpath """ d = {"ids": str([id]), "level": "standard", "encodeType": "aac", "csrf_token": ""} params = GetParams().get_encrypt_params(str(d)) context = self.my_request(self.GetMP3Url, model="post", params=params) mp3_path_url = context.get("data")[0]["url"] return mp3_path_url def print_id_list(self, id_list): """ params: id_list print the singer about 30s musics """ a = {} for index, value in enumerate(id_list): a['count'] = (index + 1) a["singer_name"] = value.get("name") a["id"] = value.get("id") a["album"] = value.get("al").get("name") a["image"] = value.get("al").get("picUrl") self.MUSIC_LIST.append(a.copy()) def random_get_mp3(self): mp3Ten = random.sample(self.MUSIC_LIST, 10) # 提出十首歌 content = "" # 把數據寫入html中 方便發送 content += '<p><font size="20" color="Tan">Happy day for you !</font></p>' content += '<table border="1" style="border-collapse: collapse;">\n<caption>Today music demo </caption>\n<tr><th>序號</th><th>歌曲名</th><th>歌曲鏈接</th><th>歌曲所屬</th><th>美圖</th></tr>' count = 1 for j in mp3Ten: s = f"\n<tr><th>{count}</th><th>{j['singer_name']}</th>" \ f"<th><a href='{self.get_mp3_url(j['id'])}'>點擊播放</a></th><th>{j['album']}</th>" \ f"<th><img src='{j['image']}' alt='美圖' height='400' width='400' /></th></tr>" content += s count += 1 content += "</table>" return content def sent_email(self, content): """ sent the music demo list for you like one """ pwd = keyring.get_password("qqemail", "884427640") yag = yagmail.SMTP("884427640@qq.com", pwd, host="smtp.qq.com") # test qq 2817634007@qq.com yag.send(self.Sented_qq_email, '網易云專屬推送', content) yag.close() print("Today music already sent ok!") def start_demo(self): try: start_name = input("input a music singer or music name " "if you like it:") id_list = self.get_mp3_id_demo(start=start_name) self.print_id_list(id_list) print(self.MUSIC_LIST) self.sent_email(self.random_get_mp3()) except Exception as e: print("出現error", e, "再試一次!") self.start_demo()# 如果要運行此程序 請打開下面的注釋# a = DownMp3()# a.start_demo()
函數庫用到
import keyring
import yagmail
下載一下就可以了,
關于keyring 這是一個保存密碼的庫, 對于一些密碼來說,我們可以這樣
keyring set qq 88442764然后就會讓你輸入密碼 ,當你輸入要獲得就這樣keyring get qq 884427640 就可以了前提你的keyring.exe 在環境變量中, 當然在python中,這個也是很簡單使用的。
關于yagmail 這是一個發送郵箱的函數庫
def sent_email(self, content): """ sent the music demo list for you like one """ pwd = keyring.get_password("qqemail", "884427640") yag = yagmail.SMTP("884427640@qq.com", pwd, host="smtp.qq.com") # test qq 2817634007@qq.com yag.send(self.Sented_qq_email, '網易云專屬推送', content) yag.close() print("Today music already sent ok!")
pwd 這個是郵箱的QQ郵箱的授權碼, 很長的字符串,要去QQ郵箱里面開啟服務,所以我就放到密碼庫里面了,然后用SMTP鏈接一下郵箱, 就這樣發送就可以了。
懂點html的都應該會編寫這個。
就這樣寫一下就可以了。 發送全部代碼:# -*- coding : utf-8 -*- # @Time : 2020/9/17 14:59 # @author : 沙漏在下雨# @Software : PyCharm# @CSDN : https://me.csdn.net/qq_45906219from GetParams import GetParamsimport requestsfrom get_useragent import GetUserAgentCSimport randomimport keyringimport yagmailclass DownMp3(object): def __init__(self): self.GetIdUrl = "https://music.163.com/weapi/cloudsearch/get/web?csrf_token=" self.GetMP3Url = 'https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=' self.ua = GetUserAgentCS().get_user() self.headers = {"User-Agent": self.ua} self.MUSIC_LIST = [] # The singer music demo list self.Sented_qq_email = self.get_email() def get_email(self): email_list = input("輸入QQ郵箱 如果你有多個 請用空格隔開:").split() if len(email_list) == 1: if "@qq.com" not in email_list[0]: raise Exception("郵箱規格好像不合適,你輸入的是 ", email_list[0]) else: return email_list[0] elif len(email_list) >= 2: for i in email_list: if "@qq.com" not in i: raise Exception("郵箱規格好像不合適,你輸入的是 ", i) else: pass return email_list def my_request(self, url, model="get", params=None): if model == 'post': r = requests.post(url, headers=self.headers, params=params) if r.status_code == 200: r.encoding = r.apparent_encoding s = r.json() return s elif model == 'get': r = requests.get(url, headers=self.headers, params=params) if r.status_code == 200: return r.content else: raise Exception("method is error !") def get_mp3_id_demo(self, start=None): """ get the mp3 id {"hlpretag":"<span class=\"s-fc7\">","hlposttag":"</span>","s":"本兮","type":"1","offset":"0","total":"true","limit":"30","csrf_token":""} """ if start is None: raise Exception("You should enter a start name, but you enter start =", start) d = { "hlpretag": "<span class=\"s-fc7\">", "hlposttag": "</span>", "s": str(start), "type": "1", "offset": "0", "total": "true", "limit": "30", "csrf_token": "" } params = GetParams().get_encrypt_params(str(d)) return self.my_request(self.GetIdUrl, model="post", params=params)["result"]["songs"] def get_mp3_url(self, id): """ params: id the music of id fix the id into "{"ids":"[35440198]","level":"standard","encodeType":"aac","csrf_token":""}" so we can get the music the downpath """ d = {"ids": str([id]), "level": "standard", "encodeType": "aac", "csrf_token": ""} params = GetParams().get_encrypt_params(str(d)) context = self.my_request(self.GetMP3Url, model="post", params=params) mp3_path_url = context.get("data")[0]["url"] return mp3_path_url def print_id_list(self, id_list): """ params: id_list print the singer about 30s musics """ a = {} for index, value in enumerate(id_list): a['count'] = (index + 1) a["singer_name"] = value.get("name") a["id"] = value.get("id") a["album"] = value.get("al").get("name") a["image"] = value.get("al").get("picUrl") self.MUSIC_LIST.append(a.copy()) def random_get_mp3(self): mp3Ten = random.sample(self.MUSIC_LIST, 10) # 提出十首歌 content = "" # 把數據寫入html中 方便發送 content += '<p><font size="20" color="Tan">Happy day for you !</font></p>' content += '<table border="1" style="border-collapse: collapse;">\n<caption>Today music demo </caption>\n<tr><th>序號</th><th>歌曲名</th><th>歌曲鏈接</th><th>歌曲所屬</th><th>美圖</th></tr>' count = 1 for j in mp3Ten: s = f"\n<tr><th>{count}</th><th>{j['singer_name']}</th>" \ f"<th><a href='{self.get_mp3_url(j['id'])}'>點擊播放</a></th><th>{j['album']}</th>" \ f"<th><img src='{j['image']}' alt='美圖' height='400' width='400' /></th></tr>" content += s count += 1 content += "</table>" return content def sent_email(self, content): """ sent the music demo list for you like one """ pwd = keyring.get_password("qqemail", "884427640") yag = yagmail.SMTP("884427640@qq.com", pwd, host="smtp.qq.com") # test qq 2817634007@qq.com yag.send(self.Sented_qq_email, '網易云專屬推送', content) yag.close() print("Today music already sent ok!") def start_demo(self): try: start_name = input("input a music singer or music name " "if you like it:") id_list = self.get_mp3_id_demo(start=start_name) self.print_id_list(id_list) print(self.MUSIC_LIST) self.sent_email(self.random_get_mp3()) except Exception as e: print("出現error", e, "再試一次!") self.start_demo()# 如果要運行此程序 請打開下面的注釋# a = DownMp3()# a.start_demo() def random_get_mp3(self): mp3Ten = random.sample(self.MUSIC_LIST, 10) # 提出十首歌 content = "" # 把數據寫入html中 方便發送 content += '<p><font size="20" color="Tan">Happy day for you !</font></p>' content += '<table border="1" style="border-collapse: collapse;">\n<caption>Today music demo </caption>\n<tr><th>序號</th><th>歌曲名</th><th>歌曲鏈接</th><th>歌曲所屬</th><th>美圖</th></tr>' count = 1 for j in mp3Ten: s = f"\n<tr><th>{count}</th><th>{j['singer_name']}</th>" \ f"<th><a href='{self.get_mp3_url(j['id'])}'>點擊播放</a></th><th>{j['album']}</th>" \ f"<th><img src='{j['image']}' alt='美圖' height='400' width='400' /></th></tr>" content += s count += 1 content += "</table>" return content
就這樣寫一下就可以了。
# -*- coding : utf-8 -*- # @Time : 2020/9/17 14:59 # @author : 沙漏在下雨# @Software : PyCharm# @CSDN : https://me.csdn.net/qq_45906219from GetParams import GetParamsimport requestsfrom get_useragent import GetUserAgentCSimport randomimport keyringimport yagmailclass DownMp3(object): def __init__(self): self.GetIdUrl = "https://music.163.com/weapi/cloudsearch/get/web?csrf_token=" self.GetMP3Url = 'https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=' self.ua = GetUserAgentCS().get_user() self.headers = {"User-Agent": self.ua} self.MUSIC_LIST = [] # The singer music demo list self.Sented_qq_email = self.get_email() def get_email(self): email_list = input("輸入QQ郵箱 如果你有多個 請用空格隔開:").split() if len(email_list) == 1: if "@qq.com" not in email_list[0]: raise Exception("郵箱規格好像不合適,你輸入的是 ", email_list[0]) else: return email_list[0] elif len(email_list) >= 2: for i in email_list: if "@qq.com" not in i: raise Exception("郵箱規格好像不合適,你輸入的是 ", i) else: pass return email_list def my_request(self, url, model="get", params=None): if model == 'post': r = requests.post(url, headers=self.headers, params=params) if r.status_code == 200: r.encoding = r.apparent_encoding s = r.json() return s elif model == 'get': r = requests.get(url, headers=self.headers, params=params) if r.status_code == 200: return r.content else: raise Exception("method is error !") def get_mp3_id_demo(self, start=None): """ get the mp3 id {"hlpretag":"<span class=\"s-fc7\">","hlposttag":"</span>","s":"本兮","type":"1","offset":"0","total":"true","limit":"30","csrf_token":""} """ if start is None: raise Exception("You should enter a start name, but you enter start =", start) d = { "hlpretag": "<span class=\"s-fc7\">", "hlposttag": "</span>", "s": str(start), "type": "1", "offset": "0", "total": "true", "limit": "30", "csrf_token": "" } params = GetParams().get_encrypt_params(str(d)) return self.my_request(self.GetIdUrl, model="post", params=params)["result"]["songs"] def get_mp3_url(self, id): """ params: id the music of id fix the id into "{"ids":"[35440198]","level":"standard","encodeType":"aac","csrf_token":""}" so we can get the music the downpath """ d = {"ids": str([id]), "level": "standard", "encodeType": "aac", "csrf_token": ""} params = GetParams().get_encrypt_params(str(d)) context = self.my_request(self.GetMP3Url, model="post", params=params) mp3_path_url = context.get("data")[0]["url"] return mp3_path_url def print_id_list(self, id_list): """ params: id_list print the singer about 30s musics """ a = {} for index, value in enumerate(id_list): a['count'] = (index + 1) a["singer_name"] = value.get("name") a["id"] = value.get("id") a["album"] = value.get("al").get("name") a["image"] = value.get("al").get("picUrl") self.MUSIC_LIST.append(a.copy()) def random_get_mp3(self): mp3Ten = random.sample(self.MUSIC_LIST, 10) # 提出十首歌 content = "" # 把數據寫入html中 方便發送 content += '<p><font size="20" color="Tan">Happy day for you !</font></p>' content += '<table border="1" style="border-collapse: collapse;">\n<caption>Today music demo </caption>\n<tr><th>序號</th><th>歌曲名</th><th>歌曲鏈接</th><th>歌曲所屬</th><th>美圖</th></tr>' count = 1 for j in mp3Ten: s = f"\n<tr><th>{count}</th><th>{j['singer_name']}</th>" \ f"<th><a href='{self.get_mp3_url(j['id'])}'>點擊播放</a></th><th>{j['album']}</th>" \ f"<th><img src='{j['image']}' alt='美圖' height='400' width='400' /></th></tr>" content += s count += 1 content += "</table>" return content def sent_email(self, content): """ sent the music demo list for you like one """ pwd = keyring.get_password("qqemail", "884427640") yag = yagmail.SMTP("884427640@qq.com", pwd, host="smtp.qq.com") # test qq 2817634007@qq.com yag.send(self.Sented_qq_email, '網易云專屬推送', content) yag.close() print("Today music already sent ok!") def start_demo(self): try: start_name = input("input a music singer or music name " "if you like it:") id_list = self.get_mp3_id_demo(start=start_name) self.print_id_list(id_list) print(self.MUSIC_LIST) self.sent_email(self.random_get_mp3()) except Exception as e: print("出現error", e, "再試一次!") self.start_demo()# 如果要運行此程序 請打開下面的注釋# a = DownMp3()# a.start_demo()
擴展了一個下載一首歌的代碼,如果你需要。
# -*- coding : utf-8 -*- # @Time : 2020/9/17 21:35 # @author : 沙漏在下雨# @Software : PyCharm# @CSDN : https://me.csdn.net/qq_45906219import requestsfrom get_useragent import GetUserAgentCSfrom GetParams import GetParamsfrom DownMp3 import DownMp3class DownOneMp3(DownMp3): def __init__(self): super().__init__() self.GetIdUrl = "https://music.163.com/weapi/cloudsearch/get/web?csrf_token=" self.params_url = "https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=" self.headers = {"user-agent": GetUserAgentCS().get_user()} self.start = input("Please input the music name:") ids = self.get_id() self.params = self.get_params(id=ids) self.mp3_name = self.start + ".mp3" def my_request(self, url, model="get", params=None): """ 繼承父類的一個方法 """ return super().my_request(url, model, params) def get_params(self, id): """給出id 返回加密參數""" d = {"ids": str([id]), "level": "standard", "encodeType": "aac", "csrf_token": ""} params = GetParams().get_encrypt_params(str(d)) return params def get_id(self): """ 根據歌曲名稱獲取id """ start = self.start d = { "hlpretag": "<span class=\"s-fc7\">", "hlposttag": "</span>", "s": str(start), "type": "1", "offset": "0", "total": "true", "limit": "30", "csrf_token": "" } params = GetParams().get_encrypt_params(str(d)) return self.my_request(self.GetIdUrl, model="post", params=params)["result"]["songs"][0].get("id") def spider(self): """ 這是爬取一首歌的方式, 你只需要輸入歌曲名稱就可以 會自動調用其他類實現參數加密 id獲取等 """ import os r = requests.post(self.params_url, params=self.params) if r.status_code == 200: print(r.json()) mp3 = r.json().get("data")[0].get("url") print("music link is ", mp3) rmp3 = requests.get(mp3, headers=self.headers) if rmp3.status_code == 200: with open(self.mp3_name, 'wb') as ;fw: ;fw.write(rmp3.content) print("Down Successful! ", "file path is ", os.path.dirname(__file__)) # 如果要運行此程序 請打開下面的注釋# a = DownOneMp3()# a.spider()
""" 如果你僅僅只是想下載一首歌 跳轉到DownOneMp3模塊啟動模塊運行 如果你想多首歌發送某人郵箱 跳轉到DownMp3模塊啟動模塊運行 """
到此,關于“如何使用JS逆向方法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。