大家好,在大家对一个视图机器人感到兴奋之前,我想说这只是一个有趣的项目,我只是想试一试,看看它是否真的能工作,并在此过程中学到一些东西。我对发布这篇文章没有兴趣,也没有兴趣尝试成为一名伙伴或认真的机器人人,也许只是和我的朋友玩个恶作剧,他想要时不时地流媒体。既然这样说了,我就可以继续了。
我写了一个基本的程序来构建twitch查看器令牌,然后开始将它们连接到我认为twitch计算它的视图。这是奇怪的事情,当我点击10个机器人时,它会将观众数量重新设置为实际的观众人数。我的问题是它到底是怎么弄明白的。我想指出的是,我正在使用代理连接,这样twitch就会认为这些观众来自世界各地,而不是来自一个单一的地点。
还有另一种我尝试过的方法,那就是建立所有的观众令牌,然后像上面那样,我得到一个视图令牌并立即发送它,我基于代理建立它们,然后同时发送它们,这通常会超过10个观众上限,但不会太多,但是它不会重新设置回应计观众计数。
下面是构建令牌的代码:(有点凌乱,所以我会回答任何需要回答的问题)
ASIHTTPRequest *request43 = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://api.twitch.tv/api/channels/%@/access_token?as3=t",_twitchName]]];
[request43 setProxyHost:host];
[request43 setProxyPort:port];
[request43 addRequestHeader:@"Host" value:@"api.twitch.tv"];
[request43 addRequestHeader:@"User-Agent" value:@"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:33.0) Gecko/20100101 Firefox/33.0"];
[request43 addRequestHeader:@"Accept" value:@"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"];
[request43 addRequestHeader:@"Accept-Language" value:@"en-US,en;q=0.5"];
[request43 addRequestHeader:@"Accept-Encoding" value:@"gzip, deflate"];
[request43 addRequestHeader:@"Referer" value:@"http://www-cdn.jtvnw.net/swflibs/TwitchPlayer.rc356cd0c16b6941b7f81b61f6c81628e0af555d9.swf"];
[request43 addRequestHeader:@"Cookie" value:@" __qca=P0-1674306474-1405279259134; __utma=165406266.651051162.1405279260.1417284372.1417380722.33; __utmz=165406266.1411832471.26.8.utmcsr=twitch.tv|utmccn=(referral)|utmcmd=referral|utmcct=/nozux; language=en-us; __gads=ID=bc1b6635a26dc0a7:T=1405279267:S=ALNI_MY1rrxM6Qf6aS_lUCRlff0o0gtUaA; unique_id=e8ba8f001f90b6bc293ab6e79ea0b1bb; __utmc=165406266; feature_bucket=88; _twitch_session_id=c06f09efe4c36c8ea46176deabab0cb5; __utmb=165406266.0.10.1417380722; mp_809576468572134f909dffa6bd0dcfcf_mixpanel=%7B%22distinct_id%22%3A%20%22147312bcdb989-0fc383a2c86945-41652d42-13c680-147312bcdba176%22%2C%22%24initial_referrer%22%3A%20%22http%3A%2F%2Fintl.gg%2F%22%2C%22%24initial_referring_domain%22%3A%20%22intl.gg%22%7D"];
[request43 addRequestHeader:@"Connection" value:@"keep-alive"];
[request43 addRequestHeader:@"If-None-Match" value:@"11b92749f327a27cb4ebfb8b57f12b15"];
[request43 addRequestHeader:@"Cache control" value:@"no-cache"];
[request43 setTimeOutSeconds:10];
[request43 setFailedBlock:^{
NSLog(@"failed 1st");
NSLog(@"%@",request43.error);
}];
[request43 setCompletionBlock:^{
NSError *error;
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:request43.responseData options:0 error:&error];
NSString *token = [[jsonDic valueForKey:@"token"] stringByAddingPercentEscapesUsingEncoding:
NSASCIIStringEncoding];
NSString *sig = [jsonDic valueForKey:@"sig"];
NSLog(@"%@",jsonDic);
ASIHTTPRequest *request44 = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://usher.twitch.tv/api/channel/hls/%@.m3u8?token=%@&p=4753325&player=twitchweb&sig=%@&segment_preference=4",_twitchName,token,sig]]];
////http//usher.twitch.tv/api/channel/hls/%@.m3u8?token=%@&p=4753325&player=twitchweb&sig=%@&segment_preference=4
[request44 addRequestHeader:@"Host" value:@"usher.twitch.tv"];
[request44 addRequestHeader:@"User-Agent" value:@"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:33.0) Gecko/20100101 Firefox/33.0"];
[request44 addRequestHeader:@"Accept" value:@"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"];
[request44 addRequestHeader:@"Accept-Language" value:@"en-US,en;q=0.5"];
[request44 addRequestHeader:@"Accept-Encoding" value:@"gzip, deflate"];
[request44 addRequestHeader:@"Referer" value:@"http://www-cdn.jtvnw.net/swflibs/TwitchPlayer.rc356cd0c16b6941b7f81b61f6c81628e0af555d9.swf"];
[request44 addRequestHeader:@"Cookie" value:@" __qca=P0-1674306474-1405279259134; __utma=165406266.651051162.1405279260.1417284372.1417380722.33; __utmz=165406266.1411832471.26.8.utmcsr=twitch.tv|utmccn=(referral)|utmcmd=referral|utmcct=/nozux; language=en-us; __gads=ID=bc1b6635a26dc0a7:T=1405279267:S=ALNI_MY1rrxM6Qf6aS_lUCRlff0o0gtUaA; unique_id=e8ba8f001f90b6bc293ab6e79ea0b1bb; __utmc=165406266; feature_bucket=88; _twitch_session_id=c06f09efe4c36c8ea46176deabab0cb5; __utmb=165406266.0.10.1417380722; mp_809576468572134f909dffa6bd0dcfcf_mixpanel=%7B%22distinct_id%22%3A%20%22147312bcdb989-0fc383a2c86945-41652d42-13c680-147312bcdba176%22%2C%22%24initial_referrer%22%3A%20%22http%3A%2F%2Fintl.gg%2F%22%2C%22%24initial_referring_domain%22%3A%20%22intl.gg%22%7D"];
[request44 addRequestHeader:@"Connection" value:@"keep-alive"];
[request44 addRequestHeader:@"Cache control" value:@"no-cache"];
[request44 setProxyHost:host];
[request44 setProxyPort:port];
[request44 setFailedBlock:^{
NSLog(@"failed 2st");
NSLog(@"%@",request44.error);
}];
[request44 setCompletionBlock:^{
// NSLog(@"%@",[[NSString alloc] initWithData:request44.responseData encoding:NSUTF8StringEncoding]);
NSString *urls = [[NSString alloc] initWithData:request44.responseData encoding:NSUTF8StringEncoding];
// NSLog(@"%@",urls);
NSArray *urlArray = [urls componentsSeparatedByString:@"http://"];
NSLog(@"%@",urlArray);
if (urlArray.count < 2) {
return;
}
NSString *url = [NSString stringWithFormat:@"http://%@",[[[urlArray objectAtIndex:1] componentsSeparatedByString:@"\n"] objectAtIndex:0]];
//NSString *url = [[NSString stringWithFormat:@"http://%@",[urlArray lastObject]] stringByReplacingOccurrencesOfString:@"\n" withString:@""];
NSLog(@"%@",url);
if ([url rangeOfString:@"video"].location != NSNotFound) {
NSLog(@"%@",url);
ASIHTTPRequest *final = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:url]];
[final setProxyHost:host];
[final setProxyPort:port];
[final addRequestHeader:@"Cache control" value:@"no-cache"];
[final addRequestHeader:@"Host" value:@"video11.iad02.hls.twitch.tv"];
[final addRequestHeader:@"User-Agent" value:@"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:33.0) Gecko/20100101 Firefox/33.0"];
[final addRequestHeader:@"Accept" value:@"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"];
[final addRequestHeader:@"Accept-Language" value:@"en-US,en;q=0.5"];
[final addRequestHeader:@"Accept-Encoding" value:@"gzip, deflate"];
[final addRequestHeader:@"Referer" value:@"http://www-cdn.jtvnw.net/swflibs/TwitchPlayer.rc356cd0c16b6941b7f81b61f6c81628e0af555d9.swf"];
[final addRequestHeader:@"Cookie" value:@"__qca=P0-1674306474-1405279259134; __utma=165406266.651051162.1405279260.1417284372.1417380722.33; __utmz=165406266.1411832471.26.8.utmcsr=twitch.tv|utmccn=(referral)|utmcmd=referral|utmcct=/nozux; language=en-us; __gads=ID=bc1b6635a26dc0a7:T=1405279267:S=ALNI_MY1rrxM6Qf6aS_lUCRlff0o0gtUaA; unique_id=e8ba8f001f90b6bc293ab6e79ea0b1bb; __utmc=165406266; feature_bucket=88; _twitch_session_id=c06f09efe4c36c8ea46176deabab0cb5; __utmb=165406266.0.10.1417380722; mp_809576468572134f909dffa6bd0dcfcf_mixpanel=%7B%22distinct_id%22%3A%20%22147312bcdb989-0fc383a2c86945-41652d42-13c680-147312bcdba176%22%2C%22%24initial_referrer%22%3A%20%22http%3A%2F%2Fintl.gg%2F%22%2C%22%24initial_referring_domain%22%3A%20%22intl.gg%22%7D"];
[final addRequestHeader:@"Connection" value:@"keep-alive"];
[final setFailedBlock:^{
NSLog(@"final failed");
}];
[final setCompletionBlock:^{
if ([final.responseString rangeOfString:@"#EXT-X-MEDIA-SEQUENCE"].location != NSNotFound) {
[self.builtRequests addObject:final];
if (proxyDictonary) {
[self.SuccessProxies addObject:proxyDictonary];
}
[self sendRequest:final];
NSLog(@"%lu",_builtRequests.count);
} else {
NSLog(@"%@",final.responseHeaders);
NSLog(@"%@",final.responseString);
}
}];
[final startAsynchronous];
}
}];
[request44 startAsynchronous];
}];
[request43 startAsynchronous];以下是我的代码在连接成功时的响应头:
Request43:"Accept-Ranges" = bytes;
Age = 0;
"Cache-Control" = "max-age=0, private, must-revalidate";
Connection = "keep-alive";
"Content-Encoding" = gzip;
"Content-Length" = 231;
"Content-Type" = "application/json; charset=utf-8";
Date = "Wed, 03 Dec 2014 20:51:39 GMT";
Etag = "\"151bb8422eb29f9f33a520ab352f152e\"";
"Front-End-Https" = on;
Server = nginx;
Status = "200 OK";
Vary = "Accept-Encoding";
Via = "1.1 varnish";
"Www-Authenticate" = "OAuth realm='TwitchTV'";
"X-API-Version" = 3;
"X-Frame-Options" = SAMEORIGIN;
"X-MH-Cache" = "appcache2; M";
"X-Request-Id" = 7939f63c1e3130c43a4edfc9a0911629;
"X-Runtime" = "0.030651";
"X-UA-Compatible" = "IE=Edge,chrome=1";
"X-Varnish" = 1041100800;
Request44:Connection = "keep-alive";
"Content-Length" = 2268;
"Content-Type" = "application/vnd.apple.mpegurl";
Date = "Wed, 03 Dec 2014 20:52:44 GMT";
Server = nginx;
Via = "usher25:8933";
"X-Cache" = "MISS from CLONWLPROX1";
"X-Cache-Lookup" = "MISS from CLONWLPROX1:9999";
final:"Accept-Ranges" = bytes;
"Access-Control-Allow-Origin" = "https://secure.twitch.tv";
Age = 1;
"Cache-Control" = "no-cache, no-store, private";
Connection = "keep-alive";
"Content-Length" = 351;
"Content-Type" = "application/vnd.apple.mpegurl; charset=utf-8";
Date = "Wed, 03 Dec 2014 20:57:56 GMT";
Expires = "Wed, 03 Dec 2014 20:57:55 GMT";
"Last-Modified" = "Wed, 03 Dec 2014 20:57:53 GMT";
Server = nginx;
Via = "1.1 CLONWLPROX1 (squid/3.3.8)";
"X-Cache" = "MISS from CLONWLPROX1";
"X-Cache-Lookup" = "MISS from CLONWLPROX1:9999";以下是当我通过浏览器转到流时来自firefox的响应头。
request44:Accept-Ranges:bytes年龄:0缓存控制:max-age=0,专用,必须重新验证连接:保活内容编码:gzip内容长度:230内容类型:应用程序/json;字符集=utf-8日期:星期三,03 12月2014 21:07:44 GMT ETag:"74252dca9d2cf4e5da6f91f0d9fcc6c0“前端-Https:服务器上:nginx状态:200 OK变化:接受编码方式:1.1 varnish WWW-Authenticate:OAuth realm='TwitchTV‘X-API-Version:3 X-Frame-Options:SAMEORIGIN X-MH-Cache:appcache2;M X请求-Id:13c6dbe385ebb778b21596eadb83f4bc X-运行时:0.060941 X-UA-兼容:IE=边缘,chrome=1 X-清漆:1048532873
request44:Connection:keep-aliveContent-Length:2252 Content-Type:application/vnd.apple.mpegurl日期:Wed,03 Dec 2014 21:07:44 GMT服务器:nginx通过:usher16:8947
final:Accept-Ranges:bytes访问控制允许来源:https://secure.twitch.tv年龄:0缓存控制:无缓存,无存储,专用连接:保持连接内容长度:351内容类型:应用程序/vnd.apple.mpegurl;字符集=utf-8日期:星期三,2014年12月3日21:07:46 GMT过期时间:星期三,2014年12月21:07:47 GMT保持活跃:超时=50上次修改时间:星期三,2014年12月21:07:42 GMT服务器:nginx
发布于 2014-12-04 15:08:17
你遇到了Twitch的反视图机器人代码。到目前为止还没有人能够破解它的工作原理。他们根本没有谈论过这件事。它似乎是喜怒无常的。有时它真的工作得很好,而有时它似乎只做了一半。一些人认为,当检测到机器人时,他们会将结果随机化,以便混淆机器人编写者。显然Twitch的时间太多了。
https://stackoverflow.com/questions/27281737
复制相似问题