http://gh.ffshrine.org/soundtracks/599
发觉结构很简单,歌曲是以CD为目录存放的地址。
比如上面那个url就是编号为599的CD的url,链接进去有这支专辑的各首歌的对应url,比如第一首为:
http://gh.ffshrine.org/song/599/1
歌曲的真实地址也在这个页面里给出了。的确,浏览器里能看到歌曲的地址。
按道理很简单,直接wget就行了。
不过看了页面src后才发觉,事情没想象中那么容易。
歌曲的地址被javascript混淆过,是形如下面的一段东西:
<script>使用python可以很方便地decode,具体如下:
var data = "var%20addr%20%3D%20%222 (此处删除若干) 0A%09%09";
eval(unescape(data));
</script>
那么首先要decodeurl的encoding(what's this? refer here: http://www.blooberry.com/indexdot/html/topics/urlencoding.htm)
(
一开头我搞错了,以为是html的entity问题,这个可以使用perl的HTML::Entities模块来完成,具体如下:
// data是形如" <"这种东东
use HTML::Entities;
use decode_entities($data);
)
import urllib;
urllib.unquote("%20%3D");
于是得到了预期的东西:
'var addr = "http://dl1.ffshrine.org........ '
接下来,则要使用javascript的eval功能来执行这段javascript代码了……这里我考虑了两种方法:
1. 使用某个实际的html engine,如php…… 来得到最终链接地址
2. 使用某个独立的html engine,我搜索到了javax.script
具体代码如下:(script.java)
import javax.script.*;
import java.net.URL;
import java.io.*;
class script{
public static void main(String [] args){
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
try{
URL url = new URL( "http://gh.ffshrine.org/song/598/1" );
InputStreamReader reader = new FileReader( "/home/iveney/workspace/test.js" );
Object obj = engine.eval(reader);
System.out.println(obj);
}catch(Exception e){
e.printStackTrace();
}
}
}
最主要的一步是engine.eval,等同于原javascript中的eval.
编译能通过,但事实上他是有问题的。因为解码后我得到的是这样的东东(我把whitespace escape了):
var addr = "http://dl1.ffshrine.org/soundtracks/dl/598/00720b/Last Blade 2 Arrange/01_-_the_flower_that_blooms_in_the_moonlight.mp3";
function decode(address) {
var Address = "";
Address = address;
Address = unescape(Address);
function unescapesome(thesome) {
var newString = thesome;
newString = newString.replace(/%3A/g, ":");
newString = newString.replace(/%27/g, "'");
newString = newString.replace(/%28/g, "(");
newString = newString.replace(/%29/g, ")");
newString = newString.replace(/%21/g, "!");
newString = newString.replace(/%7E/g, "~");
return newString;
}
document.getElementById("linkcode").innerHTML = "<a href='" + unescapesome(escape(Address)) + "'>click here</a>";}
decode(addr);
里面有用到DOM model的document,发觉不能正常运行……
后来我没有深究究竟java这条路要怎么做,因为事实上我看到真实链接已经出来了 -。- 就在第一行!!!
于是马上用curl下载一系列的url,然后准备用相似步骤还原成原来的javascript得到地址。
但是没有得到预期的结果――还原成的是这样的东西:
var addr = new Array()我日!原来地址还被一个function wrap着呢!
addr[0] = "http://dl1.f";
addr[1] = "fshrine.org/";
addr[2] = "soundtracks/";
addr[3] = "dl/598/00720";
addr[4] = "b/Last Blade";
addr[5] = " 2 Arrange/m";
addr[6] = "vovld01_-_th";
addr[7] = "e_flower_tha";
addr[8] = "t_blooms_in_";
addr[9] = "the_moonligh";
addr[10] = "t.mp3";
function decode(address) {
var Address = "";
for (var i = 0; i != address.length; i++) {
Address += address[i]
}
Address = unescape(Address);
Address = Address.replace(/\/mvovld/, "/");
function unescapesome(thesome) {
var newString = thesome;
newString = newString.replace(/%3A/g, ":");
newString = newString.replace(/%27/g, "'");
newString = newString.replace(/%28/g, "(");
newString = newString.replace(/%29/g, ")");
newString = newString.replace(/%21/g, "!");
newString = newString.replace(/%7E/g, "~");
return newString;
}
document.getElementById("linkcode").innerHTML = "<a href='" + unescapesome(escape(Address)) + "'>click here</a>";}
decode(addr);
难道又要我用java来解释吗?
但是为什么我直接查看页面源代码会得到已经被解释过的javascript代码呢?
我猜测原因是因为referer的问题。用curl我没有构造合适的http参数,也许原来的页面有检查我是从哪个referer进去的。
然后我换wget试了试,却惊讶的发觉问题解决了:我能用wget得到正确的解释过的url……
由于最近忙,这里我先不深究,迟点问高手。
最后的shell代码如下:
#!/bin/bash
DIR=/tmp/mp3
#curl "http://gh.ffshrine.org/song/598/[1-12]" --create-dirs /tmp/mp3 -o "/tmp/mp3/#1.html"
mkdir $DIR
for i in `seq 1 48`
do
wget http://gh.ffshrine.org/song/599/$i -O "$DIR/$i.html"
done
for i in `seq 1 48`
do
str=`grep "var data" "$DIR/$i.html"`
str=`echo $str | cut -d '"' -f 2`
#echo $str
command="import urllib; js=urllib.unquote('$str'); print js"
# we get javascript now
js=`echo $command | python`
addr=`echo $js | head -n 1 | cut -d \" -f 2`
echo $addr
a=`wget "$addr" -P /win/d/Music/LastBladeIIOST/`
done
上面用到了不少工具,待我稍微注释。
首先是一个for loop用wget把所有页面下回来,存到相应位置。注意-O是指定输出文件名,而-P是指定输出的目录。
然后一个for loop处理decode stuff。
1.把该html文件中有用的那一段grep出来。
2.用cut把引号部分提取出来
3.用python decode之
4.再用cut把链接提取出来
5.用wget进行下载
今晚浪费了不少时间,不过当作锻炼一下自己吧。
No comments:
Post a Comment