牢騷
射手網關門了,聲討的話網上已經鋪天蓋地,我不想多啰嗦,我只說一句:
某些部門的老爺有折騰字幕組的閑工夫,不如去整治一下鋪天蓋地的電視購物騙子廣告,我會給你們燒香感謝的。
正題
射手網關站之后,網上流傳一個射手下載器,簡單研究了一下,發現這東西調用的是射手播放器的api,一部電影只能獲取一個字幕,無法選擇,而且很多字幕都不匹配。
那么問題來了,既然射手播放器仍然可以獲取字幕,那么證明字幕文件仍然存在于射手的服務器上。因為它們是同一個來源,我們能不能用其他方法也從服務器上得到字幕呢?也就是說,射手網只是關閉了前臺頁面,我們只要獲取字幕的文件名索引,仍然可以下載到字幕文件,于是我想到了百度快照。
只需在百度里輸入site:shooter.cn 電影名稱,就會出現很多結果,這些結果現在直接打開,會跳轉到射手首頁,可是我們可以點擊快照:
有的快照是結果頁的,有的快照打開會出現字幕列表,如果出現列表,打開其中的任意一項仍然會跳轉到首頁,怎么辦呢?好辦,我們先去看列表里任意一項的鏈接,鏈接的最后是一個xml文件,我們用這個xml文件名做關鍵字繼續搜索,就能得到它的結果頁快照:
好了,第一步已經完成了,百度快照幾乎保存了所有射手字幕的索引,只要用一定的技巧,都可以搜出來,那么接下來,我們就要獲取字幕。
通過分析快照結果頁中的射手源碼,我發現了一個貓膩,即,射手的每一個字幕文件都有一個唯一的id,而這個id以下載次數的形式顯示在每個字幕的頁面中,也就是說,頁面中顯示的下載次數,并不是真正的次數,而是字幕的id號:
有了這個id,一切好辦,射手現在還能訪問的頁面,除了那個告別首頁,還有一個字幕上傳頁面 http://shooter.cn/sub/upload.html,網站都關了還留著上傳頁面干嘛?一定有問題,那么打開這個頁面,查看一下里面所有的js代碼:
終于,在loadmain.js里面我發現了這樣的代碼:
function shtgdownfile(g, j, f, d) {
var a = makeXmlReq();
try {
g.target = ""
} catch (c) {
alert(c)
}
a.open("GET", "/files/file3.php?hash=" + shtg_filehash + "&fileid=" + j, false);
a.send("");
if (a.status == 200 || a.status == 304) {
var b = a.responseText;
if (b && b.indexOf("ERR:") < 0) {
showcounter("downcounter", j, "file", "total", 1);
b = (shtg_calcfilehash(b));
var h = "http://file1.shooter.cn" + b;
if (!d) {
g.href = h;
g.target = "_blank"
}
if (f) {
location.href = h
}
return true
}
}
alert("文件獲取失敗:" + a.status + " _ " + b)
}
一切一目了然,我們只需照做即可
首先,在瀏覽器里面輸入:
http://www.shooter.cn/files/file3.php?hash=duei7chy7gj59fjew73hdwh213f&fileid=所要下載的字幕文件的id
(其中,duei7chy7gj59fjew73hdwh213f就是上面代碼中的shtg_filehash,它是個常量,值同樣來自于loadmain.js),會返回如下的結果。注意這里的編碼要用utf8,否則顯示亂碼:
這是一段經過變換的post參數,要變換回去,我們按照上面代碼中所寫,利用射手自身的一個函數
shtg_calcfilehash,先用瀏覽器訪問http://shooter.cn/sub/upload.html,然后讓瀏覽器執行:javascript:var address=shtg_calcfilehash('剛才得到的字符串');alert(address);
非常好,直接彈出了正確的post參數,在這段參數的前面加上http://file1.shooter.cn,直接訪問,bingo!!!,字幕終于成功下載了!
神器:自動化下載腳本
上面的下載過程實在太繁瑣,如果有很多字幕要下載,每個都這樣來一遍,不得累死啊,所以,一個下載腳本是必須的。
在這里我要介紹一個強大的爬蟲引擎:phantomjs,它可以用javascript做開發,只有一個可執行文件卻非常強大,實際上它是一個沒有界面的webkit引擎瀏覽器,而且是跨平臺的,它的好處一個是腳本語言直接使用js,這樣頁面中很多js函數它可以直接使用和修改,另一個是它可以方便的抓取到用ajax異步生成的頁面。
好了,介紹結束,腳本代碼如下:
/*
Name: phantomjs射手字幕下載腳本
File: shooter.js
Author: b41k3r
*/
var system = require('system')
var fileid = system.args[1];
var page = require('webpage').create();
var execFile = require("child_process").execFile
var fs = require("fs");
var filename = "address.txt";
if (!fs.exists(filename)) {
var file = fs.open(filename, 'a');
}else{
fs.remove(filename);
var file = fs.open(filename, 'a');
}
var url = "http://www.shooter.cn/files/file3.php?hash=duei7chy7gj59fjew73hdwh213f&fileid="+fileid;
page.open(url, function (status) {
if (status !== 'success') {
console.log('Unable to post!');
} else {
if (page.injectJs('filehash.js')) {
var address = 'http://file1.shooter.cn' + page.evaluate(function(post_parameter) {return shtg_calcfilehash(post_parameter);},page.plainText);
console.log(address);
file.write(address);
file.close();
execFile("wget", ["-O", fileid + ".rar","-i", "address.txt"], null, function (err, stdout, stderr) {
console.log("execFileSTDOUT:", JSON.stringify(stdout))
console.log("execFileSTDERR:", JSON.stringify(stderr))
})
}
}
setTimeout(function () { phantom.exit(0) }, 2000)
});
phantomjs沒有下載功能,這里的下載直接調用了wget,另外注意上面的page.injectJs('filehash.js'),這個包含進來的filehash.js文件的內容實際上就是射手的變換函數shtg_calcfilehash,我把它放在了本地執行,phantomjs的好處在這里完全體現。
在命令行執行: phantomjs shooter.js 字幕文件的id :
腳本成功的下載了字幕。
一切大功告成,射手網復活了。
phantomjs以及腳本源碼和wget打包下載
http://pan.baidu.com/s/1o6JVdW2