浅测 长亭雷池 WAF “动态防护”

本文首发于 Anyeの小站

前言

雷池 WAF 社区版的更新速度是真快啊,几乎一周一个小版本,俩月一个大版本,攻城狮们真的狠啊,没法测了。

|25%xauto

废话不多说,前两天看到了 这篇文章,对雷池的“动态防护”功能挺感兴趣,特地来试试。

安装部署

本文以测评为主,不再阐述部署过程,介绍一下我这里的测试环境:

VM1:1Panel 部署 OpenResty,部署项目 Anyeの导航 ,IP(192.168.0.220)

VM2:部署雷池 WAF 社区版,添加站点,开启“动态防护”,IP(192.168.0.225)

测试

扒取页面

通常,我会采用这种方式来复刻一个主题,最常用的就是直接从浏览器开发人员工具中扒取出页面的 html,css,js 等文件,来重制主题。

开启了雷池动态防护的页面,会有一个解密的过程,其实也就是 js 执行的过程

|100%x100%

|100%x100%

HTML

这个过程极大的延长了页面的加载时间,大致是 3s 左右。

页面打开后,对于元素发现页面构建相同,代表页面并没有因为加密而产生变形

|100%x100%

|100%x100%

可见页面已加密,不过加密也导致 索引 页面严重增大🤣,看看后期有没有希望继续优化。

JS

加密了 js 文件尝试了一下,每次返回的js加密结果都不相同。

|100%x100%

很明显是进行了混淆,不过经过文本对比后发现了端倪。

这里贴出完整 js 代码

// 源js文件
/*! * Lazy Load - JavaScript plugin for lazy loading images * * Copyright (c) 2007-2017 Mika Tuupola * * Licensed under the MIT license: *   http://www.opensource.org/licenses/mit-license.php * * Project home: *   https://appelsiini.net/projects/lazyload * * Version: 2.0.0-beta.2 * */
(function(root, factory) {
    if (typeof exports === "object") {
        module.exports = factory(root);
    } else if (typeof define === "function" && define.amd) {
        define([], factory(root));
    } else {
        root.LazyLoad = factory(root);
    }
}
)(typeof global !== "undefined" ? global : this.window || this.global, function(root) {
    "use strict";
    const defaults = {
        src: "data-src",
        srcset: "data-srcset",
        selector: ".lazyload"
    };
    /** * Merge two or more objects. Returns a new object. * @private * @param {Boolean}  deep     If true, do a deep (or recursive) merge [optional] * @param {Object}   objects  The objects to merge together * @returns {Object}          Merged values of defaults and options */
    const extend = function() {
        let extended = {};
        let deep = false;
        let i = 0;
        let length = arguments.length;
        /* Check if a deep merge */
        if (Object.prototype.toString.call(arguments[0]) === "[object Boolean]") {
            deep = arguments[0];
            i++;
        }
        /* Merge the object into the extended object */
        let merge = function(obj) {
            for (let prop in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, prop)) {
                    /* If deep merge and property is an object, merge properties */
                    if (deep && Object.prototype.toString.call(obj[prop]) === "[object Object]") {
                        extended[prop] = extend(true, extended[prop], obj[prop]);
                    } else {
                        extended[prop] = obj[prop];
                    }
                }
            }
        };
        /* Loop through each object and conduct a merge */
        for (; i < length; i++) {
            let obj = arguments[i];
            merge(obj);
        }
        return extended;
    };
    function LazyLoad(images, options) {
        this.settings = extend(defaults, options || {});
        this.images = images || document.querySelectorAll(this.settings.selector);
        this.observer = null;
        this.init();
    }
    LazyLoad.prototype = {
        init: function() {
            /* Without observers load everything and bail out early. */
            if (!root.IntersectionObserver) {
                this.loadImages();
                return;
            }
            let self = this;
            let observerConfig = {
                root: null,
                rootMargin: "0px",
                threshold: [0]
            };
            this.observer = new IntersectionObserver(function(entries) {
                entries.forEach(function(entry) {
                    if (entry.intersectionRatio > 0) {
                        self.observer.unobserve(entry.target);
                        self.loadImage(entry.target);
                    }
                });
            }
            ,observerConfig);
            this.images.forEach(function(image) {
                self.observer.observe(image);
            });
        },
        loadAndDestroy: function() {
            if (!this.settings) {
                return;
            }
            this.loadImages();
            this.destroy();
        },
        loadImage: function(image) {
            image.onerror = function() {
                image.onerror = null;
                image.src = image.srcset = image.dataset.original;
            }
            ;
            let src = image.getAttribute(this.settings.src);
            let srcset = image.getAttribute(this.settings.srcset);
            if ("img" === image.tagName.toLowerCase()) {
                if (src) {
                    image.dataset.original = image.src;
                    image.src = src;
                }
                if (srcset) {
                    image.srcset = srcset;
                }
            } else {
                image.style.backgroundImage = "url(" + src + ")";
            }
        },
        loadImages: function() {
            if (!this.settings) {
                return;
            }
            let self = this;
            this.images.forEach(function(image) {
                self.loadImage(image);
            });
        },
        destroy: function() {
            if (!this.settings) {
                return;
            }
            this.observer.disconnect();
            this.settings = null;
        }
    };
    root.lazyload = function(images, options) {
        return new LazyLoad(images,options);
    }
    ;
    if (root.jQuery) {
        const $ = root.jQuery;
        $.fn.lazyload = function(options) {
            options = options || {};
            options.attribute = options.attribute || "data-src";
            new LazyLoad($.makeArray(this),options);
            return this;
        }
        ;
    }
    return LazyLoad;
});
// 动态防护加密后的js文件
function vgo8rYXzpS() {
    var YIhUo91Nlh = 99.6174697329428;
    while (YIhUo91Nlh < 6) {
        YIhUo91Nlh++
    }
    var kJsBQ2iTCw = 77.7991427720637;
    while (kJsBQ2iTCw < 8) {
        kJsBQ2iTCw++
    }
    var Uv8SujYUUJ = 54.122410119766634;
    62.94717341414315 + 14.215159769026501;
    "eCDkWHqKcu";
    20.29250300507593 + 96.90578776550426;
    var hKDl2Z6IyR = 2.1154780179250436;
    while (hKDl2Z6IyR < 9) {
        hKDl2Z6IyR++
    }
    var jJJdYPyWC8 = 96.35369160356686;
    while (jJJdYPyWC8 < 10) {
        jJJdYPyWC8++
    }
    var q1lUq8lALI = 79.3826780702858;
    var KSm4kSmK5Q = 16.811363665066132;
    while (KSm4kSmK5Q < 5) {
        KSm4kSmK5Q++
    }
    while (q1lUq8lALI < 5) {
        q1lUq8lALI++
    }
    var k8jxtioSu1 = 46.12863667479478;
    if (k8jxtioSu1 < 50)
        VdgkMuAloP("dbKMKN3DiD");
    else
        VdgkMuAloP("Z_GUlDIf7g");
    32.61116098968565 + 39.92340222133316;
    var WOIqRFoBWI = 35.570788142150256;
    while (WOIqRFoBWI < 10) {
        WOIqRFoBWI++
    }
    var REP52ajkkB = 68.57029249635578;
    while (REP52ajkkB < 9) {
        REP52ajkkB++
    }
    var UvGT8ugsmm = 77.45257249038768;
    var c_XLMPoMhw = 70.0508383263844;
    var oXNng_nyI3 = 61.714023740614785;
    "f3dzUmlSrt";
    while (oXNng_nyI3 < 8) {
        oXNng_nyI3++
    }
    "oiou9de1Yg";
    "jdpOma9ApF";
    var NeReO5OH2M = 63.89278655453103;
    while (NeReO5OH2M < 8) {
        NeReO5OH2M++
    }
    var _p_ydR_UZY = 83.88263735619535;
    var F85mcn2g_m = 17.165604886412726;
    while (F85mcn2g_m < 10) {
        F85mcn2g_m++
    }
    24.428701219017995 + 36.33105120927406;
    var E_btPRjrmk = 95.02151619364821;
    var No5m6438qj = 4.1049208686863246;
    while (No5m6438qj < 9) {
        No5m6438qj++
    }
    while (E_btPRjrmk < 6) {
        E_btPRjrmk++
    }
    var NW66eJHW18 = 80.32092123501981;
    if (NW66eJHW18 < 50)
        VdgkMuAloP("wVsjIS9XQo");
    else
        VdgkMuAloP("GoLW5hTcVj");
    43.682142399473555 + 22.477837399452866;
    var UNuZiogsXq = 70.37483244640134;
    while (UNuZiogsXq < 6) {
        UNuZiogsXq++
    }
    var JyjoRvjvV4 = 60.33084553561216;
    "PPLO3pqrCR";
    function VdgkMuAloP() {
        "CCutBlYuiL";
        "MgmL5Sv_33";
        19.82880014765916 + 66.83450544153038;
        var eH8bW0LeRO = 91.84505170089825;
        var GGEb99P0LW = 92.75726773787632;
        "eM_DBnNLNQ";
        "LTExkL39fU";
        var ayFeMZ7J9o = 4.08422739984733;
        var rvzNYoM37B = 42.468405912837106;
        while (rvzNYoM37B < 6) {
            rvzNYoM37B++
        }
        "YLovxab17O";
        var dpUNCcw57i = 4.9146145098517575;
        while (dpUNCcw57i < 10) {
            dpUNCcw57i++
        }
        var ZjzssshCHy = 22.711581319339555;
        "lsyj2Pu6bi";
        "mAdio22F97";
        95.9152148251555 + 18.563789346616783;
        "Kisq7F_TOW";
        var EO9rGZSTTK = 53.3184198670574;
        while (EO9rGZSTTK < 6) {
            EO9rGZSTTK++
        }
        var Lfrg2SayBj = 96.40296951052316;
        var SR4gkdmFPm = 24.691037844119176;
        while (SR4gkdmFPm < 7) {
            SR4gkdmFPm++
        }
        "njAS_NShim";
        "DIoi_JwNCk";
        var qZALlgtAos = 65.84687374547939;
        while (qZALlgtAos < 5) {
            qZALlgtAos++
        }
        "i8UnwEQqP2";
        var mkzN8inJtT = 89.67717243925355;
        "EXgVlnAkaM";
        var HGgVbs9bD5 = 56.50704313244045;
        var myQFrz2kY4 = 54.55344568694437;
        while (myQFrz2kY4 < 8) {
            myQFrz2kY4++
        }
        var VcC388Sonl = 78.22901590625897;
        while (VcC388Sonl < 5) {
            VcC388Sonl++
        }
        var EDQM5T4i5x = 58.12080899105871;
        while (EDQM5T4i5x < 8) {
            EDQM5T4i5x++
        }
        var lS3HRC8N0e = 42.29800294748819;
        while (lS3HRC8N0e < 5) {
            lS3HRC8N0e++
        }
    }
}
(function(that, a) {
    var checkF = new RegExp("\\w *\\(\\){.+}");
    "Saz5menkPn";
    var checkR = new RegExp("(\\[x|u](\\w){2,4})+");
    var checkFunction = function checkFunction1() {
        if (checkR.test(checkFunction.toString())) {
            f2([2, 15, 12])
        }
        ;return '\x63\x68\x65\x63\x6b\x46\x75\x6e\x63\x74\x69\x6f\x6e'
    };
    var f1 = function f1(a) {
        a.push[a];
        f2(a)
    };
    var f2 = function f2(a) {
        a.push[a];
        f1(a)
    };
    if (!checkF.test(checkFunction.toString())) {
        f2([])
    } else if (checkR.test(checkFunction.toString())) {
        f2([1, 3, 7])
    }
    ;"ISXAG9bapu";
    var KOaO2Jk15j = 13.366279497772231;
    KOaO2Jk15j = 65.44109390187671;
    return a(that);
    function f5OTtZ1pUr() {
        "PFAZrkUkjJ";
        "yohosCBZku";
        "czcc_QG98P";
        var Y7ZMWHKbB5 = 54.61165307973092;
        while (Y7ZMWHKbB5 < 7) {
            Y7ZMWHKbB5++
        }
        "RAAE3i3HNJ";
        var yYJU5WMbNs = 81.78463513401672;
        var Dsj0YbE3nh = 60.12962678573978;
        while (Dsj0YbE3nh < 8) {
            Dsj0YbE3nh++
        }
        "OrNvH3Vm8U";
        var FcVeaK_8CJ = 70.65213865609662;
        var V10P1fXl1e = 93.28700416475893;
        while (V10P1fXl1e < 7) {
            V10P1fXl1e++
        }
        var _jQaUeEOlz = 50.09958863458343;
        while (_jQaUeEOlz < 6) {
            _jQaUeEOlz++
        }
        "mkyDT6LuXp";
        "i_d0Jej01W";
        93.1178573977863 + 65.0171586053574;
        "MdcdXdZD8e";
        var FvwOTr68cW = 63.96686898919228;
        while (FvwOTr68cW < 5) {
            FvwOTr68cW++
        }
        12.007514883700402 + 67.83201664204582;
        var lVk87OnDY0 = 10.352772574019035;
        while (lVk87OnDY0 < 10) {
            lVk87OnDY0++
        }
        "ZIxYt7RDz5";
        var HOjmKYxZYn = 73.07394273998264;
        var xf5LYnXM_h = 34.42670716048105;
        while (xf5LYnXM_h < 7) {
            xf5LYnXM_h++
        }
        25.31980979829108 + 70.92299314386324;
        53.64987099085665 + 15.95767193794893;
        81.04615728361688 + 53.03190420900158;
        "xMyhHs6tqa";
        var CicbLkYxKL = 71.43209809856342;
        while (CicbLkYxKL < 9) {
            CicbLkYxKL++
        }
        81.82768180662697 + 44.54696909044475;
        "a7S1hc6l6e";
        40.02457556515699 + 50.13884740950273
    }
}
)(this, function(that) {
    var EfanXdEsAo = 45.044183852209066;
    var YiD8rJkjM4 = 60.40560906974519;
    while (YiD8rJkjM4 < 9) {
        YiD8rJkjM4++
    }
    var SFXCSJnYT5 = 5.6590674829357;
    function DROWk3baLH() {
        var zJ2eGCAqG6 = 88.73517894514487;
        while (zJ2eGCAqG6 < 7) {
            zJ2eGCAqG6++
        }
        "fVZRgjskF7";
        var imVKfLWElR = 98.4392536479853;
        var JRZm9ZRXt9 = 65.52198475056669;
        "B07bldh2rt";
        94.61531928891331 + 21.79165407508193;
        "H7umcmyF_g";
        var kUwyNiUzjX = 48.5975080540464;
        while (kUwyNiUzjX < 5) {
            kUwyNiUzjX++
        }
        var G5q4i5ptYT = 17.20767169078439;
        while (G5q4i5ptYT < 9) {
            G5q4i5ptYT++
        }
        "S0RQAJX7ZD";
        var sbwEsBL3on = 31.621188048769;
        var Rbqnn2M5lo = 1.6814855430946412;
        var wXdYUzqLKS = 53.13735728383625;
        var iIMDA_Qowp = 87.59602310423611;
        55.899852486295956 + 23.463153124052145;
        49.64055650210554 + 21.699124979927305
    }
});
(function(root, factory) {
    if (typeof exports === "object") {
        module.exports = factory(root)
    } else if (typeof define === "function" && define.amd) {
        define([], factory(root))
    } else {
        root.LazyLoad = factory(root)
    }
    20.075305793669145 + 96.72088665263502;
    function mCbgSrID5z() {
        var ymZDdeQQne = 84.05118287547904;
        while (ymZDdeQQne < 8) {
            ymZDdeQQne++
        }
        "oeSlUltLf7";
        var vRcSMA7HZy = 95.63940228416716;
        while (vRcSMA7HZy < 5) {
            vRcSMA7HZy++
        }
        42.847416356461686 + 64.228599747433;
        var S4X325xZd0 = 36.8477478357082;
        var OjdsnE6IgU = 54.6819719737484;
        while (OjdsnE6IgU < 7) {
            OjdsnE6IgU++
        }
        var tsdIhKV6Tu = 21.849203694513204;
        "IBEZHnHB9P";
        var W1xUDNOclb = 97.45176245010938;
        var qBhKSMePxI = 53.918246237085604;
        while (qBhKSMePxI < 8) {
            qBhKSMePxI++
        }
        var tG5h3fCZpA = 8.9527278684316;
        1.8795339533222326 + 85.30147367116075;
        3.4838274267666733 + 52.70631782675951;
        var sglVSvKjZv = 13.453736652916252;
        while (sglVSvKjZv < 9) {
            sglVSvKjZv++
        }
        var bzJ8IfE03K = 72.4963090140686;
        var IzYpLOgN6D = 1.7126081902147487;
        86.90125410102027 + 60.096220564929666;
        55.32420449194843 + 93.21714769547813;
        15.44123941754805 + 88.74042551968007;
        "ayjAX7QOFR";
        "nsviM21tO7";
        "RGvq8LBnOO";
        2.5365166268296333 + 58.41895276641477;
        var NwT9TZgChj = 3.2736264569624316;
        "ZVRMQfyCrJ";
        "fwutOlKiEI";
        var Ejy2yBkKAt = 51.83509013431559;
        while (Ejy2yBkKAt < 7) {
            Ejy2yBkKAt++
        }
        92.07691206149254 + 13.437580090223227;
        "qdd7jYm20k";
        var j2KtWorODN = 42.14264503067741;
        2.478519996620122 + 58.627727544483704
    }
}
)(typeof global !== "undefined" ? global : this.window || this.global, function(root) {
    "use strict";
    var defaults = {
        src: "data-src",
        srcset: "data-srcset",
        selector: ".lazyload"
    };
    var extend = function extend1() {
        var extended = {};
        var deep = false;
        var i = 0;
        var length = arguments.length;
        if (Object.prototype.toString.call(arguments[0]) === "[object Boolean]") {
            deep = arguments[0];
            i++
        }
        var merge = function merge(obj) {
            for (var prop in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, prop)) {
                    if (deep && Object.prototype.toString.call(obj[prop]) === "[object Object]") {
                        extended[prop] = extend(true, extended[prop], obj[prop])
                    } else {
                        extended[prop] = obj[prop]
                    }
                }
            }
        };
        for (; i < length; i++) {
            var obj = arguments[i];
            merge(obj)
        }
        return extended
    };
    function LazyLoad(images, options) {
        this.settings = extend(defaults, options || {});
        this.images = images || document.querySelectorAll(this.settings.selector);
        this.observer = null;
        this.init()
    }
    LazyLoad.prototype = {
        init: function init() {
            if (!root.IntersectionObserver) {
                this.loadImages();
                return
            }
            var self = this;
            var observerConfig = {
                root: null,
                rootMargin: "0px",
                threshold: [0]
            };
            this.observer = new IntersectionObserver(function(entries) {
                entries.forEach(function(entry) {
                    if (entry.intersectionRatio > 0) {
                        self.observer.unobserve(entry.target);
                        self.loadImage(entry.target)
                    }
                })
            }
            ,observerConfig);
            this.images.forEach(function(image) {
                self.observer.observe(image)
            })
        },
        loadAndDestroy: function loadAndDestroy() {
            if (!this.settings) {
                return
            }
            this.loadImages();
            this.destroy()
        },
        loadImage: function loadImage(image) {
            image.onerror = function() {
                image.onerror = null;
                image.src = image.srcset = image.dataset.original
            }
            ;
            var src = image.getAttribute(this.settings.src);
            var srcset = image.getAttribute(this.settings.srcset);
            if ("img" === image.tagName.toLowerCase()) {
                if (src) {
                    image.dataset.original = image.src;
                    image.src = src
                }
                if (srcset) {
                    image.srcset = srcset
                }
            } else {
                image.style.backgroundImage = "url(" + src + ")"
            }
        },
        loadImages: function loadImages() {
            if (!this.settings) {
                return
            }
            var self = this;
            this.images.forEach(function(image) {
                self.loadImage(image)
            })
        },
        destroy: function destroy() {
            if (!this.settings) {
                return
            }
            this.observer.disconnect();
            this.settings = null
        }
    };
    root.lazyload = function(images, options) {
        return new LazyLoad(images,options)
    }
    ;
    if (root.jQuery) {
        var $ = root.jQuery;
        $.fn.lazyload = function(options) {
            options = options || {};
            options.attribute = options.attribute || "data-src";
            new LazyLoad($.makeArray(this),options);
            return this
        }
    }
    98.21293314139757 + 7.022202427695869;
    return LazyLoad;
    var zb5YrDEzX8 = 49.67145292566205;
    function EMQ2TiywJ2() {
        "kDDG4hcurX";
        "LmMQDl5Guf";
        "H1d2hSNdZu";
        "vR3uU0dztV";
        "BYg6Cwwew1";
        "Z7Cgb85The";
        var vqCn2LKHiQ = 79.8849526204871;
        while (vqCn2LKHiQ < 6) {
            vqCn2LKHiQ++
        }
        "HzKhtzFo0S";
        var Ruo3QF3HKv = 57.10873587557603;
        while (Ruo3QF3HKv < 8) {
            Ruo3QF3HKv++
        }
        var NIVPEUabT_ = 25.838978101412078;
        var pmvJIgXrA7 = 41.71629707156116;
        while (pmvJIgXrA7 < 7) {
            pmvJIgXrA7++
        }
        var cTqhNJmnqp = 7.679109504729966;
        var Xkldnu7eiS = 89.26080892492617;
        while (Xkldnu7eiS < 8) {
            Xkldnu7eiS++
        }
        var Iq6adjqOVj = 86.04734679658776;
        while (Iq6adjqOVj < 7) {
            Iq6adjqOVj++
        }
        var TyC7F0mXPj = 57.405394830228786;
        while (TyC7F0mXPj < 7) {
            TyC7F0mXPj++
        }
        var q7oS54FoCf = 19.715578974920984;
        6.354381716758419 + 48.514464467999424;
        var JPOOCo51Cg = 94.50513995137923;
        18.85838453981073 + 55.22787281970704;
        "rUww9Es4UQ"
    }
});

可见该加密方式采用了:

  • 变量名和函数名替换:将原有的变量名和函数名替换为难以理解的字符或字符串,例如vgo8rYXzpSYIhUo91Nlh等。
  • 字符串混淆:将代码中的字符串通过某些算法转换为难以阅读的形式。
  • 控制流改变:通过添加无意义的循环、条件判断等,改变代码的控制流,使得代码执行过程变得复杂。
  • 代码拆分:将代码拆分为多个部分,并通过某些机制动态地组合执行。

可见还是较为容易反混淆的,期待后期加强。

python 爬取

根据 官方文档 所述,动态防护还是为了可以更好地阻止爬虫和攻击自动化程序的分析,那么就尝试编写一段python代码来进行 HTML 内容爬取测试。

比如爬取 本站导航站,这里使用 Microsoft 的 playwright 库

import asyncio
from playwright.async_api import async_playwright

async def scrape_data():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()

        # 加载页面
        await page.goto('http://192.168.0.220')

        # 等待页面加载完成
        await page.wait_for_load_state('networkidle')

        # 提取链接、图标和描述
        items = await page.query_selector_all('.list-item.block')
        data = []

        for item in items:
            link = await item.query_selector('a.list-content')
            if link:
                href = await link.get_attribute('href')
                title = await link.query_selector('.list-title')
                desc = await link.query_selector('.list-desc')
                img = await item.query_selector('img')

                data.append({
                    'link': href,
                    'title': await title.inner_text() if title else None,
                    'desc': await desc.inner_text() if desc else None,
                    'icon': await img.get_attribute('src') if img else None,
                })

        await browser.close()
        return data

# 运行
async def main():
    data = await scrape_data()
    for entry in data:
        print(entry)

asyncio.run(main())

源站执行爬取后输出:

|100%x100%

雷池防护后:

|100%x100%

效果明显,不过,感觉还是有绕过的空间呀?试试浏览器有头模式?

import asyncio
from playwright.async_api import async_playwright

async def scrape_data():
    async with async_playwright() as p:
        # 指定浏览器路径并启用有头模式
        browser = await p.chromium.launch(
            headless=False,  # 设置为 False 以显示浏览器窗口
            executable_path="C:\\Users\\Anye\\AppData\\Local\\Chromium\\Application\\chrome.exe"
        )
        page = await browser.new_page()

        # 加载本地服务器上的页面
        await page.goto('http://192.168.0.225/')

        # 手动处理人机验证
        print("请手动处理页面上的人机验证...")
        await page.wait_for_selector('.list-item.block', timeout=0)  # 等待页面加载完成,没有超时限制

        # 提取链接、图标和描述
        items = await page.query_selector_all('.list-item.block')
        data = []

        for item in items:
            link = await item.query_selector('a.list-content')
            if link:
                href = await link.get_attribute('href')
                title = await link.query_selector('.list-title')
                desc = await link.query_selector('.list-desc')
                img = await item.query_selector('img')

                data.append({
                    'link': href,
                    'title': await title.inner_text() if title else None,
                    'desc': await desc.inner_text() if desc else None,
                    'icon': await img.get_attribute('src') if img else None,
                })

        await browser.close()
        return data

# 运行
async def main():
    data = await scrape_data()
    for entry in data:
        print(entry)

asyncio.run(main())

结果:成功获取内容

|100%x100%

既然这样,那岂不是等待解密后就可以获取内容了,那么等待5秒试试?

import asyncio
from playwright.async_api import async_playwright

async def scrape_data():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()

        # 加载页面
        await page.goto('http://192.168.0.225')

        # 等待页面加载完成
        await page.wait_for_load_state('networkidle')

        # 等待5秒
        await page.wait_for_timeout(5000)

        # 提取链接、图标和描述
        items = await page.query_selector_all('.list-item.block')
        data = []

        for item in items:
            link = await item.query_selector('a.list-content')
            if link:
                href = await link.get_attribute('href')
                title = await link.query_selector('.list-title')
                desc = await link.query_selector('.list-desc')
                img = await item.query_selector('img')

                data.append({
                    'link': href,
                    'title': await title.inner_text() if title else None,
                    'desc': await desc.inner_text() if desc else None,
                    'icon': await img.get_attribute('src') if img else None,
                })

        await browser.close()
        return data

# 运行
async def main():
    data = await scrape_data()
    for entry in data:
        print(entry)

asyncio.run(main())

|100%x100%

成功获取。

雷池开发别打我,HTML 确实不太好加密

不过目前来讲确实可以拦截大部分爬虫的爬取,正常爬虫不会长时间等待页面加载,也不会用有头模式。

测试++

经测试,开启 人机验证 后,是可以有效拦截爬虫获取内容。

|100%x100%

|100%x100%

不过还是希望雷池开发大大可以继续研究研究如何加强“动态防护”的算法😘。

后记

不让黑客,越雷池一步。

本次测试为内部测试环境,请勿用于黑客攻击行为。后期雷池也会加强加密算法,保护 WEB 安全。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/675598.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

二人订单共享模式:新零售电商盈利新秘诀

电商江湖日新月异&#xff0c;竞争如火如荼&#xff0c;如何脱颖而出&#xff0c;赢得消费者&#xff1f;二人订单共享模式&#xff0c;这是一种全新的商业模式&#xff0c;旨在打造爆款产品&#xff0c;迅速吸引大量客源&#xff0c;并激发消费者重复购买欲望。 首先&#xf…

期权懂带你懂50etf认沽期权和认购期权有什么区别?

今天带你了解期权懂带你懂50etf认沽期权和认购期权有什么区别&#xff1f;在金融市场中&#xff0c;期权是一种允许持有者在未来某个时间以特定价格买入或卖出基础资产的金融衍生品。 50etf认沽期权和认购期权有什么区别&#xff1f; 50ETF认沽期权和认购期权的主要区别在于它…

从报名到领证:软考高级【网络规划设计师】报名考试全攻略

本文共计10551字&#xff0c;预计阅读35分钟。包括七个篇章&#xff1a;报名、准考证打印、备考、考试、成绩查询、证书领取及常见问题。 不想看全文的可以点击目录&#xff0c;找到自己想看的篇章进行阅读。 一、报名篇 报名条件要求&#xff1a; 1.凡遵守中华人民共和国宪…

淘宝电商接口获取商品数据,该怎么获取?

淘宝电商接口&#xff08;也称为淘宝开放平台API&#xff09;允许开发者通过编程方式获取淘宝平台上的商品数据、订单数据等。然而&#xff0c;直接获取淘宝的商品数据并不是一件简单的事情&#xff0c;因为淘宝对API的使用有一定的限制和要求&#xff0c;包括权限申请、接口调…

项目-双人五子棋对战: websocket的讲解与使用 (1)

项目介绍 接下来, 我们将制作一个关于双人五子棋的项目, 话不多说先来理清一下需求. 1.用户模块 用户的注册和登录 管理用户的天梯分数, 比赛场数, 获胜场数等信息. 2.匹配模块 依据用户的天梯积分, 实现匹配机制. 3.对战模块 把两个匹配到的玩家放到同一个游戏房间中, 双方通…

线程进阶-2 ThreadLocal

一.简单说一下ThreadLocal 1.ThreadLocal是一个线程变量&#xff0c;用于在并发条件下&#xff0c;为不同线程提供相互隔离的变量存储空间。在多线程并发的场景下&#xff0c;每个线程往ThreadLocal中存的变量都是相互独立的。 2.基本方法 &#xff08;1&#xff09;set(Obj…

wms中对屏幕进行修改wm size设置屏幕宽高原理剖析

背景&#xff1a; 上面是正常屏幕1440x2960的屏幕大小&#xff0c;如果对display进行相关的修改&#xff0c;可以使用如下命令&#xff1a; adb shell wm size 1080x1920 得出如下的画面 明显看到差异就是屏幕上下有黑边了&#xff0c;那么下面就来调研这个wm size是怎么做的…

软件系统测试的定义和测试内容介绍

一、什么是软件系统测试? 软件系统测试是指对软件系统的功能、性能、可靠性、稳定性等方面进行全面检查和验证的过程。其目的是发现潜在的问题、缺陷和风险&#xff0c;并确保软件系统的质量和稳定性。 软件系统测试可以分为多个阶段&#xff0c;包括单元测试、集成测试、系…

《深入浅出C语言:从基础到指针的全面指南》

1. 简介 C语言是一种通用的编程语言&#xff0c;广泛应用于系统编程、嵌入式系统和高性能应用程序。它由Dennis Ritchie在1972年开发&#xff0c;并且至今仍然非常流行。C语言以其高效、灵活和强大的功能著称&#xff0c;是许多现代编程语言的基础。 2. 基本语法 2.1 Hello, …

44-4 waf绕过 - CDN简介

一、CDN简介 CDN,即内容分发网络(Content Delivery Network),是建立在现有网络基础之上的智能虚拟网络。它依靠部署在各地的边缘服务器,并通过中心平台的负载均衡、内容分发和调度等功能模块,使用户可以就近获取所需内容,从而降低网络拥塞,提高用户访问响应速度和命中率…

servlet小项目与servlet续集

文章目录 servlet小项目与servlet续集,是结合上一次的案例进行升级,给项目新增了,增加员工,删除员工,查询具体员工 功能新增操作修改操作删除操作过滤器Cookie servlet小项目与servlet续集,是结合上一次的案例进行升级,给项目新增了,增加员工,删除员工,查询具体员工 功能 上一…

Spring boot集成通义千问大模型实现智能问答

Spring boot集成通义千问大模型实现智能问答 背景 我在用idea进行java开发时发现了通义灵码这款免费的智能代码补全插件&#xff0c;用了一段时间了&#xff0c;感觉很不错。就想着在自己的项目中也能集成通义千问大模型实现智能回答&#xff0c;毕竟对接openai需要解决网络问…

社交媒体数据恢复:Weico

一、从备份中恢复数据 云备份 希望这篇教程能帮助你恢复Weico中的聊天记录和文件。如有其他问题&#xff0c;请随时联系我们。 三、注意事项 在尝试恢复数据的过程中&#xff0c;请避免执行任何可能导致数据进一步丢失的操作。 数据恢复的效果取决于多种因素&#xff0c;包…

GPU的最佳拍档HBM到底是什么

在AI界&#xff0c;英伟达的大名无人不知&#xff0c;无人不晓。然而即使在AI芯片界占据绝对霸主地位的英伟达&#xff0c;依旧受制于人。 众所周知&#xff0c;算力与带宽是制衡AI应用的两大关键因素&#xff0c;长期以来高速发展的算力受困于有限的带宽限制了其性能的最大发…

信息系统项目管理师0142:管理新实践(9项目范围管理—9.1管理基础—9.1.2管理新实践)

点击查看专栏目录 文章目录 9.1.2 管理新实践 9.1.2 管理新实践 需求一直是项目管理的关注重点&#xff0c;需求管理过程结束于需求关闭&#xff0c;即把产品、服务或成果移交给接收方&#xff0c;以便长期测量、监控、实现并维持收益。随着全球项目环境变得日益复杂&#xff0…

【人工智能Ⅱ】实验8:生成对抗网络

实验8&#xff1a;生成对抗网络 一&#xff1a;实验目的 1&#xff1a;理解生成对抗网络的基本原理。 2&#xff1a;学会构建改进的生成对抗网络&#xff0c;如DCGAN、WGAN、WGAN-GP等。 3&#xff1a;学习在更为真实的数据集上应用生成对抗网络的方法。 二&#xff1a;实验…

Java反序列化-RMI流程分析

RMI 在反序列化里漏洞里面是很常用的&#xff0c;它是一个分布式的思想。 RMI概述 RMI 通常包含两个独立的程序&#xff0c;一个服务端 和 一个客户端。服务端通过绑定这个远程对象类&#xff0c;它可以封装网络操作。客户端层面上只需要传递一个名字&#xff0c;还有地址。 …

LNMP 环境下使用 Zstd 压缩优化网站备份脚本

网站的备份一直都是网站运营、服务器运维中很重要的一环&#xff0c;明月无论是在自己的服务器还是客户的代运维服务器上都是非常重视网站备份的&#xff0c;尤其热衷于优化网站备份这块儿&#xff0c;毕竟明月自己的服务器配置一直都是最低的 1H1G 呀&#xff0c;就这配置常年…

(函数)空格填充(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//声明空格填充函数&#xff1b; void space(char a[100]);int main() {//初始化变量值&#xff1b;char a[100] { 0 };//获取用户输入的数据&#xff1b;print…

人工智能学习笔记(1):了解sklearn

sklearn 简介 Sklearn是一个基于Python语言的开源机器学习库。全称Scikit-Learn&#xff0c;是建立在诸如NumPy、SciPy和matplotlib等其他Python库之上&#xff0c;为用户提供了一系列高质量的机器学习算法&#xff0c;其典型特点有&#xff1a; 简单有效的工具进行预测数据分…