一个基于GoogleAdsense的刷量系统的设计与实现

之前在测试googleAdscence的时候发现,在正常的情况下,googleAdsence刷量的收入大概会在2美金左右。如果加上抹机以及代理切换等手段,最终产生的收益可能会更高。但是这里涉及到的问题最终使策略对抗的问题。单机能够能够持续性的刷出2美金左右的收益。这里仅提出这个问题,并不去解决,原因点有三个:第一,这个是核心生产力和竞争力。第二,这个是需要大量的测试模型和规则来去验证获得最终的可行规则。第三,最终可行规则本身可能会变,因此需要不停的去重复第二步,不停的更新最终可行规则,策略对抗就是这么麻烦。其本质都是人与机器的区分。

 此文章仅是一个入门,依靠此文章中讲解的技术和方式可获得很少量的收益,想要获得更大量的收益需要自行进行探索和研究。

1. 设计篇

 adscence 刷量本质还是在于如何去解放双手。不用人去刷pv/uv,机器来去操作即可。顺着这个思路去走即可。

 那么下一个问题就应该是如何让adsence发现不了你是机器人或者机器。这个不做深入讨论,有兴趣可做交流讨论。

  设计上,你可以有一个网站,或者站群或者多个站群,这是前提条件。那还需要的就是一个可以自动刷广告的机器,这里会以ios正常开发中的WKWebView为例来实现。

  此类模式中最常见的还有刷移动端广告的喝水app,跑步app,轻游戏等app。均为名义上的跑步,喝水等,实为刷广告为app主赚钱。

2. 实现篇

  实现上基本的你得有一个网站,一个googleadsence账号,并为网站设置googleadsence广告。

  另外,得自己做一个app来打开网站去加载谷歌广告,并不定时的点击。

  本着以下设计原则来简单讲解下简单的刷广告规则:

  1. 如何创建这样一个可以自动加载网站的应用。

  这里用WKWebView来简单实现一个app可以自动加载页面。

  1. 如何设定策略,让一个自动拉取网站的页面,页面之间的关联性如何保证。

  这里需要注意的第一个是ip,第二个是ua(user-agent),第三个是Referer。因此,大型的刷量系统必然会设计到很多的ip代理/vpn。第二ua好说很好解决。第三referer就是要保证页面之间的关联性。需要设置合理的referer。

  1. 如何自动点击广告,规则如何。

 这里需要测算的,当然你下设置固定的值,实时观察,待每日广告收益更新的时候可以取适当的调整。

 简单从代码层面讲一下如何去做app:

 这里是设置一个状态信息,以便实时观察到正在跑什么:

m_statusLabel  = [[UILabel alloc] initWithFrame:CGRectMake(self.view.frame.size.width/4, 50, self.view.frame.size.width/2, 30)];
    [self.view addSubview:m_statusLabel];
    m_statusLabel.backgroundColor = [UIColor blackColor];
    [m_statusLabel setTextColor:[UIColor whiteColor]];
    [m_statusLabel setAdjustsFontSizeToFitWidth:true];
    [m_statusLabel setTextAlignment:NSTextAlignmentCenter];

这里是一些其他的方法,大家参考下:

-(void)startRequestWithUA:(NSString*)userAgent lastUrl:(NSString*) lastUrl url:(NSString*)url viewTimes:(NSNumber*)viewTimes{
    m_WebView.customUserAgent = userAgent;
    NSLog(@"url=%@,last_url=%@,view_times=%@", url, lastUrl, viewTimes);
    // 请求网址
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
    [request setValue:lastUrl forHTTPHeaderField:@"Referer"];
    [m_WebView loadRequest:request];
    m_WebView.UIDelegate = self;
    m_WebView.navigationDelegate = self;
    
    m_reloadTimes = [viewTimes intValue];
    
    // 开启定时器跑任务
    int randomTime = [Utility GetRandomTime];
    m_Timer = [NSTimer scheduledTimerWithTimeInterval:randomTime target:self selector:@selector(Timered:) userInfo:nil repeats:NO];
    
    
    // 添加控件
    NSLog(@"-- web view reloaded.");
    NSString *msgText  = [NSString stringWithFormat:@"浏览器加载完成, 已加载%d次,%d秒后再次加载!", m_reloadTimes,randomTime];
    m_statusLabel.text = msgText;
}
/* 页面加载完成 */
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    NSLog(@"load finished-----------------");
    // 得延迟执行
    int randomTime = [Utility GetRandomNum:4] + 1;
    [NSTimer scheduledTimerWithTimeInterval:randomTime target:self selector:@selector(scrollView:) userInfo:nil repeats:NO];
}
/* 在发送请求之前,决定是否跳转 */
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    if (navigationAction.targetFrame == nil) {
        [webView loadRequest:navigationAction.request];
    }
    //允许跳转
    decisionHandler(WKNavigationActionPolicyAllow);
    //不允许跳转
    //decisionHandler(WKNavigationActionPolicyCancel);
}
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
    NSLog(@"createWebViewWithConfiguration");
    if (!navigationAction.targetFrame.isMainFrame) {
        [webView loadRequest:navigationAction.request];
    }
    return nil;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 配置WKWebView
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    m_WebView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:config];
    [self.view addSubview:m_WebView];
    [self initCtrl];
    
    LoadConfigApi* loadConfigApi = [[LoadConfigApi alloc] initWithToken:TEST_TOKEN netType:TEST_NET_TYPE];
    [loadConfigApi startWithCompletionBlockWithSuccess:^(YTKBaseRequest *request) {
        NSLog(@"request succeed with string %@",request.responseString);
        NSString * ua =[[request.responseObject objectForKey:@"data"] objectForKey:@"ua"];
        NSString * url =[[request.responseObject objectForKey:@"data"] objectForKey:@"url"];
        NSString * lastUrl =[[request.responseObject objectForKey:@"data"] objectForKey:@"last_url"];
        NSNumber* viewTimes =[[request.responseObject objectForKey:@"data"] objectForKey:@"view_times"];
        
        [self startRequestWithUA:ua lastUrl:lastUrl url:url viewTimes:viewTimes];
    } failure:^(YTKBaseRequest *request) {
        // 你可以直接在这里使用 self
        NSLog(@"request failed with response string %@", request.responseString);
    }];
}
-(void)clickView:(NSTimer *)timer{
//    NSInteger pointId = [PTFakeMetaTouch fakeTouchId:[PTFakeMetaTouch getAvailablePointId] AtPoint:CGPointMake(30,30) withTouchPhase:UITouchPhaseBegan];
//    [PTFakeMetaTouch fakeTouchId:pointId AtPoint:CGPointMake(30,30) withTouchPhase:UITouchPhaseEnded];
    NSString *jsString = @"document.elementFromPoint(100, 100).click();";
    [m_WebView evaluateJavaScript:jsString completionHandler:^(id object, NSError * _Nullable error) {
        NSLog(@"obj:%@---error:%@", object, error);
    }];
    
}
-(void)scrollView:(NSTimer *)timer{
    [m_WebView.scrollView setContentOffset:CGPointMake(0, [Utility GetRandomNum:5]*100 + 500) animated:YES];
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(clickView:) userInfo:nil repeats:NO];
}
- (void)Timered:(NSTimer*)timer {
    
    LoadConfigApi* loadConfigApi = [[LoadConfigApi alloc] initWithToken:TEST_TOKEN netType:TEST_NET_TYPE];
    [loadConfigApi startWithCompletionBlockWithSuccess:^(YTKBaseRequest *request) {
        NSLog(@"request succeed with string %@",request.responseString);
        NSString * ua =[[request.responseObject objectForKey:@"data"] objectForKey:@"ua"];
        NSString * url =[[request.responseObject objectForKey:@"data"] objectForKey:@"url"];
        NSString * lastUrl =[[request.responseObject objectForKey:@"data"] objectForKey:@"last_url"];
        NSNumber* viewTimes =[[request.responseObject objectForKey:@"data"] objectForKey:@"view_times"];
        [self startRequestWithUA:ua lastUrl:lastUrl url:url viewTimes:viewTimes];
    } failure:^(YTKBaseRequest *request) {
        // 你可以直接在这里使用 self
        NSLog(@"request failed with response string %@", request.responseString);
    }];
}

 大家对完整代码有兴趣的话可以加我微信nicholas_mcc,完整工程可以分享的。

adsense

不好意思写错了。怪不得没人回 哈哈哈

人還在嗎?
關於Google 如何分辦你是人或是機這個問題,我想進一步與你討論。由於我最近開始了有關的專題研究,所以我希望得到專業者的看法。我的研究對象是YouTube上的Googleads的判定,是有效流量或是無效流量。以你的認知,你認為Google是以甚麼條件來判定你是人或機的?
以YouTube為例,最基本的可能有帳號,ip 還有網頁上的活動記錄,但由於直接或不明來錄也可以作為廣告收入,則可限制了活動記錄為考量因素。ip方面,聽說Googleadsense 會傳送無關ip的cookies給訪問者,從而令用vpn的ip無效,但我已發現vpn的Datacenter ip是可以用來刷流量的,所以以上無關判定。那麼你認為還有甚麼重要考量是令Google判定你是機器而非人類?