Web Spider XHR ブレークポイント スタックと値の逆のケース (3)

ここに画像の説明を挿入

声明

此次案例只为学习交流使用,抓包内容、敏感网址、数据接口均已做脱敏处理,切勿用于其他非法用途;


序文

対象のウェブサイトアドレス: aHR0cHM6Ly9tdXNpYy45MXEuY29tLw==


提示:以下是本篇文章正文内容,下面案例可供参考

1.リソースの推奨

JS の逆暗号化および復号化ツールをダウンロードして使用します: https://blog.csdn.net/EXIxiaozhou/article/details/128034062

2. ミッションステートメント

1. 歌手名や曲名などのキーワードを入力して関連情報を取得します;
2. プラットフォームの曲 ID を入力して曲のダウンロードを完了します;
ここに画像の説明を挿入
最終結果
ここに画像の説明を挿入

3. ウェブサイト分析

実装のアイデア

  • 1. キーワード検索で曲情報を取得;
  • 2. 曲の再生リンクを取得するために、曲 ID を介してインターフェイスを要求します。
  • 3.曲の再生リンクから曲をダウンロードします。

1. Web サイトを開き、ホームページの検索ボックスにキーワードを入力して Enter キーを押すと、データが Web ページにあることがわかります。検索キーワードを置き換えるだけです。

曲情報を取得するためのキーワード url: aHR0cHM6Ly9tdXNpYy45MXEuY29tL3NlYXJjaD93b3JkPcfgu6i0yQ==ここに画像の説明を挿入
データを直接見ることができます。分析モジュールを使用して目的のデータを直接抽出します
ここに画像の説明を挿入
2、曲ダウンロード チェーンの XHR インターフェイスを分析して取得し、曲の再生ページにアクセスして、ダウンロード曲のリンクは次のインターフェイスによって返されます
曲のダウンロード チェーンの XHR インターフェイス URL を取得します: aHR0cHM6Ly9tdXNpYy45MXEuY29tL3YxL3NvbmcvdHJhY2tsaW5r
ここに画像の説明を挿入
リクエストの分析時に送信されるパラメーターは GET リクエスト、sign は MD5 暗号化文字列、appid はバージョン番号、TSID曲 ID、タイムスタンプは 10 桁 タイムスタンプ
暗号化された平文データは次の文字列です。TSID とタイムスタンプの 2 つのパラメータを置き換えるだけです

f'TSID={
    
    TSID歌曲ID}&appid=16073360&timestamp={
    
    timestamp时间戳}0b50b02fd0d73a9c4c8c3a781c30845f'

ここに画像の説明を挿入
3.曲のダウンロードリンクを取得し、それを開いて直接再生します
ここに画像の説明を挿入

4. XHR ブレークポイントのデバッグ、WT-JS を使用して JS 暗号化コードを復元する

逆の考え方

  • 1. ブラウザのリソース パネルから XHR ブレークポイントを追加し、ブラウザ リクエストの前に停止させて、リクエスト パラメータを分析できるようにします。
  • 2. リソース パネルの下のコール スタックで、値をたどって暗号化されたコードを見つけます。
  • 3. 暗号化された平文を取得したら、WT-JS を使用して JS 暗号化コードを復元します。
  • 4. Python コードを介して JS コードを呼び出して、タスク全体を実現します。

1. インターフェイスの URL に従って、XHR ブレークポイントを設定します. ここでは、曲のダウンロード チェーンを取得する XHR インターフェイスを例に取ります.
ブラウザがこのインターフェイスにリクエストを送信すると、パッケージを送信する前にブレークポイントが作成されます. ;
ここに画像の説明を挿入
2. 曲の再生ページでページを更新します XHR ブレークポイントをトリガーできます. ここでコード パラメータが生成されていることがわかります. コール スタックを介して値をたどって暗号化されたコードを見つけ、それをたどる必要があります.毎回スタックから新しい関数に切り替えるのが通常のプロセスです.前のブレークポイントをキャンセルし、新しい関数でブレークポイントを再設定し、操作をリフレッシュします.
ここに画像の説明を挿入
スタックを呼び出して平文暗号化関数にここに来ます.と値、そして createSign() メソッドでブレークポイントを再設定します;
リターン時のブレークポイントに注意してください、ブレーク 前後に (値の二重カウントを避けるため)、暗号化された平文は r += の値です
ここに画像の説明を挿入
3. JS 暗号化コードを復元し、クリックして JS 暗号化コードを生成し、デバッグ用に pycharm エディターに貼り付け、pycharm を開い
ここに画像の説明を挿入
て JS 暗号化コードをデバッグします
ここに画像の説明を挿入

5. コードの実装

1. JS 暗号化コード: encode.js

var CryptoJS = CryptoJS || (function (Math, undefined) {
    
    
    var crypto;
    if (typeof window !== 'undefined' && window.crypto) {
    
    
        crypto = window.crypto;
    }
    if (typeof self !== 'undefined' && self.crypto) {
    
    
        crypto = self.crypto;
    }
    if (typeof globalThis !== 'undefined' && globalThis.crypto) {
    
    
        crypto = globalThis.crypto;
    }
    if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
    
    
        crypto = window.msCrypto;
    }
    if (!crypto && typeof global !== 'undefined' && global.crypto) {
    
    
        crypto = global.crypto;
    }
    if (!crypto && typeof require === 'function') {
    
    
        try {
    
    
            crypto = require('crypto');
        } catch (err) {
    
    }
    }
    var cryptoSecureRandomInt = function () {
    
    
        if (crypto) {
    
    
            if (typeof crypto.getRandomValues === 'function') {
    
    
                try {
    
    
                    return crypto.getRandomValues(new Uint32Array(1))[0];
                } catch (err) {
    
    }
            }
            if (typeof crypto.randomBytes === 'function') {
    
    
                try {
    
    
                    return crypto.randomBytes(4).readInt32LE();
                } catch (err) {
    
    }
            }
        }
        throw new Error('Native crypto module could not be used to get secure random number.');
    };
    var create = Object.create || (function () {
    
    
        function F() {
    
    }
        return function (obj) {
    
    
            var subtype;
            F.prototype = obj;
            subtype = new F();
            F.prototype = null;
            return subtype;
        };
    }());
    var C = {
    
    };
    var C_lib = C.lib = {
    
    };
    var Base = C_lib.Base = (function () {
    
    
        return {
    
    
            extend: function (overrides) {
    
    
                var subtype = create(this);
                if (overrides) {
    
    
                    subtype.mixIn(overrides);
                }
                if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
    
    
                    subtype.init = function () {
    
    
                        subtype.$super.init.apply(this, arguments);
                    };
                }
                subtype.init.prototype = subtype;
                subtype.$super = this;
                return subtype;
            }, create: function () {
    
    
                var instance = this.extend();
                instance.init.apply(instance, arguments);
                return instance;
            }, init: function () {
    
    }, mixIn: function (properties) {
    
    
                for (var propertyName in properties) {
    
    
                    if (properties.hasOwnProperty(propertyName)) {
    
    
                        this[propertyName] = properties[propertyName];
                    }
                }
                if (properties.hasOwnProperty('toString')) {
    
    
                    this.toString = properties.toString;
                }
            }, clone: function () {
    
    
                return this.init.prototype.extend(this);
            }
        };
    }());
    var WordArray = C_lib.WordArray = Base.extend({
    
    
        init: function (words, sigBytes) {
    
    
            words = this.words = words || [];
            if (sigBytes != undefined) {
    
    
                this.sigBytes = sigBytes;
            } else {
    
    
                this.sigBytes = words.length * 4;
            }
        }, toString: function (encoder) {
    
    
            return (encoder || Hex).stringify(this);
        }, concat: function (wordArray) {
    
    
            var thisWords = this.words;
            var thatWords = wordArray.words;
            var thisSigBytes = this.sigBytes;
            var thatSigBytes = wordArray.sigBytes;
            this.clamp();
            if (thisSigBytes % 4) {
    
    
                for (var i = 0; i < thatSigBytes; i++) {
    
    
                    var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
                    thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
                }
            } else {
    
    
                for (var j = 0; j < thatSigBytes; j += 4) {
    
    
                    thisWords[(thisSigBytes + j) >>> 2] = thatWords[j >>> 2];
                }
            }
            this.sigBytes += thatSigBytes;
            return this;
        }, clamp: function () {
    
    
            var words = this.words;
            var sigBytes = this.sigBytes;
            words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
            words.length = Math.ceil(sigBytes / 4);
        }, clone: function () {
    
    
            var clone = Base.clone.call(this);
            clone.words = this.words.slice(0);
            return clone;
        }, random: function (nBytes) {
    
    
            var words = [];
            var r = (function (m_w) {
    
    
                var m_w = m_w;
                var m_z = 0x3ade68b1;
                var mask = 0xffffffff;
                return function () {
    
    
                    m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask;
                    m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask;
                    var result = ((m_z << 0x10) + m_w) & mask;
                    result /= 0x100000000;
                    result += 0.5;
                    return result * (Math.random() > .5 ? 1 : -1);
                }
            });
            var RANDOM = false, _r;
            try {
    
    
                cryptoSecureRandomInt();
                RANDOM = true;
            } catch (err) {
    
    }
            for (var i = 0, rcache; i < nBytes; i += 4) {
    
    
                if (!RANDOM) {
    
    
                    _r = r((rcache || Math.random()) * 0x100000000);
                    rcache = _r() * 0x3ade67b7;
                    words.push((_r() * 0x100000000) | 0);
                    continue;
                }
                words.push(cryptoSecureRandomInt());
            }
            return new WordArray.init(words, nBytes);
        }
    });
    var C_enc = C.enc = {
    
    };
    var Hex = C_enc.Hex = {
    
    
        stringify: function (wordArray) {
    
    
            var words = wordArray.words;
            var sigBytes = wordArray.sigBytes;
            var hexChars = [];
            for (var i = 0; i < sigBytes; i++) {
    
    
                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
                hexChars.push((bite >>> 4).toString(16));
                hexChars.push((bite & 0x0f).toString(16));
            }
            return hexChars.join('');
        }, parse: function (hexStr) {
    
    
            var hexStrLength = hexStr.length;
            var words = [];
            for (var i = 0; i < hexStrLength; i += 2) {
    
    
                words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
            }
            return new WordArray.init(words, hexStrLength / 2);
        }
    };
    var Latin1 = C_enc.Latin1 = {
    
    
        stringify: function (wordArray) {
    
    
            var words = wordArray.words;
            var sigBytes = wordArray.sigBytes;
            var latin1Chars = [];
            for (var i = 0; i < sigBytes; i++) {
    
    
                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
                latin1Chars.push(String.fromCharCode(bite));
            }
            return latin1Chars.join('');
        }, parse: function (latin1Str) {
    
    
            var latin1StrLength = latin1Str.length;
            var words = [];
            for (var i = 0; i < latin1StrLength; i++) {
    
    
                words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
            }
            return new WordArray.init(words, latin1StrLength);
        }
    };
    var Utf8 = C_enc.Utf8 = {
    
    
        stringify: function (wordArray) {
    
    
            try {
    
    
                return decodeURIComponent(escape(Latin1.stringify(wordArray)));
            } catch (e) {
    
    
                throw new Error('Malformed UTF-8 data');
            }
        }, parse: function (utf8Str) {
    
    
            return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
        }
    };
    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
    
    
        reset: function () {
    
    
            this._data = new WordArray.init();
            this._nDataBytes = 0;
        }, _append: function (data) {
    
    
            if (typeof data == 'string') {
    
    
                data = Utf8.parse(data);
            }
            this._data.concat(data);
            this._nDataBytes += data.sigBytes;
        }, _process: function (doFlush) {
    
    
            var processedWords;
            var data = this._data;
            var dataWords = data.words;
            var dataSigBytes = data.sigBytes;
            var blockSize = this.blockSize;
            var blockSizeBytes = blockSize * 4;
            var nBlocksReady = dataSigBytes / blockSizeBytes;
            if (doFlush) {
    
    
                nBlocksReady = Math.ceil(nBlocksReady);
            } else {
    
    
                nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
            }
            var nWordsReady = nBlocksReady * blockSize;
            var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
            if (nWordsReady) {
    
    
                for (var offset = 0; offset < nWordsReady; offset += blockSize) {
    
    
                    this._doProcessBlock(dataWords, offset);
                }
                processedWords = dataWords.splice(0, nWordsReady);
                data.sigBytes -= nBytesReady;
            }
            return new WordArray.init(processedWords, nBytesReady);
        }, clone: function () {
    
    
            var clone = Base.clone.call(this);
            clone._data = this._data.clone();
            return clone;
        }, _minBufferSize: 0
    });
    var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
    
    
        cfg: Base.extend(),
        init: function (cfg) {
    
    
            this.cfg = this.cfg.extend(cfg);
            this.reset();
        }, reset: function () {
    
    
            BufferedBlockAlgorithm.reset.call(this);
            this._doReset();
        }, update: function (messageUpdate) {
    
    
            this._append(messageUpdate);
            this._process();
            return this;
        }, finalize: function (messageUpdate) {
    
    
            if (messageUpdate) {
    
    
                this._append(messageUpdate);
            }
            var hash = this._doFinalize();
            return hash;
        }, blockSize: 512 / 32,
        _createHelper: function (hasher) {
    
    
            return function (message, cfg) {
    
    
                return new hasher.init(cfg).finalize(message);
            };
        }, _createHmacHelper: function (hasher) {
    
    
            return function (message, key) {
    
    
                return new C_algo.HMAC.init(hasher, key).finalize(message);
            };
        }
    });
    var C_algo = C.algo = {
    
    };
    return C;
}(Math));

(function (Math) {
    
    
    var C = CryptoJS;
    var C_lib = C.lib;
    var WordArray = C_lib.WordArray;
    var Hasher = C_lib.Hasher;
    var C_algo = C.algo;
    var T = [];
    (function () {
    
    
        for (var i = 0; i < 64; i++) {
    
    
            T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
        }
    }());
    var MD5 = C_algo.MD5 = Hasher.extend({
    
    
        _doReset: function () {
    
    
            this._hash = new WordArray.init([0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]);
        }, _doProcessBlock: function (M, offset) {
    
    
            for (var i = 0; i < 16; i++) {
    
    
                var offset_i = offset + i;
                var M_offset_i = M[offset_i];
                M[offset_i] = ((((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00));
            }
            var H = this._hash.words;
            var M_offset_0 = M[offset + 0];
            var M_offset_1 = M[offset + 1];
            var M_offset_2 = M[offset + 2];
            var M_offset_3 = M[offset + 3];
            var M_offset_4 = M[offset + 4];
            var M_offset_5 = M[offset + 5];
            var M_offset_6 = M[offset + 6];
            var M_offset_7 = M[offset + 7];
            var M_offset_8 = M[offset + 8];
            var M_offset_9 = M[offset + 9];
            var M_offset_10 = M[offset + 10];
            var M_offset_11 = M[offset + 11];
            var M_offset_12 = M[offset + 12];
            var M_offset_13 = M[offset + 13];
            var M_offset_14 = M[offset + 14];
            var M_offset_15 = M[offset + 15];
            var a = H[0];
            var b = H[1];
            var c = H[2];
            var d = H[3];
            a = FF(a, b, c, d, M_offset_0, 7, T[0]);
            d = FF(d, a, b, c, M_offset_1, 12, T[1]);
            c = FF(c, d, a, b, M_offset_2, 17, T[2]);
            b = FF(b, c, d, a, M_offset_3, 22, T[3]);
            a = FF(a, b, c, d, M_offset_4, 7, T[4]);
            d = FF(d, a, b, c, M_offset_5, 12, T[5]);
            c = FF(c, d, a, b, M_offset_6, 17, T[6]);
            b = FF(b, c, d, a, M_offset_7, 22, T[7]);
            a = FF(a, b, c, d, M_offset_8, 7, T[8]);
            d = FF(d, a, b, c, M_offset_9, 12, T[9]);
            c = FF(c, d, a, b, M_offset_10, 17, T[10]);
            b = FF(b, c, d, a, M_offset_11, 22, T[11]);
            a = FF(a, b, c, d, M_offset_12, 7, T[12]);
            d = FF(d, a, b, c, M_offset_13, 12, T[13]);
            c = FF(c, d, a, b, M_offset_14, 17, T[14]);
            b = FF(b, c, d, a, M_offset_15, 22, T[15]);
            a = GG(a, b, c, d, M_offset_1, 5, T[16]);
            d = GG(d, a, b, c, M_offset_6, 9, T[17]);
            c = GG(c, d, a, b, M_offset_11, 14, T[18]);
            b = GG(b, c, d, a, M_offset_0, 20, T[19]);
            a = GG(a, b, c, d, M_offset_5, 5, T[20]);
            d = GG(d, a, b, c, M_offset_10, 9, T[21]);
            c = GG(c, d, a, b, M_offset_15, 14, T[22]);
            b = GG(b, c, d, a, M_offset_4, 20, T[23]);
            a = GG(a, b, c, d, M_offset_9, 5, T[24]);
            d = GG(d, a, b, c, M_offset_14, 9, T[25]);
            c = GG(c, d, a, b, M_offset_3, 14, T[26]);
            b = GG(b, c, d, a, M_offset_8, 20, T[27]);
            a = GG(a, b, c, d, M_offset_13, 5, T[28]);
            d = GG(d, a, b, c, M_offset_2, 9, T[29]);
            c = GG(c, d, a, b, M_offset_7, 14, T[30]);
            b = GG(b, c, d, a, M_offset_12, 20, T[31]);
            a = HH(a, b, c, d, M_offset_5, 4, T[32]);
            d = HH(d, a, b, c, M_offset_8, 11, T[33]);
            c = HH(c, d, a, b, M_offset_11, 16, T[34]);
            b = HH(b, c, d, a, M_offset_14, 23, T[35]);
            a = HH(a, b, c, d, M_offset_1, 4, T[36]);
            d = HH(d, a, b, c, M_offset_4, 11, T[37]);
            c = HH(c, d, a, b, M_offset_7, 16, T[38]);
            b = HH(b, c, d, a, M_offset_10, 23, T[39]);
            a = HH(a, b, c, d, M_offset_13, 4, T[40]);
            d = HH(d, a, b, c, M_offset_0, 11, T[41]);
            c = HH(c, d, a, b, M_offset_3, 16, T[42]);
            b = HH(b, c, d, a, M_offset_6, 23, T[43]);
            a = HH(a, b, c, d, M_offset_9, 4, T[44]);
            d = HH(d, a, b, c, M_offset_12, 11, T[45]);
            c = HH(c, d, a, b, M_offset_15, 16, T[46]);
            b = HH(b, c, d, a, M_offset_2, 23, T[47]);
            a = II(a, b, c, d, M_offset_0, 6, T[48]);
            d = II(d, a, b, c, M_offset_7, 10, T[49]);
            c = II(c, d, a, b, M_offset_14, 15, T[50]);
            b = II(b, c, d, a, M_offset_5, 21, T[51]);
            a = II(a, b, c, d, M_offset_12, 6, T[52]);
            d = II(d, a, b, c, M_offset_3, 10, T[53]);
            c = II(c, d, a, b, M_offset_10, 15, T[54]);
            b = II(b, c, d, a, M_offset_1, 21, T[55]);
            a = II(a, b, c, d, M_offset_8, 6, T[56]);
            d = II(d, a, b, c, M_offset_15, 10, T[57]);
            c = II(c, d, a, b, M_offset_6, 15, T[58]);
            b = II(b, c, d, a, M_offset_13, 21, T[59]);
            a = II(a, b, c, d, M_offset_4, 6, T[60]);
            d = II(d, a, b, c, M_offset_11, 10, T[61]);
            c = II(c, d, a, b, M_offset_2, 15, T[62]);
            b = II(b, c, d, a, M_offset_9, 21, T[63]);
            H[0] = (H[0] + a) | 0;
            H[1] = (H[1] + b) | 0;
            H[2] = (H[2] + c) | 0;
            H[3] = (H[3] + d) | 0;
        }, _doFinalize: function () {
    
    
            var data = this._data;
            var dataWords = data.words;
            var nBitsTotal = this._nDataBytes * 8;
            var nBitsLeft = data.sigBytes * 8;
            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
            var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
            var nBitsTotalL = nBitsTotal;
            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ((((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00));
            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ((((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00));
            data.sigBytes = (dataWords.length + 1) * 4;
            this._process();
            var hash = this._hash;
            var H = hash.words;
            for (var i = 0; i < 4; i++) {
    
    
                var H_i = H[i];
                H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
            }
            return hash;
        }, clone: function () {
    
    
            var clone = Hasher.clone.call(this);
            clone._hash = this._hash.clone();
            return clone;
        }
    });
    function FF(a, b, c, d, x, s, t) {
    
    
        var n = a + ((b & c) | (~b & d)) + x + t;
        return ((n << s) | (n >>> (32 - s))) + b;
    }
    function GG(a, b, c, d, x, s, t) {
    
    
        var n = a + ((b & d) | (c & ~d)) + x + t;
        return ((n << s) | (n >>> (32 - s))) + b;
    }
    function HH(a, b, c, d, x, s, t) {
    
    
        var n = a + (b ^ c ^ d) + x + t;
        return ((n << s) | (n >>> (32 - s))) + b;
    }
    function II(a, b, c, d, x, s, t) {
    
    
        var n = a + (c ^ (b | ~d)) + x + t;
        return ((n << s) | (n >>> (32 - s))) + b;
    }
    C.MD5 = Hasher._createHelper(MD5);
    C.HmacMD5 = Hasher._createHmacHelper(MD5);
}(Math));

function MD5_Encrypt(word) {
    
    
    return CryptoJS.MD5(word).toString();
    //反转:
    //return CryptoJS.MD5(word).toString().split("").reverse().join("");
}

2. execjs モジュールが JS コードを呼び出す

import execjs
with open(file='encode.js', mode='r', encoding='utf-8') as fis:
     js_code = fis.read()  # 读取JS代码文件
js_obj = execjs.compile(js_code)  # 激将JS代码传入
js_obj.call('function', 'params')  # 调用JS的函数, 参数1:函数名、参数2:该函数所需要的参数

3. 詳細は公式アカウント【プログラマー シャオジョウ】にご注目ください。

6. Pip モジュールのインストール

ミラーアドレス

  • 清華: https://pypi.tuna.tsinghua.edu.cn/simple
  • アリババクラウド: http://mirrors.aliyun.com/pypi/simple/
  • 中国科学技術大学 https://pypi.mirrors.ustc.edu.cn/simple/
  • 華中科技大学: http://pypi.hustunique.com/
  • 山東工科大学: http://pypi.sdutlinux.org/
  • 豆板: http://pypi.douban.com/simple/

ケースで使用されているサードパーティ製モジュールと対応するバージョン

  • リクエスト==2.27.0
  • PyExecJS==1.5.1
  • lxml==4.9.1

pip 指定モジュールのインストール: pip install モジュール名 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip 指定 requirements.txt ファイルのインストール: pip install -i https://pypi.doubanio.com/simple/ -r 要件.txt


知らせ

この記事のすべてのコンテンツは学習とコミュニケーションのみを目的としています. キャプチャされたパケットの内容, 機密性の高い URL, データ インターフェースは減感されています. 商用または違法な目的で使用することは固く禁じられています. それ以外の場合, そこから生じるすべての結果は何もありません侵害がある場合は、すぐに削除するよう私に連絡してください。

本記事を無断転載、改変して二次配布することを禁じます 本記事で説明した技術の無断使用による事故等について、作者は一切の責任を負わないものとします. 侵害等があった場合は、直ちに作者までご連絡ください.公式アカウント【プログラマーXiaozhou】を削除!

おすすめ

転載: blog.csdn.net/EXIxiaozhou/article/details/128712138