日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

開始

 

此網站F費與M費通道共用,搞定M費通道即可。

 

確立目標網址:點擊進入

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

 

 

進入到跳轉頁面:

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

可以看到出現了咱們需要的一些音樂

 

分析(x0)

 

這些音樂的源文件地址是否在咱們的網頁元素中,然后再查看網頁源代碼中是否有咱們需要的內容。(:網頁元素與網頁源代碼不一定是一樣的,網頁元素是經過瀏覽器渲染后的源代碼,而源代碼純粹就是服務器給咱們傳送過來的原始數據)

 

網頁元素中只有封面圖片的資源,沒用音頻源文件地址:

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

網頁源代碼中同樣沒有咱們需要的內容:

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

分析(x1)

 

其實沒有才正常(這種大型網站的數據不會讓你這么輕易抓取)....不過是帶大家走一遍流程,對別的網站也要這樣分析

 

那么咱們開始播放音樂抓包,看是否能抓到數據:

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

果然是經過觸發播放按鈕后,服務器傳給咱們客戶端的。(ajax)

 

而咱們抓到的這個源文件地址

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

除了這兩段外,其它的應該都是固定死的。

 

分析(x2)

 

那么我假設這兩段是從我開始訪問這首歌曲頁面的時候生成的,比如后面那串數字為這首音樂在服務器數據庫中的對應的一個ID值呢?

 

假設是合理的,不過由于咱們前面已經查看過源代碼和網頁元素中找不到這些值,我就不在這里浪費時間了。

 

分析(x3)

 

這里我和大家講一下,咱們向服務器發送一個網址請求,服務器給咱們返回的可不止一個數據包,一般都是N個數據包。當我們看到源代碼中沒有時候,也許它正悄悄地通過Ajax傳給我們了?

 

Ajax在網上有很多的解釋,但是大家未必能理解。從服務器獲得源代碼數據,然后通過瀏覽器渲染執行JAVAScript獲得一些數據(音樂)。

 

這樣說大家應該就懂了,那么咱們開始抓當前頁面的包:

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

Ajax異步請求的數據,都會在XHR中。所以直接篩選就好了。這個包我已經抓到了,get請求然后看下返回的值。

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

果然就是這個包數據都是對應的,然后打開看看里面是否有音樂源文件地址:

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

并沒有,但是有一個rid出現了兩次。

 

分析(x4)

 

那么它是否是咱們音樂的ID(索引)值?

 

接著看下面的包:

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

這個get請求很關鍵,它的參數中利用到了咱們的rid這個值

 

而他返回值里正好有咱們的音樂源文件地址:

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

通過分析獲取到音樂

 

通過咱們的分析,已經可以理清思路了。

 

首先抓取這個包獲取到rid

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

然后傳遞rid進行這個包的請求獲取到音樂文件地址

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 


某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 


某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

JavaScript繞過之參數冗余

 

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 


某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

可以看到這個rid獲取的地址中有key值是url編碼很輕松就可以解碼:

 

import requests
keywords = '%E5%BE%80%E4%BA%8B%E9%9A%8F%E9%A3%8E'
print(requests.utils.unquote(keywords))
# 往事隨風

 

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

而pn=1意思就是第一頁嘛,30就是這一頁總共30條音樂數據咯,1代表狀態碼請求成功,而最后reqId這個值如何獲取呢?

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 


某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

有能力的自己去逆向JavaScript,而咱們這里直接把這里的參數都刪除掉,同樣可以訪問到咱們的rid,為什么呢?

 

當你訪問百度的時候

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 


某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

可以看到多余了很多你看不懂的參數,而這些參數實際上可以直接刪除掉!

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

結果是一樣的,這個就叫參數冗余。

 

CSRF攻擊與防御

 

當咱們直接訪問這個鏈接卻出現這樣的畫面?

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

而咱們如果把請求頭全部放到咱們的pycharm中利用Python/ target=_blank class=infotextkey>Python模擬發送請求卻可以成功(自行測試)

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

?

 

可以看到請求中有一個參數叫csrf,這個叫做防跨站點攻擊

 

這個就好理解了,當我們用瀏覽器直接訪問的話,盡管可以帶cookies,但是咱們是沒法攜帶這個參數的。而當我們把請求頭完整地復制在pycharm中Python運行的話,就可以攜帶這個參數,那么就可以訪問。

 

目的就是保護此api防止任意情況下都可以隨便訪問。

 

而這個csrf參數不就是咱們cookies中的值么?那么是不是咱們首先需要獲取cookies?因為cookies會過期啊,為了讓你的程序永久有效,那么最好的辦法就是自動獲取cookies

 

總結

 

那么所有的原理都可以搞清楚了

 

首先訪問首頁獲取cookies,然后繞過JavaScript刪除多余的參數獲取到rid,最后通過rid進行訪問獲取到音樂源地址(這里的參數也可以刪除),最后保存數據!

某些音樂只能聽一分鐘?Python繞過反爬,完美下載音樂

 

代碼

 

"""
author: 善念
date: 2021-04-12
"""
import requests
import jsonpath
from urllib.request import urlretrieve
import urllib.parse


def get_csrf():
    # 保持cookies 維持客戶端與服務器之間的會話

    headers = {
        'Accept': 'text/html,Application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        # 'Cookie': 'Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1618229629; _ga=GA1.2.1951895595.1618229638; _gid=GA1.2.369506281.1618229638; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1618230532; kw_token=ZOMA0RIOLV',
        'Host': 'www.kuwo.cn',
        'Pragma': 'no-cache',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36',
    }
    s.get('http://www.kuwo.cn/', headers=headers)

    url = f'http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={keyword}&pn=1&rn=30&httpsStatus=1&reqId=a3b6cb30-9b8a-11eb-bc04-b33703ed2ebb'
    headers = {
        'Accept': 'application/json, text/plain, */*',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        # 'Cookie': 'Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1618229629; _ga=GA1.2.1951895595.1618229638; _gid=GA1.2.369506281.1618229638; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1618229710; kw_token=UTBATXE1HY',
        'csrf': s.cookies.get_dict()['kw_token'],
        'Host': 'www.kuwo.cn',
        'Pragma': 'no-cache',
        'Referer': f'http://www.kuwo.cn/search/list?key={keyword}',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36',


    }
    r = s.get(url, headers=headers)
    print(r.text)
    rid = jsonpath.jsonpath(r.json(), '$..rid')[0]
    print(rid)
    return rid


def get_music_url(rid):
    url = f'http://www.kuwo.cn/url?format=mp3&rid={rid}&response=url&type=convert_url3&br=128kmp3&from=web&httpsStatus=1'
    headers = {
        'Accept': 'application/json, text/plain, */*',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        # 'Cookie': 'Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1618231398; _ga=GA1.2.52993118.1618231399; _gid=GA1.2.889494894.1618231399; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1618231413; _gat=1; kw_token=VBM6N1XEG4P',
        'Host': 'www.kuwo.cn',
        'Pragma': 'no-cache',
        'Referer': f'http://www.kuwo.cn/search/list?key={keyword}',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36',
    }
    music_url = s.get(url, headers=headers).json().get('url')
    print(music_url)
    return music_url


def get_music(music_url):
    urlretrieve(music_url, f'{urllib.parse.unquote(keyword)}'+'.mp3')


def go():
    rid = get_csrf()
    music_url = get_music_url(rid)
    get_music(music_url)


if __name__ == '__main__':
    s = requests.session()
    keyword = input('請輸入您要下載的音樂名字:')
    keyword = urllib.parse.quote(keyword)
    go()


文章到這里就結束了,感謝你的閱讀,只是有些話想對讀者們說說。

分享到:
標簽:Python
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定