吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 38601|回复: 403
上一主题 下一主题
收起左侧

[Python 原创] 喜马拉雅加密算法分析

    [复制链接]
跳转到指定楼层
楼主
wshuo 发表于 2020-8-27 22:31 回帖奖励
本帖最后由 wshuo 于 2020-8-27 22:45 编辑

[md]所有源码我放到了 蓝奏云,所有人可以免费下载,知识用来共享:https://www.lanzoux.com/ibiWDg4gc2f
download.py为主入口文件,其中有两个参数你可能需要调节

self.run_t = 7
self.save_dir = r"D:\喜马拉雅"

一个是同时下载个数,一个是保存路径,剩下的需要调节最下面的整本书的albumId了,另外其中我加入了转换mp3格式的函数,不过我默认注释掉了,如果想使用可以配置ffmpeg到环境变量中去

前言

这几天一直听听评书,发现喜马拉雅上的资源很多,不过很可惜都是付费的,所以我冲了一个月会员,简单写个爬虫,爬下来几10部,够我一年听的了

开始分析

打开chrome控制台,点击播放,最先拿到的一个接口就是

https://mpay.ximalaya.com/mobile/track/pay/244130607/?device=pc

当然这个是付费的一部书,所以如果你浏览器不带 会员的cookie是访问不到的,其中的数字 244130607,这个在他们的接口中叫做 trackId, 每个音频文件对应唯一的一个 trackId
在这里插入图片描述
也就是对应这个界面的后面的数字,通过这个唯一的trackId可以获取到音频文件,那么看一下这个接口返回的内容

{
"ret": 0,
"msg": "0",
"trackId": 244130607,
"uid": 170217760,
"albumId": 30816438,
"title": "《三体》第一季 第十集 聚会与大撕裂",
"domain": "http://audiopay.cos.xmcdn.com",
"totalLength": 12780565,
"sampleDuration": 0,
"sampleLength": 0,
"isAuthorized": true,
"apiVersion": "1.0.0",
"seed": 9583,
"fileId": "27*31*44*62*1*8*6*48*52*4*6*17*16*6*35*35*6*43*25*27*48*63*58*4*50*47*60*64*15*39*59*49*2*36*48*48*16*58*18*44*2*32*12*7*52*64*51*26*29*4*22*",
"buyKey": "617574686f72697a6564",
"duration": 1578,
"ep": "20NvOoh6T39X3qwKO4cY5g5bVhg+1nfPHIQafFTmCXihnrqF2PjczO8O0auK1KJhDrJ30XMYfKJo2uz+xgwd3rwRPi5f",
"highestQualityLevel": 1,
"downloadQualityLevel": 1,
"authorizedType": 1
}

这里,我充会员了,所以可以直接用浏览器中打开这个url,其中有用的字段有了只有几个 seedfileId两个通过js加密算法计算出 m4a的路径,并拼接主域名,然后 ep 经过另一个加密算法得到url的访问参数buy_key sign token timestamp,最后将它们拼接到一起才是一个完整的 音频的url

两个js加密算法

经过我调试我分别找到了这两个加密的 js算法

  1. 计算 m4a的路径js算法:
function vt(t) {
                this._randomSeed = t,
                this.cg_hun()
            }
            vt.prototype = {
                cg_hun: function() {
                    this._cgStr = "";
                    var t = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890"
                      , e = t.length
                      , n = 0;
                    for (n = 0; n < e; n++) {
                        var r = this.ran() * t.length
                          , o = parseInt(r);
                        this._cgStr += t.charAt(o),
                        t = t.split(t.charAt(o)).join("")
                    }
                },
                cg_fun: function(t) {
                    t = t.split("*");
                    var e = ""
                      , n = 0;
                    for (n = 0; n < t.length - 1; n++)
                        e += this._cgStr.charAt(t[n]);
                    return e
                },
                ran: function() {
                    this._randomSeed = (211 * this._randomSeed + 30031) % 65536;
                    return this._randomSeed / 65536
                },

            };

c = function(t, e) {
    var n = new vt(t).cg_fun(e);
    return "/" === n[0] ? n : "/".concat(n)
}

console.log(c(9583,"27*31*44*62*1*8*6*48*52*4*6*17*16*6*35*35*6*43*25*27*48*63*58*4*50*47*60*64*15*39*59*49*2*36*48*48*16*58*18*44*2*32*12*7*52*64*51*26*29*4*22*"))

node跑一下可以得到 m4a的路径
输出:

/group3/M04/9E/88/wKgMbF4ejn2TfGPRAMMEFYoRHXs027.m4a
  1. 通过ep来计算url参数的js算法:
Z = function() {
                throw new TypeError("Invalid attempt to destructure non-iterable instance")
            }

J = function(t, e) {
var n = []
  , r = !0
  , o = !1
  , i = void 0;
try {
    for (var a, u = t[Symbol.iterator](); !(r = (a = u.next()).done) && (n.push(a.value),
    !e || n.length !== e); r = !0)
        ;
} catch (t) {
    o = !0,
    i = t
} finally {
    try {
        r || null == u.return || u.return()
    } finally {
        if (o)
            throw i
    }
}
return n
}

Q = function(t) {
if (Array.isArray(t))
    return t
}

tt = function(t, e) {
    return Q(t) || J(t, e) || Z()
}

function yt(t, e) {
    for (var n, r = [], o = 0, i = "", a = 0; 256 > a; a++)
        r[a] = a;
    for (a = 0; 256 > a; a++)
        o = (o + r[a] + t.charCodeAt(a % t.length)) % 256,
        n = r[a],
        r[a] = r[o],
        r[o] = n;
    for (var u = o = a = 0; u < e.length; u++)
        o = (o + r[a = (a + 1) % 256]) % 256,
        n = r[a],
        r[a] = r[o],
        r[o] = n,
        i += String.fromCharCode(e.charCodeAt(u) ^ r[(r[a] + r[o]) % 256]);
    return i
}

var mt = yt("xm", "Ä[üJ=†Û3áf÷N")
 gt = [19, 1, 4, 7, 30, 14, 28, 8, 24, 17, 6, 35, 34, 16, 9, 10, 13, 22, 32, 29, 31, 21, 18, 3, 2, 23, 25, 27, 11, 20, 5, 15, 12, 0, 33, 26]

bt = function(t) {

var e1 = yt(
    function(t, e) {
    for (var n = [], r = 0; r < t.length; r++) {
        for (var o = "a" <= t[r] && "z" >= t[r] ? t[r].charCodeAt() - 97 : t[r].charCodeAt() - "0".charCodeAt() + 26, i = 0; 36 > i; i++)
            if (e[i] == o) {
                o = i;
                break
            }
        n[r] = 25 < o ? String.fromCharCode(o - 26 + "0".charCodeAt()) : String.fromCharCode(o + 97)
    }
    return n.join("")
    }("d" + mt + "9",gt)
    ,
    e2 = function(t) {
        if (!t)
            return "";
        var e, n, r, o, i, a = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1];
        for (o = (t = t.toString()).length,
        r = 0,
        i = ""; r < o; ) {
            do {
                e = a[255 & t.charCodeAt(r++)]
            } while (r < o && -1 == e);if (-1 == e)
                break;
            do {
                n = a[255 & t.charCodeAt(r++)]
            } while (r < o && -1 == n);if (-1 == n)
                break;
            i += String.fromCharCode(e << 2 | (48 & n) >> 4);
            do {
                if (61 == (e = 255 & t.charCodeAt(r++)))
                    return i;
                e = a[e]
            } while (r < o && -1 == e);if (-1 == e)
                break;
            i += String.fromCharCode((15 & n) << 4 | (60 & e) >> 2);
            do {
                if (61 == (n = 255 & t.charCodeAt(r++)))
                    return i;
                n = a[n]
            } while (r < o && -1 == n);if (-1 == n)
                break;
            i += String.fromCharCode((3 & e) << 6 | n)
        }
        return i
    }(t)
    ).split("-")

console.log(e1)
}

var c = bt("20NvOoh6T39X3qwKO4cY5g5bVhg+1nfPHIQafFTmCXihnrqF2PjczO8O0auK1KJhDrJ30XMYfKJo2uz+xgwd3rwRPi5f")

这段js比较复杂,调试的时候坑死我了,不在同一个地方,导致我来回复制,最终于才把这个算法整理到这一个js文件中,依然用 node跑一下,输出:

[
  '617574686f72697a6564',
  'ef9a0678d77870843ef203d6333ce021',
  '5790',
  '1598533668'
]

这几个参数分别对应的是:buy_key sign token timestamp
有了这了两个js算法就可以完全的解析 这个接口返回的参数了。

python 代码仿写加密算法

  1. 计算 m4a路径加密算法
class vt():
    def __init__(self,t):
        self._randomSeed = t
        self.cg_hun()

    def ran(self):
        self._randomSeed = (211 * self._randomSeed + 30031) % 65536
        return self._randomSeed / 65536

    def cg_hun(self):
        self._cgStr = ""
        t = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890"
        e = len(t)
        n = 0
        for i in range(e):
            r = self.ran() * len(t)
            o = int(r)
            self._cgStr += t[o]
            t = "".join(t.split(t[o]))

    def cg_fun(self,t):
        t = [int(i) if i else 0 for i in t.split("*")]
        e = ""
        n = 0;
        for n in range(n,len(t)-1):
            e += self._cgStr[t[n]]
        return e

def path_decode(seed,fileId):
    c = vt(seed)
    p = c.cg_fun(fileId)
    return p 

if __name__ == '__main__':
    result = path_decode(9583,"27*31*44*62*1*8*6*48*52*4*6*17*16*6*35*35*6*43*25*27*48*63*58*4*50*47*60*64*15*39*59*49*2*36*48*48*16*58*18*44*2*32*12*7*52*64*51*26*29*4*22*")
    print(result)
  1. 通过ep来计算url参数的算法:
def yt(t, e):
    r = [0 for i in range(256)]
    o = 0
    i = ""
    for a in range(0,256):
        r[a] = a;
    for a in range(0,256):
        o = (o + r[a] + ord(t[a % len(t)])) % 256
        n = r[a]
        r[a] = r[o]
        r[o] = n

    u = 0
    o = 0
    a = 0
    for u in range(0,len(e)):
        a = (a + 1) % 256
        o = (o + r[a]) % 256
        n = r[a]
        r[a] = r[o]
        r[o] = n
        i += chr(ord(e[u]) ^ r[(r[a] + r[o]) % 256])
    return i

def bt(t):
    def arg1(t,e):
        n = [' ' for i in range(256)]
        for r in range(0,len(t)):

            if "a" <= t[r] and "z" >= t[r]:
                o = ord(t[r]) - 97 
            else:
                o = ord(t[r]) - ord("0") + 26
            for i in range(0,36):
                if (e[i] == o):
                    o = i
                    break

            if 25< o:
                n[r] = chr(o - 26 + ord("0")) 
            else:
                n[r] = chr(o + 97)

        return "".join(n).strip()

    a1 = arg1("d" + mt + "9", gt)
    def arg2(t):
        if not t:
            return ""

        e = n = r = o = i = a = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1];

        o = len(t)
        i = ""
        r = 0
        while r < o:
            while True:
                e = a[255 & ord(t[r])]
                r += 1
                if not (r < o and -1 == e):
                    break
            if (-1 == e):
                break
            while True:
                n = a[255 & ord(t[r])]
                r += 1
                if not (r < o and -1 == n):
                    break
            if (-1 == n):
                break
            i += chr(e << 2 | (48 & n) >> 4)
            while True:
                e = (255 & ord(t[r]))
                if 61 == e:
                    return i
                r += 1

                e = a[e]
                if not (r < o and -1 == e):
                    break
            if (-1 == e):
                break
            i += chr((15 & n) << 4 | (60 & e) >> 2);
            while True:
                n = (255 & ord(t[r]))
                if (61 == n):
                    return i
                r += 1
                n = a[n]
                if not (r < o and -1 == n):
                    break
            if (-1 == n):
                break
            i += chr((3 & e) << 6 | n)

        return i

    a2 = arg2(t)
    buy_key,sign,token,timestamp = yt(a1,a2).split('-')
    data = dict(
        buy_key=buy_key,
        sign=sign,
        token=token,
        timestamp=timestamp,
    )
    return data

mt = yt("xm", "Ä[üJ=†Û3áf÷N")
gt = [19, 1, 4, 7, 30, 14, 28, 8, 24, 17, 6, 35, 34, 16, 9, 10, 13, 22, 32, 29, 31, 21, 18, 3, 2, 23, 25, 27, 11, 20, 5, 15, 12, 0, 33, 26]

def ep_decode(ep):
    data = bt(ep)
    return data

if __name__ == '__main__':
    print(ep_decode('20NvOoh6T39X3qwKO4cY5g5bVhg+1nfPHIQafFTmCXihnrqF2PjczO8O0auK1KJhDrJ30XMYfKJo2uz+xgwd3rwRPi5f'))

这个接口到此为止才算是完全可以解析。

免费接口分析

如果你没有充会员,免费的音频还是可以听的,我找到一个免费音频的接口

https://www.ximalaya.com/revision/play/v1/audio?id=324681559&ptype=1

返回值:

{
"ret": 200,
"data": {
"trackId": 324681559,
"canPlay": true,
"isPaid": false,
"hasBuy": true,
"src": "https://aod.cos.tx.xmcdn.com/group84/M03/4A/A6/wKg5Hl8s0cTwcp6xABQ0EbeuW5Q193.m4a",
"albumIsSample": false,
"sampleDuration": 48,
"isBaiduMusic": false,
"firstPlayStatus": true,
"isVipFree": false
}
}

这个接口还是比较简单的,返回值里面直接包含 m4a音频地址,没有加密措施,另外 url中的数字依然是 trackId,值得一提的是免费音频的trackId不能用在付费接口,我猜测是版本迭代的问题,或者是客户端不同的问题,因为当时我不只是分析网页的接口,还抓包了电脑客户端的接口,具体对应的是网页还是客户端我也忘了。

解析整本书的接口

喜马拉雅接口主要关键的有两个参数,一个是前面我说的 trackId 另一个就是albumIdtrackId 对应唯一的一个音频,而 albumId 对应的是唯一的一本书。

https://www.ximalaya.com/revision/album/v1/getTracksList?albumId=30816438&pageNum=1&pageSize=1000

返回值中就有每一集的trackId,其实喜马拉雅还有很多其他接口,搜索接口等等,一般的其他的接口需要在请求头中加入xm-sign,我也写了xm-sign的计算方法:

import requests
import time
import hashlib
import random
import json
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

# 获取sign签名

def get_sign(headers):
    serverTimeUrl = "https://www.ximalaya.com/revision/time"
    response = requests.get(serverTimeUrl,headers=headers,verify=False)
    serverTime = response.text
    nowTime = str(round(time.time()*1000))

    sign = str(hashlib.md5("himalaya-{}".format(serverTime).encode()).hexdigest()) + "({})".format(str(round(random.random()*100))) + serverTime + "({})".format(str(round(random.random()*100))) + nowTime
    headers["xm-sign"] = sign
    return headers

def get_header():
    headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36"
    }    
    headers = get_sign(headers)
    return headers

if __name__ == '__main__':
        # 这是一个搜索接口
    url = "https://www.ximalaya.com/revision/search/main?core=all&spellchecker=true&device=iPhone&kw=%E9%9B%AA%E4%B8%AD%E6%82%8D%E5%88%80%E8%A1%8C&page=1&rows=20&condition=relation&fq=&paidFilter=false"
    s = requests.get(url,headers=get_header(),verify=False)
    print(s.json())

还有很多其他接口,我就懒得说了,因为我不想写了,有了这些就可以满足我下载整本书的需求了

最终整合

我写了 喜马拉雅 扫码登陆的脚本,因为我不能每次都去复制浏览器中的 cookie,这种重复劳动太傻了

import requests
import re
from threading import Thread
import time
import requests
from io import BytesIO
import http.cookiejar as cookielib
from PIL import Image
import sys
import psutil
from base64 import b64decode
import os

requests.packages.urllib3.disable_warnings()

class show_code(Thread):
    def __init__(self,data):
        Thread.__init__(self)
        self.data = data

    def run(self):
        img = Image.open(BytesIO(self.data))  # 打开图片,返回PIL image对象
        img.show()

def is_login(session):
    headers = {'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36"}
    url = "https://www.ximalaya.com/revision/main/getCurrentUser"
    try:
        session.cookies.load(ignore_discard=True)
    except Exception:
        pass
    response  = session.get(url,verify=False,headers=headers)
    if response.json()['ret'] == 200:
        print(response.json())
        return session,True
    else:
        return session,False

def login():
    if not os.path.exists(".cookie"):
        os.makedirs('.cookie')
    if not os.path.exists('.cookie/xmly.txt'):
        print("hello")
        with open(".cookie/xmly.txt",'w') as f:
            f.write("")
    session = requests.session()
    session.cookies = cookielib.LWPCookieJar(filename='.cookie/xmly.txt')
    session,status = is_login(session)
    if not status:
        url = "https://passport.ximalaya.com/web/qrCode/gen?level=L"
        response = session.get(url,verify=False)
        data = response.json()
        # with open('qrcode.jpg','wb') as f:
            # f.write(b64decode(data['img']))
        t= show_code(b64decode(data['img']))
        t.start()
        qrId = data['qrId']

        url = 'https://passport.ximalaya.com/web/qrCode/check/%s/%s' % (qrId,int(time.time()*1000))
        while 1:
            response = session.get(url,verify=False)
            data = response.json()
            # code = re.findall("window.wx_code='(.*?)'",response.text)
            # sys.exit()

            if data['ret'] == 0:
                # for proc in psutil.process_iter():  # 遍历当前process
                    # try:
                    #     if proc.name() == "Microsoft.Photos.exe":  
                    #         proc.kill()  # 关闭该process
                    # except Exception as e:
                    #     print(e)
                break
            time.sleep(1)
        session.cookies.save()
    return session
if __name__ == '__main__':
    login()

简单的一个扫码登陆脚本,如果cookie自动保存成文件,下次使用的时候直接调用:

session = login()

就能在保持登陆状态下,访问各种接口

[/md]

免费评分

参与人数 219威望 +2 吾爱币 +298 热心值 +194 收起 理由
simon77 + 1 + 1 用心讨论,共获提升!
既明 + 1 我很赞同!
riwfhiu + 1 + 1 膜拜大佬
测试中…… + 1 + 1 谢谢@Thanks!
kl3337 + 1 + 1 谢谢@Thanks!
erniuvip + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
斗地主专用 + 1 + 1 谢谢@Thanks!
巴卫 + 1 + 1 谢谢@Thanks!
苦楝树的叶子 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
磐石Rj + 1 + 1 我很赞同!
人二 + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
tiankexingli + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
shujie_chen + 1 + 1 我很赞同!
墙头等红性 + 1 + 1 我很赞同!
虎爷0724 + 1 + 1 热心回复!
0槊夜人0 + 1 + 1 用心讨论,共获提升!
旺旺小小酥 + 1 + 1 我很赞同!
youku2020 + 1 + 1 谢谢@Thanks!
xxzzcc + 1 用心讨论,共获提升!
Register1128 + 1
stone009 + 1 + 1 我很赞同!
Tombl7 + 1 我很赞同!
空明哞哞霸 + 1 + 1 我很赞同!
如T初 + 1 + 1 我很赞同!
Li520pj + 1 谢谢@Thanks!
tkslxdbz + 1 我很赞同!
太阳王 + 1 我很赞同!
13815982080 + 1 我很赞同!
lyqs + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
剑自出匣匣自鸣 + 1 + 1 谢谢@Thanks!
GuiShang + 1 + 1 我很赞同!
qwer20001022 + 1 + 1 我很赞同!
SFDSN + 1 厉害!这样下载整本书籍就方便多了
wsp0801 + 1 + 1 我很赞同!
zm4032599 + 1 + 1 我很赞同!
Questionairy + 1 楼主六啊
jstt552200 + 1 我很赞同!
sculpting_time + 1 用心讨论,共获提升!
thinkcc + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
kongmu + 1 我很赞同!
cg594 + 1 + 1 用心讨论,共获提升!
COVID + 1 我很赞同!
linux28 + 1 + 1 有成品对小白最好了 哈哈
djboy110 + 1 谢谢@Thanks!
SpecteRz + 1 我很赞同!
pinhai + 1 用心讨论,共获提升!
我就看不说话 + 1 我很赞同!
Pi星神 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
兮椿 + 1 + 1 我很赞同!
ALeng52 + 1 感谢!!!
alexj + 1 + 1 谢谢@Thanks!
迷魂 + 1 + 1 谢谢@Thanks!
woshinishu + 1 + 1 谢谢@Thanks!
wxfhf520 + 1 + 1 谢谢@Thanks!
maxshihe + 1 用心讨论,共获提升!
kamv1 + 1 我很赞同!
trojansun + 1 + 1 用心讨论,共获提升!
1qwert颉 + 1 + 1 谢谢@Thanks!
0615 + 1 + 1 我很赞同!
XX木 + 1 + 1 谢谢@Thanks!楼主强大,老早想这样做!!
ssddyytt + 1 + 1 谢谢@Thanks!
young_007 + 1 + 1 我很赞同!
乔帮主 + 1 + 1 虽然看不懂,但是觉得厉害
关山月明 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
coffe000 + 1 + 1 牛人啊,小弟一定要好好学习ph
燕先生 + 1 + 1 求大佬帮忙下雪中悍刀行:))
tiidaa + 1 + 1 热心回复!
virs520 + 1 + 1 我很赞同!
小白2号 + 1 谢谢@Thanks!
mollid + 1 + 1 谢谢@Thanks!
chinabrz + 1 + 1 我很赞同!
fantasyyao + 1 谢谢@Thanks!
神de天秤 + 1 + 1 谢谢@Thanks!
messiahc + 1 谢谢@Thanks!
billkeyjian + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
爱豆豆 + 1 + 1 用心讨论,共获提升!
萌鬼出没 + 1 + 1 热心回复!
ruanzeyu + 1 我很赞同!
菠萝Pine + 1 + 1 热心回复!
fiona82 + 1 + 1 谢谢@Thanks!
Jack2002 + 1 + 1 我很赞同!
jiang8681 + 1 + 1 我很赞同!
fushouyin + 1 热心回复!
smilingk + 1 + 1 谢谢@Thanks!
年轻真是可怕 + 1 + 1 热心回复!
52pojieyangyi + 1 + 1 我很赞同!
911伟少 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
windlans + 1 + 1 用心讨论,共获提升!
一年三季 + 1 + 1 谢谢@Thanks!
429632952 + 1 + 1 我很赞同!
RainH + 1 + 1 厉害
暗夜揽月 + 1 我很赞同!
playerpj + 1 + 1 我很赞同!
jixiangyh + 1 + 1 我很赞同!
desertwind + 1 + 1 谢谢@Thanks!
Kandev + 1 用心讨论,共获提升!
huoafs + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
gy810 + 1 + 1 谢谢@Thanks!
shou0823 + 1 + 1 用心讨论,共获提升!
leafleave + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

来自 #
 楼主| wshuo 发表于 2020-8-28 22:11 |楼主
本帖最后由 wshuo 于 2020-9-16 12:30 编辑

感谢大家的支持,这里简单说明几点:
1.看到评论还有人要帮忙下载的,你下载我的代码,donwload.py文件是可以直接跑的,把你想下载的书籍数字贴进去就会全集下载,而且,如果你中间停止了再次运行也可以接着下载,而不会重新下载每一集,记得配置一下我文章开头的参数,保存路径,多线程下载同时下载个数。接口2请求头需要x-sign,所以需要把请求头改为 data = session.get(url,verify=False,headers=get_header()).json()
2. 另外很多人需要寻找加密算法的步骤,或许后期我会再写一篇文章详细的说明如何调试js,不过其实很多人不知道,真正复杂的不是调试js找到加密算法这部分,而是我用python来仿写js加密逻辑,我读不懂js的算法,但是我知道每一步的逻辑,在用每一步的逻辑仿写成python的代码,这一部分才是复杂且消耗时间的,你只要有一步js逻辑理解错误了,结果就不一致了

免费评分

参与人数 3热心值 +3 收起 理由
idou + 1 用心讨论,共获提升!
t2aonw5upmi + 1 看着好熟悉,我也仿写过
shyocean + 1 我很赞同!

查看全部评分

推荐
生如夏花之维霸 发表于 2020-9-2 11:35
不知道有没有大佬,可以打包封装出来,做成电脑应用,,方便我们有vip的人,下载使用
没有VIP的也可以用免费的接口,下载免费的音频
这样满篇的代码对于电脑小白真的太难了
小弟,在此谢谢好心的大佬了

免费评分

参与人数 5吾爱币 +4 热心值 +5 收起 理由
zhaoyf18 + 1 + 1 热心回复!
bigjack + 1 + 1 我很赞同!
yang586lin + 1 + 1 我很赞同!
v3009 + 1 我很赞同!
aa867741420 + 1 + 1 我很赞同!

查看全部评分

推荐
chenj_freedom 发表于 2020-8-28 09:14
能否具体写写那两个js算法的调试思路?或者步骤? 这个感觉才是门槛
推荐
li831203 发表于 2020-8-28 08:19
有没有喜马拉雅的安卓破解
推荐
poppinxiaonan 发表于 2020-8-28 08:11
厉害厉害&#128077;

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
catalina + 1 + 1 用心讨论,共获提升!

查看全部评分

推荐
jing19233 发表于 2020-10-13 10:02
兮椿 发表于 2020-10-13 09:05
各位有没有人像我一样,下来几本书以后就无法下载了。
我以为是路由的问题,重启了路由器还是不行。
重启 ...

喜马拉雅对PC接口有限制的:
https://www.52pojie.cn/forum.php ... 27&pid=34364899

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
兮椿 + 1 + 1 热心回复!

查看全部评分

3#
梅石楠 发表于 2020-8-27 22:37
楼主辛苦了,收藏了,相互学习
4#
修缘 发表于 2020-8-27 22:47
很棒的分享,学习了。
5#
pjrnong 发表于 2020-8-27 22:55
谢谢分享。mark 学习。
6#
跑了一下午 发表于 2020-8-27 22:59

楼主辛苦了,收藏了,相互学习
7#
pengtusheng 发表于 2020-8-27 23:45

很棒的分享,学习了。
8#
boringdog 发表于 2020-8-28 02:07
感谢楼主分享!
9#
我为52pojie狂 发表于 2020-8-28 06:52
感谢楼主提供,收藏备用~
10#
涛之雨 发表于 2020-8-28 06:52
拜见肝帝
这工作量。。。
佩服
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 11:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表