突破喜馬拉雅sign簽名反爬

喜馬拉雅

網頁分析

1
2
3
4
5
6
7
8
-  打開咱們要爬取的音樂專輯https: / / www.ximalaya.com / ertong / 424529 /
-  F12打開開發者工具
-  點擊XHR 隨便點擊一首歌曲會看到存儲全部歌曲的地址【json格式】
-  正常狀況下咱們直接用requests請求上面的地址就能夠直接獲取歌曲的全部信息<br> -  咱們拿着上面獲取的地址向瀏覽器發起請求,發現沒有返回任何信息
-  咱們查看請求頭中的信息發現有一個xm - sign參數,值爲加密後的字符串,就是這個參數使咱們獲取不到數據
-  31a0dbb5916dfe85d62d8fa5988efc43 ( 36 ) 1563537528652 ( 26 ) 1563537531252
-  後面的時間戳爲服務器時間戳和系統當前時間戳,計算過時時間
-  咱們分析出xm - sign參數的加密規則,每次請求都在headers加上咱們本身生成的xm - sign參數便可
加密方式:
ximalaya-時間戳(sha1加密) + (100之內隨機生成一個數) + 服務器時間 + (100之內隨機生成一個數) + 系統當前時間

校驗方式:
ximalaya-時間戳(sha1加密) + 服務器時間 

獲取地址

請求地址

告訴咱們沒有標誌,此時感受咱們在請求時少了點參數,去查看請求頭html

查看請求頭

後端邏輯代碼

1
2
3
4
5
-  下載安裝node.js   https: / / nodejs.org / en / download /     安裝方式:<a href = "https://blog.csdn.net/cai454692590/article/details/86093297" >https: / / blog.csdn.net / cai454692590 / article / details / 86093297 < / a>
-  獲取服務器時間戳
-  調用js代碼中的函數生成xm - sign參數
-  在headrs中加上生成的xm - sign參數像瀏覽器發起請求
-  獲取數據進行持久化

js代碼須要改的

目標地址:

加密方式:

代碼實現

安裝pyexecjs模塊node

1
pip install pyexecjs

猛擊下載js代碼python

# -*- coding: utf-8 -*-
# @Time    : 2019/7/19 19:05
import requests
import os
import re
from bs4 import BeautifulSoup
import lxml
import json
import execjs   # 操做js代碼的庫

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36',
    'Accept': 'text/html,application/xhtml+ xml,application/xml;q = 0.9,image/webp,image/apng,*/*;q=0.8, application/signe-exchange;v = b3',
    'Host': 'www.ximalaya.com'
}

'''爬取喜馬拉雅服務器系統時間戳,用於生成xm-sign'''
def getxmtime():
    url="https://www.ximalaya.com/revision/time"
    response = requests.get(url, headers=headers)
    html = response.text
    return html

'''利用xmSign.js生成xm-sign'''
def exec_js():
    #獲取喜馬拉雅系統時間戳
    time = getxmtime()

    #讀取同一路徑下的js文件
    with open('xmSign.js',"r",encoding='utf-8') as f:
        js = f.read()

    # 經過compile命令轉成一個js對象
    docjs = execjs.compile(js)
    # 調用js的function生成sign
    res = docjs.call('python',time)
    return res

"""獲取專輯一共有多少頁"""
def getPage():
    url = "https://www.ximalaya.com/ertong/424529/"
    html = requests.get(url,headers=headers).text
    # 建立BeautifulSoup對象
    suop = BeautifulSoup(html,'lxml')  # 實例化對象,使用lxml進行解析
    # 根據屬性獲取 最大頁碼
    max_page = suop.find("input",placeholder="請輸入頁碼").attrs["max"]
    return max_page


response_list = []
"""請求歌曲源地址"""
def gethtml():
    # 調用exec_js函數生成xm-sign
    xm_sign = exec_js()
    # 將生成的xm-sign添加到請求投中
    headers["xm-sign"] = xm_sign
    max_page = getPage()
    for page in range(1,int(max_page)+1):
        url = "https://www.ximalaya.com/revision/play/album?albumId=424529&pageNum={}&sort=1&pageSize=30".format(page)
        # 下載
        response= requests.get(url,headers=headers).text
        response = json.loads(response)
        response_list.append(response)

"""數據持久化"""
def write_data():
    # 請求歌曲地址拿到響應數據json
    gethtml()
    for res in response_list:
        data_list = res["data"]["tracksAudioPlay"]
        for data in data_list:
            trackName = data["trackName"] # 歌名
            trackCoverPath = data["trackCoverPath"] # 封面地址
            music_path = data["src"] # url
            print(trackName,trackCoverPath,music_path)
write_data()

下載音頻
下載音頻

相關文章
相關標籤/搜索