2013年11月15日 星期五

使用Greasemonkey脚本彻底摆脱BT工厂下载弹窗

今天有空,所以更新一下多年没有动过的博客。
事情是这样的……
正是因为今天有空,所以我为了陶冶情操,文化交流网站‘BT工厂’看了看最近更新的新的文化交流内容……
然后呢,我一如既往的点开了很多很多的文化交流种子下载页……
但是把这些下载页的种子全都下载下来是一件很痛苦的事情!
来看一下代码:
<form action="../down.php" method="post">
  <input type="hidden" value="torrent" id="type" name="type" />
  <input type="hidden" value="#######" id="id" name="id" />
  <input type="hidden" value="#######" id="name" name="name" />
  <input type="submit" value="  下 载 /  down  " onclick="openpage()" class="round_box" id="down_btn"  />
</form>
可以看到,这个下载按钮被点击时不但会提交表单开始下载文件,同时还会触发openpage函数。
这个函数定义如下: 
function openpage() {
var rand=Math.floor(Math.random()*2+1);
switch(rand)
{
 case 1:
 window.open('http://??.?????.biz/','','scrollbars=1,resizable=1').blur();
 break;
 case 2:
 window.open('http://??.?????.info/','','scrollbars=1,resizable=1').blur();
 break;
 default:
 break;
 }
window.focus(); 
}
 
这才是最蛋疼的!每下载一个种子文件都要经过如下操作:
1点击一下下载按钮
2关闭弹出来的网站主页
3下载文件
4关闭网页

如果只是一个种子还好,但是我每次可都是要下载大量种子的啊!折腾不起啊啊啊啊!
然后我就去下载了greasemonkey插件然后开始折腾用户js脚本……
话说firefox这一点就不如换芯之前的opera方便,opera原生支持User CSS和User JS! 

解决弹窗的话很容易,只需要一句:
document.getElementById("down_btn").onclick = null;
 
好吧,即便如此还是太麻烦了…… 
毕竟有那么多种子等着我去下载学习呢,要是不用点击下载按钮就好了……
这也好说,这么一句就够了!
document.getElementsByTagName("form")[0].submit();
嗯…… 
这下好多了,尤其是我还在FireFox里设置了种子文件默认是保存操作,省得我一下一下点了。

不过好像还是有点不爽啊,既然都自动下载了,
那么下载了之后我又何必非要很傻逼的去手动关掉那些下载页!我想要它自动关掉!
于是就有了如下最终版代码:
// ==UserScript==
// @name        AntiBTGCPop&AutoDownload
// @namespace   wye-ANGER.blogspot.com
// @description AntiBTGCPop & AutoDownload
// @include     http://www3.*domn.com/*/file.php/*.html
// @include     http://www3.*down.info/*/file.php/*.html
// @include     http://www3.*down.com/*/file.php/*.html
// @version     1
// @grant       none
// ==/UserScript==

document.getElementsByTagName("form")[0].submit();
document.getElementsByTagName('html')[0].innerHTML
    = document.getElementsByTagName('form')[0].outerHTML;
var http_request = new XMLHttpRequest();
document.getElementById("down_btn").onclick = null;

function onResponse()
{
    if(http_request.readyState!=4) return;
    if(http_request.status!=200)
    {
        alert("Problem retrieving XML data");
        return;
    }
    //assume browser cached torrent
    setTimeout("window.close()",1000);
}

var nameval = document.getElementById("name").value;
var idval = document.getElementById("id").value;
var arg="type=torrent" +"&name="+nameval+"&id="+idval;

http_request.onreadystatechange=onResponse;
http_request.open('POST',"../down.php", true);
http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
http_request.send(arg);

这个脚本需要配合两项FireFox来使用
1.about:config中的dom.allow_scripts_to_close_windows需要设置为true以允许js关闭窗口
2.火狐应设置自动保存种子文件而不询问(没试过,或许不这么设置也可以用)
使用这个脚本之后,只需要按住Ctrl点击下载页连接,下载页在后台打开后会自动开始下载,然后自动关闭下载页!
这下终于可以痛痛快快的进行文化交流了~
 
找脚本的同学看到这里就够了,如果对代码还有点兴趣可以继续看。 
 
稍微解释一下上面的脚本吧。
一开始先对form进行submit()先通过能触发下载的正规渠道发出请求。
然后问题又来了,从浏览器发出请求到服务器完成响应的间隔时间是不可预测的!
如果窗口关早了,服务器还没来得及响应请求,那文件都没来得及开始下载。 
对于BT工厂这样的文化交流网站更是如此!慢起来的时候那真是^$#&*@(&#$*@)&$*#@!
 
那么就需要简单的判断一下服务器是否已经响应了下载请求。
对此,我的解决方案是先调用submit()走正规途径提交表单。
然后通过XMLHttpRequest提交一个同样的表单。 
这时假设这两次提交表单对应的HTTP请求被浏览器缓存优化,
认定多出来的一次请求不会造成太多的网络负担(本来一个种子文件也不会造成多少负担)。 
假定等后提交的请求服务器完成全部响应时,前一个通过submit()发送的请求已经至少完成了初步的响应。
那么此时关闭窗口应该至少浏览器已经开始下载了。
 
至此,大功告成~