photo_2023-02-04_10-57-52.jpg

Via 春潮频道

I. 前言

一些实践示例记录:移除PC浏览器端Pornhub播放页面侧边栏图片广告;举例页面;(如需测试下述代码,请提前关闭Adguard/ublock Origin 等去广告浏览器扩展功能);

记录,尝试;为学患无疑,疑则有进;

II. 文档对象模型(DOM)

DOM.png

文档对象模型 (DOM) 将 web 页面与到脚本或编程语言连接起来。通常是指 JavaScript,但将 HTML、SVG 或 XML 文档建模为对象并不是 JavaScript 语言的一部分。DOM 模型用一个逻辑树来表示一个文档,树的每个分支的终点都是一个节点 (node),每个节点都包含着对象 (objects)。DOM 的方法 (methods) 让你可以用特定方式操作这个树,用这些方法你可以改变文档的结构、样式或者内容。节点可以关联上事件处理器,一旦某一事件被触发了,那些事件处理器就会被执行。

详细介绍DOM幕后解密

III. 实践记录(Pornhub播放页广告)

Pornhub 视频播放页 - 侧边栏广告.png

对应HTML代码(其中一个广告),仅仅隐藏 img 元素(行内元素)是非常简单的,但如需隐藏 img 之上的 div 元素(块级元素)还需要更多特征进行匹配:

<div class="dfdelbfpjd">
    <style>
        .dcjdmhckbb1675586019057 {
            margin: 0 auto;
            cursor: pointer;
            position: absolute;
            width: 300px;
            height: 250px;
            display: block !important;
            cursor: pointer;
            margin-bottom: 15px;
            clear: both;
        }

        .dcjdmhckbb1675586019057 img {
            content: '';
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            background-repeat: no-repeat;
            background-position: center;
        }
    </style>
    <div class="dcjdmhckbb1675586019057">
        <img data-title="" title="" srcset="bloB:https://www.pornhub.com/7de9ac25-9344-40a2-a559-5fb30819009e">
    </div>
</div>

喏,隐藏上述HTML代码中图片广告可以用下述CSS样式;但 div 的样式仍然占据着内容空间 height: 250px;.. ;

img[data-title][title][srcset] {display:none! important;} // 图片被隐藏了,但其父元素 div 仍占据着内容空间 

值得注意的是,class="dfdelbfpjd" 中的属性值(dfdelbfpjd)每次刷新都会变化,相应的 style 选择器名称(dcjdmhckbb1675586019057)也是;

JavaScript 脚本代码:我们将通过如下代码对相应广告元素进行捕获并重新设定其样式,使其隐藏(移除);

function pornhub_sidebar_ads() {
    setTimeout(() => {
        var ele_parent = ["div"];
        var ele_children = ["img[data-title][title][srcset]"];
        var ele_attributes = ["class"];
        var i;

        const css_Selctors = document.querySelectorAll(ele_parent);

        for (i = 0; i < css_Selctors.length; i++) {
            if (css_Selctors[i].querySelectorAll(ele_children).length !== 0) {
                if (css_Selctors[i].getAttribute(ele_attributes)) {
                    if (css_Selctors[i].attributes.length == 1) {
                        if (css_Selctors[i].children.length == 2) {
                            console.log(css_Selctors[i])
                            css_Selctors[i].style.display = "none";
                        }
                    }
                }
            }
        }
    }, 500);
}

pornhub_sidebar_ads()

1.Chrome浏览器打开举例页面

Chrome - 控制台 .png

2.进入Chrome 浏览器的“控制台”,有两种方法。 直接进入:按下Option + Command + J(Mac)或者Ctrl + Shift + J(Windows / Linux)

3.粘贴 JavaScript 代码,回车;

可复用函数:

function pornhub_sidebar_ads(ele_parent, ele_children, _length) {
    setTimeout(() => {
        var i;

        const css_Selctors = document.querySelectorAll(ele_parent);

        for (i = 0; i < css_Selctors.length; i++) {
            if (css_Selctors[i].querySelectorAll(ele_children).length !== 0) {
                if (css_Selctors[i].getAttribute(ele_attributes)) {
                    if (css_Selctors[i].attributes.length == 1) {
                        if (css_Selctors[i].children.length == 2) {
                            console.log(css_Selctors[i])
                            css_Selctors[i].style.display = "none";
                        }
                    }
                }
            }
        }
    }, 500);
}

const ele_parent = ["div"];
const ele_children = ["img[data-title][title][srcset]"];
const ele_attributes = ["class"];
const _length = 2;

pornhub_sidebar_ads(ele_parent, ele_children, ele_attributes, _length)

利用属性匹配进行移除

如前文所言,pornhub 播放页广告中 div 元素的 class 属性会随着网页刷新而变化,但其长度一直保持在10位数,且都为字母,我们可以利用该特征进行广告精准移除;

const nodelist = document.querySelectorAll('div');
for (i = 0; i < nodelist.length; i++) {
    let strings = nodelist[i].getAttribute("class");
    if (strings !== null) {
        let regex = /^[a-zA-Z]{10}$/g
        if (strings.match(regex)) {
            nodelist[i].style.display = "none";
        }
    }
}

可复用函数:

function ads_remove_attribute(tag, attribute, regex) {
    const nodelist = document.querySelectorAll(tag);
    for (i = 0; i < nodelist.length; i++) {
        let strings = nodelist[i].getAttribute(attribute);
        if (strings !== null) {
            if (strings.match(regex)) {
                nodelist[i].style.display = "none";
            }
        }
    }
}

let regex = /^[a-zA-Z]{10}$/g;
ads_remove_attribute("div", "class", regex)

IV. 实践记录(91Porn播放页广告)

function _91porn_videoplay_ads() {
    setTimeout(() => {
        var ele_parent = ["div"];
        var ele_children = ["a[target=\"_blank\"]  > img[src*=\".gif\"]"];
        var i;

        const css_Selctors = document.querySelectorAll(ele_parent);

        for (i = 0; i < css_Selctors.length; i++) {
            if (css_Selctors[i].querySelectorAll(ele_children).length !== 0) {
                if (css_Selctors[i].attributes.length == 0) {
                    if (css_Selctors[i].children.length == 9) {
                        console.log(css_Selctors[i])
                        css_Selctors[i].style.display = "none";
                    }
                }
            }
        }
    }, 500);
}

_91porn_videoplay_ads()

以上代码是针对 91porn 视频播放页广告进行针对性移除的方法,此代码较上述 Pornhub 代码精简了2行代码;大家可以在此代码上进行修改,适用大多数无法用 CSS 选择器 精准选取广告元素对象的情况;就像一个网页有非常多的 div 元素标签(如何找到它,它的特征是什么?),我们用方法 document.querySelectorAll("div"),找出DOM中所有的div元素的集合,然后通过条件遍历这个集合(NodeList),例如,我们想要找到的 div 的内容其实应该包含 a标签,且其属性 target 是 _blank,a标签的子元素包含 img 标签,该 div 元素下有9个子元素等等;

一旦条件符合,我们返回该 div 元素在所在集合的位置,并对其进行操作,如隐藏;

V. 代码优化及复用

为了能够复用,进行如下代码优化

var varr = {
    _91porn: {
        ele_parent: ["div"],
        ele_children: ["a[target=\"_blank\"]  > img[src*=\".gif\"]"],
        ele_children_length: 9
    }
}

function _91porn_videoplay_ads(ele_parent, ele_children, ele_children_length) {
    setTimeout(() => {
        var i;

        const css_Selctors = document.querySelectorAll(ele_parent);

        for (i = 0; i < css_Selctors.length; i++) {
            if (css_Selctors[i].querySelectorAll(ele_children).length !== 0) {
                if (css_Selctors[i].attributes.length == 0) {
                    if (css_Selctors[i].children.length == ele_children_length) {
                        console.log(css_Selctors[i])
                        css_Selctors[i].style.display = "none";
                    }
                }
            }
        }
    }, 500);
}

_91porn_videoplay_ads(varr._91porn.ele_parent, varr._91porn.ele_children, varr._91porn.ele_children_length)

其他函数

function ads_remove_css_Selectors(css_Selctors) {
    const nodelist = document.querySelectorAll(css_Selctors)
    for (i = 0; i < nodelist.length; i++) {
        nodelist[i].style.display = "none";
    }
}

ads_remove_css_Selectors("[target='_blank']")
ads_remove_css_Selectors("br")

VI. 附注

最后修改:2024 年 04 月 04 日 04 : 22 PM