上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

[油猴脚本开发指南]实战fetch劫持知乎去广告

[复制链接]
  • TA的每日心情
    无聊
    2022-4-18 01:37
  • 签到天数: 30 天

    [LV.5]常住居民I

    303

    主题

    2603

    帖子

    2666

    积分

    荣誉开发者

    非物质文化遗产社会摇传承人

    Rank: 10Rank: 10Rank: 10

    积分
    2666

    猫咪币纪念章

    发表于 2021-8-30 14:23:27 | 显示全部楼层 | 阅读模式

    FBI WARNING

    上节课在实战的时候我发现存在严重错误,根据cxxjackie的提示和帮助下进一步完善了代码,相对来说还是较重的,下节课会介绍另一种方法。

    上节课的主要错误在于,部分网页对于fetch存在一个喜欢写入自定义数据和读入自定义数据的问题。

    由于我创建了一层多余的空对象,网页过掉了porxy,直接在空对象写入数据,导致出现错误。

    以下代码仅经过了少量的测试,不代表真的不存在问题,如果存在问题可以反馈给我。

    let oldfetch=fetch
    function newobj(){}
    function fuckfetch(...bianliang){
        return new Promise(function(resolve, reject){
            oldfetch(...bianliang).then(function(response) {
                let handler = {
                    get: function(target, prop, receiver) {
                        if(typeof Reflect.get(target,prop)==='function')
                        {
                            if(Reflect.get(target,prop+'proxy')===undefined)
                            {
                                target[prop+'proxy']=(...funcargs)=> {
                                    let result=target[prop].call(target,...funcargs)
                                    //书写劫持的函数代码
                                    console.log('fetchfunction',bianliang,prop,funcargs,result)
                                    return result
                                }
    
                            }
                            return Reflect.get(target,prop+'proxy')
                        }
    
                        return Reflect.get(target, prop);
                    },
    
                    set(target, prop, value) {
                        return Reflect.set(target, prop, value);
                    },
                };
                let proxy=new Proxy(response, handler)
                resolve(proxy)
            })
    
        });
    }
    
    window.fetch=fuckfetch

    然后我们通过抓包可以看到

    https://www.zhihu.com/api/v3/feed/topstory/recommend?

    是获取刷新列表的fetch api

    图片.png

    运行脚本,可以发现这个api调用的json进行的返回对象的json化,所有我们开写代码了!

    图片.png

    首先判断变量的长度,以及url,如果都没问题,再判断调用的函数名是否是json,如果满足的话

    说明我们需要进行劫持了!

    观察result返回的内容,json返回的是一个Promise

    所以我们也需要返回一个Promise

    if(bianliang.length!==0&&bianliang[0].indexOf('/api/v3/feed/topstory/recommend')!==-1&&prop==='json'){
    
    return new Promise(function(resolve, reject){})
    
    }

    我们在promise内先获取result的结果,然后进行处理,再resolve结束我们创建的这个promise

    所以这里的完整代码就是

                                    if(bianliang.length!==0&&bianliang[0].indexOf('/api/v3/feed/topstory/recommend')!==-1&&prop==='json'){
                                        return new Promise(function(resolve, reject){
                                            result.then(
                                                function(data){
    
                                                    console.log('bianliang',bianliang)
                                                    let retobj={
                                                        data:[],
                                                        fresh_text:data.fresh_text,
                                                        paging:data.paging,
                                                    }
                                                    for(let index=0;index<data.data.length;index++){
                                                        if(data.data[index].ad===undefined){
                                                            retobj.data.push(data.data[index])
                                                        }
                                                    }
                                                    resolve(retobj)
                                                }
                                            )
                                        })
                                    }

    我在result.then上挂载了一个函数,并执行相应的处理,最后在resolve回去数据,

    返回的数据创建了三个属性,fresh_text以及paging都原封不动的传递,data,需要我们进行处理,这里我们可以使用ES6特性解包直接完成,但是代码相对更骚一点,很多人看不懂,暂时先忽略掉。

    紧接着对result返回的data数据的data属性做一个便利,如果不存在ad属性就push进retobj的data数组上。

    那目前为止我们已经解决大部分问题了,最后还有一个问题就是页面最初载入的时候也有一个广告,我们应该如何处理呢?

    这里由于不属于教程返回,就简单粗暴处理了一下。

    window.onload=function(){
    document.querySelector('.Pc-feedAd-container').parentElement.style.display='none'
    }

    具体脚本可以参考

    https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=911

    结语

    感谢cxxjackie对于fetch部分的帮助

    撒花~

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
  • TA的每日心情
    开心
    2022-3-7 09:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    18

    主题

    89

    帖子

    109

    积分

    中级工程师

    Rank: 5Rank: 5

    积分
    109
    发表于 2021-12-7 22:10:36 | 显示全部楼层
    let retobj={
                                                        data:[],
                                                        fresh_text:data.fresh_text,
                                                        paging:data.paging,
                                                    }
    这些参数是什么
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2022-4-18 01:37
  • 签到天数: 30 天

    [LV.5]常住居民I

    303

    主题

    2603

    帖子

    2666

    积分

    荣誉开发者

    非物质文化遗产社会摇传承人

    Rank: 10Rank: 10Rank: 10

    积分
    2666

    猫咪币纪念章

    发表于 2021-12-8 09:21:34 | 显示全部楼层
    rubinTime 发表于 2021-12-7 22:10
    let retobj={
                                                        data:[],
                               ...

    知乎的参数,原封不动拷贝了下
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-3-7 09:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    18

    主题

    89

    帖子

    109

    积分

    中级工程师

    Rank: 5Rank: 5

    积分
    109
    发表于 2021-12-8 10:18:08 | 显示全部楼层
    哥哥为什么我一个ad属性都没看,data里面的每个item基本都是15对键值对,很少有16对,多出的那一对键值对键值也不是ad
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2022-4-18 01:37
  • 签到天数: 30 天

    [LV.5]常住居民I

    303

    主题

    2603

    帖子

    2666

    积分

    荣誉开发者

    非物质文化遗产社会摇传承人

    Rank: 10Rank: 10Rank: 10

    积分
    2666

    猫咪币纪念章

    发表于 2021-12-8 10:31:33 | 显示全部楼层
    rubinTime 发表于 2021-12-8 10:18
    哥哥为什么我一个ad属性都没看,data里面的每个item基本都是15对键值对,很少有16对,多出的那一对键值对键 ...

    有ad的时候才会有ad属性
    具体还是要根据页面调试
    不过我之前写的脚本到现在都好使
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-3-7 09:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    18

    主题

    89

    帖子

    109

    积分

    中级工程师

    Rank: 5Rank: 5

    积分
    109
    发表于 2021-12-8 11:03:58 | 显示全部楼层
    李恒道 发表于 2021-12-8 10:31
    有ad的时候才会有ad属性
    具体还是要根据页面调试
    不过我之前写的脚本到现在都好使 ...

    哥哥我试了你的脚本确实可以,但是我下来刷新等待fetch请求,明明途中看到广告但在返回的json属性的data子项中确实找不到ad
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2022-4-18 01:37
  • 签到天数: 30 天

    [LV.5]常住居民I

    303

    主题

    2603

    帖子

    2666

    积分

    荣誉开发者

    非物质文化遗产社会摇传承人

    Rank: 10Rank: 10Rank: 10

    积分
    2666

    猫咪币纪念章

    发表于 2021-12-8 11:23:43 | 显示全部楼层

    rubinTime 发表于 2021-12-8 11:03

    哥哥我试了你的脚本确实可以,但是我下来刷新等待fetch请求,明明途中看到广告但在返回的json属性的data ...

    图片.png

    图片.png
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2022-4-18 01:37
  • 签到天数: 30 天

    [LV.5]常住居民I

    303

    主题

    2603

    帖子

    2666

    积分

    荣誉开发者

    非物质文化遗产社会摇传承人

    Rank: 10Rank: 10Rank: 10

    积分
    2666

    猫咪币纪念章

    发表于 2021-12-8 11:23:56 | 显示全部楼层
    rubinTime 发表于 2021-12-8 11:03
    哥哥我试了你的脚本确实可以,但是我下来刷新等待fetch请求,明明途中看到广告但在返回的json属性的data ...

    确实有ad属性的,哥哥可能找错了?
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-3-7 09:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    18

    主题

    89

    帖子

    109

    积分

    中级工程师

    Rank: 5Rank: 5

    积分
    109
    发表于 2021-12-8 21:03:32 | 显示全部楼层
    gege我火狐浏览器找到ad属性了,但是chorme翻了好几条fetch就是找不到
    回复

    使用道具 举报

    发表回复

    本版积分规则

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