上一篇写了基于单文件的直链解析,也不知道各位有没有搞定,是否获取到最终的直链,这篇文章就详细分析一下,并且获取最终直链。
我觉得蓝奏云这种很适合用来更新自己的程序,搞成自己的资源库啥的,搞到直链那就更方便了,虽然直链具有时效性,但是咱最普通的链接没有啊。
话不多说,打开bp,先按照正常访问流程走一遍
应该会和我一致,还是一样先看网页的js代码
var imwolz ='博客';
document.title = imwolz;
document.getElementById('sp_name').innerHTML=imwolz; var pwd;
var pgs;
var ib00id = '1712212717';
var _gyck6 = '69a235bb0219d3c66acadb1e932cfd22';
pgs =1;
function file(){
var pwd = document.getElementById('pwd').value;
$('#sub').val("提交中...");
$.ajax({
type : 'post',
url : '/filemoreajax.php?file=3899387',
data : {
'lx':2,
'fid':3899387,
'uid':'996269',
'pg':pgs,
'rep':'0',
't':ib00id,
'k':_gyck6,
'up':1,
'ls':1,
'pwd':pwd },
dataType : 'json',
success:function(msg){
//隐藏
document.getElementById("load2").style.display="none";
我们就看关键的这里就行,看这段代码,他向/filemoreajax.php?file=3899387发送了post请求,参数’lx’:2,‘fid’:3899387,‘uid’:‘996269’,‘pg’:pgs,‘rep’:‘0’,‘t’:ib00id,‘k’:_gyck6,‘up’:1,ls,pwd
请求完了之后我们可以看见返回了文件夹里面的信息
我们看下一个链接发现是直接拼接的id
我们继续看,发现还是跳转的链接
然后我们分析跳转后的界面
var wsk_sign = 'c20230908';
var aihidcms = 'E1co';
var ciucjdsdc = '2';
var ws_sign = 'c20230818';
var sasign = 't';
var ajaxdata = '?ctdf';
$.ajax({
type : 'post',
url : '/ajaxm.php?file=50721445',
data : { 'action':'downprocess','signs':ajaxdata,'sign':'VTNQbg4_aU2IACVNsCjoFOQRrVWBVPQU1BDJUZgdvUGRUclFyXDwBZANiB2BXMQIxAWpQZ18xCzAEMQ_c_c','websign':ciucjdsdc,'websignkey':aihidcms,'ves':1 },
dataType : 'json',
success:function(msg){
var date = msg;
if(date.zt == '1'){
$("#tourl").html("<a href="+date.dom+"/file/"+ date.url +" target=_blank rel=noreferrer><span class=txt>电信下载</span><span class='txt txtc'>联通下载</span><span class=txt>普通下载</span></a>");
setTimeout('$("#outime").css("display","block");',1800000);
}else{
$("#tourl").html("网页超时,请刷新");
};
},
error:function(){
$("#tourl").html("获取失败,请刷新");
}
});
发现又post到一个/ajaxm.php?file=50721445参数若干
然后终于获取到我们想要的东西
还有我们最终想要的直链
分析到这里一个完整的流程就搞定了,接下来我们开始上idea来编写代码
我这里还是引入okhttp3和fastjson2来解析数据
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.1</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.47</version>
</dependency>
一样的先写一个controller,让用户自主传入,url和密码
public String LanZouFile(@RequestParam String url,@RequestParam String PassWord) {
return null;
}
请求用户的给的url,获取网页的源码,还记得我们第一步要干嘛吗?
解析js,构造url和参数
参数一大把,我还是采用最朴素的正则来匹配,唉,没有ai,估计正则我都要写好久,,,
String html=requests.GetWebPage(url);
String FilePattern = "/filemoreajax\\.php\\?file=(\\d+)";
String UrlPattern = "(https?://[^/]+)";
String FidPattern = "('|\")?fid('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String UidPattern = "('|\")?uid('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String LxPattern = "('|\")?lx('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String RepPattern = "('|\")?rep('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String UpPattern = "('|\")?up('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String LsPattern = "('|\")?ls('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String FileCode = characterTools.getCharacter(html, FilePattern, 1);//获取urls
String url_1 =characterTools.getCharacter(url, UrlPattern, 0);
String fid=characterTools.getCharacter(html, FidPattern, 3).replaceAll("['\"]", "");
String uid=characterTools.getCharacter(html, UidPattern, 3).replaceAll("['\"]", "");
String lx=characterTools.getCharacter(html, LxPattern, 3).replaceAll("['\"]", "");
String rep=characterTools.getCharacter(html, RepPattern, 3).replaceAll("['\"]", "");
String up=characterTools.getCharacter(html, UpPattern, 3).replaceAll("['\"]", "");
String ls=characterTools.getCharacter(html, LsPattern, 3).replaceAll("['\"]", "");
String FileUrl =url_1+ "/filemoreajax.php?file=" + FileCode;
蓝奏云狗的地方就来了他参数中有个t和k两个参数,我开始也以为就是那俩变量,不会改变,但是写道后面,前面就开始报错,我分析了一下,用不同浏览器来请求,发现他变量名会变化,我靠,我还是第一次碰见变量名会变化的,,,
没办法只能通过匹配取出var全部内容了
List<String> values = new ArrayList<>();
Pattern pattern = Pattern.compile("var (\\w+) = '(.*?)';");
Matcher matcher = pattern.matcher(html);
while (matcher.find()) {
String value = matcher.group(2);
values.add(value);
}
String Params="lx="+lx+"&fid="+fid+"&uid="+uid+"&pg=1&rep="+rep+"&t="+ values.get(0) +"&k="+values.get(1)+"&up="+up+"&ls="+ls+"&pwd="+PassWord;
String responseData = requests.PostWithData(FileUrl, Params, url_1);
来到这一界面还是比较简单,我直接取出所有的id和name
JSONObject jsonObject = JSONObject.parseObject(responseData);
// 获取 text 数组
JSONArray textArray = jsonObject.getJSONArray("text");
JSONArray textArray1 = new JSONArray();
// 遍历 text 数组
for (Object obj : textArray) {
if (obj instanceof JSONObject) {
JSONObject item = (JSONObject) obj;
// 提取 id 和 name
String id = item.getString("id");
String name = item.getString("name_all");
String FileUrl_1=url_1+"/"+id;
}}
通过拼接请求终于来到下一界面,还是使用正则匹配出src,我真的服了,他注释里面还有个src。。
String responseData1 = requests.GetWebPage(FileUrl_1);
List<String> srcList = new ArrayList<>();
Pattern Srcpattern = Pattern.compile("src=['\"](.*?)['\"]");
Matcher matchers = Srcpattern.matcher(responseData1);
while (matchers.find()) {
String src = matchers.group(1);
srcList.add(src);
}
String sRC = srcList.get(1);
然后就来到最后,一个界面,还是来构造链接来分析
String webdata=requests.GetWebPage(url_1+sRC);
String Signs=characterTools.getCharacter(webdata, "var ajaxdata = '(.*)';", 1);
String Sign=characterTools.getCharacter(webdata, "'sign':'(.*?)'", 1);
String WebSign=characterTools.getCharacter(webdata, "var ciucjdsdc = '(.*)';", 1);
String WebSignToken=characterTools.getCharacter(webdata, "var aihidcms = '(.*)';", 1);
String params = "action=downprocess&signs="+Signs+"&sign="+Sign+"&websign="+WebSign+"&websignkey="+WebSignToken+"&ves=1";
String FileCodes = characterTools.getCharacter(webdata, "/ajaxm\\.php\\?file=(\\d+)", 1);//获取urls
String responseData2 = requests.PostWithData(url_1+"/ajaxm.php?file="+FileCodes, params, url_1+sRC);
JSONObject jsonObjects = JSONObject.parseObject(responseData2);
String dom = (String) jsonObjects.get("dom");
String lat = (String) jsonObjects.get("url");
String LatUrl = dom + "/file/" + lat;
到这一步我们也就搞到伪直链,我们浏览器点开可以下载,但是我们下载器不行,我们要获取到他302重定向的url,也就是Location,响应头,他这里对头部的验证很严谨,我最开始都是直接给我定向去验证链接了,我们要把所有的请求头都携带上,其他的对于请求头也有检验请求时要携带User-Agent,Referer
然后就搞定了,再贴一下整合的,以及测试返回结果
@RequestMapping("/LanZouFile")
public String LanZouFile(@RequestParam String url,@RequestParam String PassWord) {
String html=requests.GetWebPage(url);
String FilePattern = "/filemoreajax\\.php\\?file=(\\d+)";
String UrlPattern = "(https?://[^/]+)";
String FidPattern = "('|\")?fid('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String UidPattern = "('|\")?uid('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String LxPattern = "('|\")?lx('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String RepPattern = "('|\")?rep('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String UpPattern = "('|\")?up('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String LsPattern = "('|\")?ls('|\")?\\s*:\\s*(\\d+|'[^']+'|\"[^\"]+\")";
String FileCode = characterTools.getCharacter(html, FilePattern, 1);//获取urls
String url_1 =characterTools.getCharacter(url, UrlPattern, 0);
String fid=characterTools.getCharacter(html, FidPattern, 3).replaceAll("['\"]", "");
String uid=characterTools.getCharacter(html, UidPattern, 3).replaceAll("['\"]", "");
String lx=characterTools.getCharacter(html, LxPattern, 3).replaceAll("['\"]", "");
String rep=characterTools.getCharacter(html, RepPattern, 3).replaceAll("['\"]", "");
String up=characterTools.getCharacter(html, UpPattern, 3).replaceAll("['\"]", "");
String ls=characterTools.getCharacter(html, LsPattern, 3).replaceAll("['\"]", "");
String FileUrl =url_1+ "/filemoreajax.php?file=" + FileCode;
List<String> values = new ArrayList<>();
Pattern pattern = Pattern.compile("var (\\w+) = '(.*?)';");
Matcher matcher = pattern.matcher(html);
while (matcher.find()) {
String value = matcher.group(2);
values.add(value);
}
String Params="lx="+lx+"&fid="+fid+"&uid="+uid+"&pg=1&rep="+rep+"&t="+ values.get(0) +"&k="+values.get(1)+"&up="+up+"&ls="+ls+"&pwd="+PassWord;
String responseData = requests.PostWithData(FileUrl, Params, url_1);
JSONObject jsonObject = JSONObject.parseObject(responseData);
// 获取 text 数组
JSONArray textArray = jsonObject.getJSONArray("text");
JSONArray textArray1 = new JSONArray();
// 遍历 text 数组
for (Object obj : textArray) {
if (obj instanceof JSONObject) {
JSONObject item = (JSONObject) obj;
// 提取 id 和 name
String id = item.getString("id");
String name = item.getString("name_all");
String FileUrl_1=url_1+"/"+id;
String responseData1 = requests.GetWebPage(FileUrl_1);
List<String> srcList = new ArrayList<>();
Pattern Srcpattern = Pattern.compile("src=['\"](.*?)['\"]");
Matcher matchers = Srcpattern.matcher(responseData1);
while (matchers.find()) {
String src = matchers.group(1);
srcList.add(src);
}
String sRC = srcList.get(1);
String webdata=requests.GetWebPage(url_1+sRC);
String Signs=characterTools.getCharacter(webdata, "var ajaxdata = '(.*)';", 1);
String Sign=characterTools.getCharacter(webdata, "'sign':'(.*?)'", 1);
String WebSign=characterTools.getCharacter(webdata, "var ciucjdsdc = '(.*)';", 1);
String WebSignToken=characterTools.getCharacter(webdata, "var aihidcms = '(.*)';", 1);
String params = "action=downprocess&signs="+Signs+"&sign="+Sign+"&websign="+WebSign+"&websignkey="+WebSignToken+"&ves=1";
String FileCodes = characterTools.getCharacter(webdata, "/ajaxm\\.php\\?file=(\\d+)", 1);//获取urls
String responseData2 = requests.PostWithData(url_1+"/ajaxm.php?file="+FileCodes, params, url_1+sRC);
JSONObject jsonObjects = JSONObject.parseObject(responseData2);
String dom = (String) jsonObjects.get("dom");
String lat = (String) jsonObjects.get("url");
String LatUrl = dom + "/file/" + lat;
String RedirectUrl = requests.getRedirectUrl(LatUrl);
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("name",name);
jsonObject1.put("url",RedirectUrl);
textArray1.add(jsonObject1);
}
}
JSONObject json = new JSONObject();
json.put("code", 200);
json.put("msg", "success");
json.put("data", textArray1);
return json.toJSONString();
}
用到的方法
/**
* 获取字符
* @param Text 文本
* @param Patter 正则
* @param code 代码
* @return 字符
*/
public String getCharacter(String Text,String Patter,int code) {
Pattern r = Pattern.compile(Patter);
Matcher m = r.matcher(Text);
if (m.find()){
return m.group(code);
}
return null;
}
private final OkHttpClient client = new OkHttpClient();
/**
* 获取重定向地址
* @param url 请求地址
* @return 返回重定向地址
*/
public String getRedirectUrl(String url) {
// 构建伪头字段
OkHttpClient client = new OkHttpClient.Builder()
.followRedirects(false) // 不自动遵循重定向
.build();
// 构建一个Request对象
Request request = new Request.Builder()
.url(url)
.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
.addHeader("Accept-Encoding", "gzip, deflate, br, zstd")
.addHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
.addHeader("Cookie", "down_ip=1")
.addHeader("Sec-Ch-Ua", "\"Google Chrome\";v=\"123\", \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"123\"")
.addHeader("Sec-Ch-Ua-Mobile", "?0")
.addHeader("Sec-Ch-Ua-Platform", "\"Windows\"")
.addHeader("Sec-Fetch-Dest", "document")
.addHeader("Sec-Fetch-Mode", "navigate")
.addHeader("Sec-Fetch-Site", "none")
.addHeader("Sec-Fetch-User", "?1")
.addHeader("Upgrade-Insecure-Requests", "1")
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36")
.build();
try {
// 发送请求
Response response = client.newCall(request).execute();
// 检查响应码来看是否是重定向
if (response.isRedirect()) {
// 从Location头获取重定向URL
String redirectUrl = response.header("Location");
return redirectUrl;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 发起 POST 请求
* @param url 请求地址
* @param Params 请求体
* @return 返回请求结果
*/
public String PostWithData(String url,String Params,String Referer) {
Request request = new Request.Builder()
.url(url)
.addHeader("Referer", Referer)
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36")
.post(RequestBody.create(Params, MediaType.parse("application/x-www-form-urlencoded")))
.build();
// 发送请求并获取响应
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
System.out.println("Request failed");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 下载网页
* @param url 网页地址
* @return 返回网页内容
*/
public String GetWebPage(String url) {
Request request = new Request.Builder()
.url(url)
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36")
.build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
// 请求失败
System.out.println("请求失败: " + response.code() + " " + response.message());
}
} catch (IOException e) {
// 异常处理
e.printStackTrace();
}
return null;
}
搞定,下一个项目打算把这个进行v1封装一下,实现对话解析,毕竟万物皆可v1