Python音樂爬蟲完美繞過反爬
前言
大傢好,我叫善念。
這是我的第二篇博客,也是第一篇技術博客,希望大傢多多支持,讓我更加有動力去更新一些python爬蟲類的案例教程。
開始
確立目標網址:點擊進入
進入到跳轉頁面:
可以看到出現瞭咱們需要的一些音樂
分析(x0)
這些音樂的源文件地址是否在咱們的網頁元素中,然後再查看網頁源代碼中是否有咱們需要的內容。(註:網頁元素與網頁源代碼不一定是一樣的,網頁元素是經過瀏覽器渲染後的源代碼,而源代碼純粹就是服務器給咱們傳送過來的原始數據)
網頁元素中隻有封面圖片的資源,沒用音頻源文件地址:
網頁源代碼中同樣沒有咱們需要的內容:
分析(x1)
其實沒有才正常(這種大型網站的數據不會讓你這麼輕易抓取)….不過是帶大傢走一遍流程,對別的網站也要這樣分析
那麼咱們開始播放音樂抓包,看是否能抓到數據:
果然是經過觸發播放按鈕後,服務器傳給咱們客戶端的。(ajax)
而咱們抓到的這個源文件地址
除瞭這兩段外,其它的應該都是固定死的。
分析(x2)
那麼我假設這兩段是從我開始訪問這首歌曲頁面的時候生成的,比如後面那串數字為這首音樂在服務器數據庫中的對應的一個ID值呢?
假設是合理的,不過由於咱們前面已經查看過源代碼和網頁元素中找不到這些值,我就不在這裡浪費時間瞭。
分析(x3)
這裡我和大傢講一下,咱們向服務器發送一個網址請求,服務器給咱們返回的可不止一個數據包,一般都是N個數據包。當我們看到源代碼中沒有時候,也許它正悄悄地通過Ajax傳給我們瞭?
Ajax在網上有很多的解釋,但是大傢未必能理解。從服務器獲得源代碼數據,然後通過瀏覽器渲染執行JavaScript獲得一些數據(音樂)。
這樣說大傢應該就懂瞭,那麼咱們開始抓當前頁面的包:
Ajax異步請求的數據,都會在XHR中。所以直接篩選就好瞭。這個包我已經抓到瞭,get請求然後看下返回的值。
果然就是這個包數據都是對應的,然後打開看看裡面是否有音樂源文件地址:
並沒有,但是有一個rid
出現瞭兩次。
分析(x4)
那麼它是否是咱們音樂的ID(索引)值?
接著看下面的包:
這個get請求很關鍵,它的參數中利用到瞭咱們的rid
這個值
而他返回值裡正好有咱們的音樂源文件地址:
通過分析獲取到音樂
通過咱們的分析,已經可以理清思路瞭。
首先抓取這個包獲取到rid
然後傳遞rid
進行這個包的請求獲取到音樂文件地址
JavaScript繞過之參數冗餘
可以看到這個rid
獲取的地址中有key值是url編碼很輕松就可以解碼:
import requests keywords = '%E5%BE%80%E4%BA%8B%E9%9A%8F%E9%A3%8E' print(requests.utils.unquote(keywords)) # 往事隨風
而pn=1意思就是第一頁嘛,30就是這一頁總共30條音樂數據咯,1代表狀態碼請求成功,而最後reqId
這個值如何獲取呢?
有能力的自己去逆向JavaScript,而咱們這裡直接把這裡的參數都刪除掉,同樣可以訪問到咱們的rid
,為什麼呢?
當你訪問百度的時候
可以看到多餘瞭很多你看不懂的參數,而這些參數實際上可以直接刪除掉!
結果是一樣的,這個就叫參數冗餘。
CSRF攻擊與防禦
當咱們直接訪問這個鏈接確出現這樣的畫面?
而咱們如果把請求頭全部放到咱們的pycharm中利用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音樂爬蟲完美繞過反爬的文章就介紹到這瞭,更多相關Python爬取音樂內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- python爬蟲用request庫處理cookie的實例講解
- Python爬蟲之requests庫基本介紹
- python接口自動化使用requests庫發送http請求
- Python Http發送請求淺析
- python爬蟲之requests庫的使用詳解