[油猴脚本开发指南]实战fetch劫持知乎去广告
# FBI WARNING上节课在实战的时候我发现存在严重错误,根据cxxjackie的提示和帮助下进一步完善了代码,相对来说还是较重的,下节课会介绍另一种方法。
上节课的主要错误在于,部分网页对于fetch存在一个喜欢写入自定义数据和读入自定义数据的问题。
由于我创建了一层多余的空对象,网页过掉了porxy,直接在空对象写入数据,导致出现错误。
以下代码仅经过了少量的测试,不代表真的不存在问题,如果存在问题可以反馈给我。
```javascript
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=(...funcargs)=> {
let result=target.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
```
然后我们通过抓包可以看到
```javascript
https://www.zhihu.com/api/v3/feed/topstory/recommend?
```
是获取刷新列表的fetch api
![图片.png](data/attachment/forum/202108/30/141327nh9ucv9f9ua899eh.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")
运行脚本,可以发现这个api调用的json进行的返回对象的json化,所有我们开写代码了!
![图片.png](data/attachment/forum/202108/30/141614aczcslnilihlnqdf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")
首先判断变量的长度,以及url,如果都没问题,再判断调用的函数名是否是json,如果满足的话
说明我们需要进行劫持了!
观察result返回的内容,json返回的是一个Promise
所以我们也需要返回一个Promise
```javascript
if(bianliang.length!==0&&bianliang.indexOf('/api/v3/feed/topstory/recommend')!==-1&&prop==='json'){
return new Promise(function(resolve, reject){})
}
```
我们在promise内先获取result的结果,然后进行处理,再resolve结束我们创建的这个promise
所以这里的完整代码就是
```javascript
if(bianliang.length!==0&&bianliang.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.ad===undefined){
retobj.data.push(data.data)
}
}
resolve(retobj)
}
)
})
}
```
我在result.then上挂载了一个函数,并执行相应的处理,最后在resolve回去数据,
返回的数据创建了三个属性,fresh_text以及paging都原封不动的传递,data,需要我们进行处理,这里我们可以使用ES6特性解包直接完成,但是代码相对更骚一点,很多人看不懂,暂时先忽略掉。
紧接着对result返回的data数据的data属性做一个便利,如果不存在ad属性就push进retobj的data数组上。
那目前为止我们已经解决大部分问题了,最后还有一个问题就是页面最初载入的时候也有一个广告,我们应该如何处理呢?
这里由于不属于教程返回,就简单粗暴处理了一下。
```javascript
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部分的帮助
撒花~
let retobj={
data:[],
fresh_text:data.fresh_text,
paging:data.paging,
}
这些参数是什么 rubinTime 发表于 2021-12-7 22:10
let retobj={
data:[],
...
知乎的参数,原封不动拷贝了下 哥哥为什么我一个ad属性都没看,data里面的每个item基本都是15对键值对,很少有16对,多出的那一对键值对键值也不是ad
https://s4.ax1x.com/2021/12/08/o2M0de.png rubinTime 发表于 2021-12-8 10:18
哥哥为什么我一个ad属性都没看,data里面的每个item基本都是15对键值对,很少有16对,多出的那一对键值对键 ...
有ad的时候才会有ad属性
具体还是要根据页面调试
不过我之前写的脚本到现在都好使 李恒道 发表于 2021-12-8 10:31
有ad的时候才会有ad属性
具体还是要根据页面调试
不过我之前写的脚本到现在都好使 ...
哥哥我试了你的脚本确实可以,但是我下来刷新等待fetch请求,明明途中看到广告但在返回的json属性的data子项中确实找不到ad rubinTime 发表于 2021-12-8 11:03
哥哥我试了你的脚本确实可以,但是我下来刷新等待fetch请求,明明途中看到广告但在返回的json属性的data ...
![图片.png](data/attachment/forum/202112/08/112342s1vzn1ipp3lq1z3l.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")
rubinTime 发表于 2021-12-8 11:03
哥哥我试了你的脚本确实可以,但是我下来刷新等待fetch请求,明明途中看到广告但在返回的json属性的data ...
确实有ad属性的,哥哥可能找错了? gege我火狐浏览器找到ad属性了,但是chorme翻了好几条fetch就是找不到
页:
[1]