这个是我发现的源码解析,快手,

 

package blog.rs1314.cn.test;import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;import javax.script.ScriptException;import blog.rs1314.cn.kuaishou.*;
import org.json.JSONArray;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;public class KuaiShouTest {public static void main(String[] args) throws IOException, ScriptException {long time = new Date().getTime();long nextPageTime = KuaiShouNextPage.getNextPageTime(time);KuaishouUserVo inputClientUrl = inputClientUrl("http://www.hack95.com/s/6vyyITXo",0,time,nextPageTime);List userVideoList = inputClientUrl.getUserVideoList();System.out.println(userVideoList.size());ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(10000), Executors.defaultThreadFactory());for(int j=0;j getVideoList(KuaishouUserVo kuaishouUserVo) {KuaiShou kuaiShou = null;String readVideoPlayUrl = kuaishouUserVo.getReadVideoPlayUrl();JSONObject jsonObject = new JSONObject(readVideoPlayUrl);System.out.println(jsonObject);JSONArray feeds = jsonObject.getJSONArray("feeds");int length = feeds.length();List kuaiShouList = new ArrayList(length);for (int j = 0; j < length; j++) {kuaiShou = new blog.rs1314.cn.kuaishou.KuaiShou();try {JSONObject jsonObject1 = feeds.getJSONObject(j);//无水印频地址JSONArray main_mv_urls = jsonObject1.getJSONArray("main_mv_urls");JSONObject jsonObject2 = main_mv_urls.getJSONObject(0);String videoUrl = jsonObject2.getString("url");kuaiShou.setVideoUrl(videoUrl);//share_info  ("userId=3xwvjr74prbhz9s&photoId=3xfvvjb92hqpgdq",)String share_info = jsonObject1.getString("share_info");kuaiShou.setShare_info(share_info);String photoId = String.valueOf(jsonObject1.get("photo_id"));kuaiShou.setPhotoId(photoId);//视频名称String videoName = jsonObject1.getString("caption");videoName = videoName.replaceAll("\n", "").replaceAll(" ", "");kuaiShou.setVideoName(videoName);}catch (Exception e){}kuaiShouList.add(kuaiShou);}return kuaiShouList;}/*** 获取真实无水印视频地址json** @param kuaishouUserVo* @return*/private static String getReadVideoPlayUrl(KuaishouUserVo kuaishouUserVo) {Map sigUrlamap = kuaishouUserVo.getSigUrl();String queryStringUrl = sigUrlamap.get(QUERYSTRING);String bodyString = sigUrlamap.get(BODYSTRING);OkHttpClient okHttpClient = new OkHttpClient();FormBody.Builder requestBody = new FormBody.Builder();Map params = getMapFromStr(bodyString);Set keySet = params.keySet();for (String key : keySet) {String value = params.get(key);requestBody.add(key, value);}FormBody formBody = www.hack95.com();Request request = new Request.Builder().url(READURL + queryStringUrl).post(formBody).addHeader("Cookie", "token=988045ae46624450873917df582dfd43-1355462031").addHeader("User-Agent", "kwai-android").addHeader("Connection", "keep-alive").addHeader("Accept-Language", "zh-cn").addHeader("X-REQUESTID", randomRequestId()).addHeader("Content-Type", "application/x-www-form-urlencoded").addHeader("Host", "www.hack95.com").build();Call call = okHttpClient.newCall(request);try {Response response = call.execute();return response.body().string();} catch (IOException e) {throw new RuntimeException("地址错误或者获取失败,联系Q群号414572608");}}/*** 第二步* 1. 用户输入的分享地址 ,获取重定向后的地址* 2. 获取用户加密id和加密后作品id* 3. 获取真实的用户id* 4. 得到sig后的请求连接,post请求* 5.获取真实无水印视频地址json* 6.获取List*/private static KuaishouUserVo inputClientUrl(String url,int temp,long time,long nexttime) {KuaishouUserVo kuaishouUserVo = new KuaishouUserVo();try {//用户输入的分享地址 ,获取重定向后的地址String redirectUrl = new OkHttpClient().newCall(new Request.Builder().url(url).build()).execute().request().url().toString();redirectUrl = redirectUrl.substring(0, redirectUrl.indexOf("?"));//获取用户加密id和加密后作品idString regex = "https://www.hack95.com/u/";redirectUrl = redirectUrl.substring(redirectUrl.indexOf(regex) + regex.length());String[] split = redirectUrl.split("/");kuaishouUserVo.setUserIdJiaMi(split[0]);kuaishouUserVo.setPhotoId(split[1]);//获取真实的用户idkuaishouUserVo.setUserId(getUserId(split[0]));if(temp ==0){//得到sig后的请求连接,post请求Map sigUrl = getSigUrl(kuaishouUserVo.getUserId());kuaishouUserVo.setSigUrl(sigUrl);}else{Map sigUrl = getSigUrl(kuaishouUserVo.getUserId(),time,1,nexttime);kuaishouUserVo.setSigUrl(sigUrl);}//获取真实无水印视频地址jsonString readVideoPlayUrl = getReadVideoPlayUrl(kuaishouUserVo);kuaishouUserVo.setReadVideoPlayUrl(readVideoPlayUrl);//获取listList videoList = getVideoList(kuaishouUserVo);kuaishouUserVo.setUserVideoList(videoList);return kuaishouUserVo;} catch (IOException e) {e.printStackTrace();throw new RuntimeException("地址错误或者获取失败,联系Q群号414572608");}}/*** 第一步:: 设置存活时间   token   建议60分钟请求一次** @throws IOException*/private static void setttingLiveTime() {String url = "http://www.hack95.com/rest/n/hybrid/version?mod=HUAWEI%28COL-AL10%29&appver=6.4.1.9151&isp=CMCC&lon=0&language=zh-cn&sys=ANDROID_9&__NStokensig=30384a09fe4d364d48a9be9f182f80e76e964f870fedbd537a7a009ecd5dd60d&max_memory=384&ud=1355462031&sig=9c303bd81cc2c0575cecb7bc385c89c5&client_key=3c2cd3f3&oc=HUAWEI_KWAI&net=WIFI&lat=0&app=0&kpf=ANDROID_PHONE&ver=6.4&c=HUAWEI_KWAI&os=android&ftt=&kpn=KUAISHOU&token=988045ae46624450873917df582dfd43-1355462031&country_code=cn&hotfix_ver=&did_gt=1557994638922&iuid=&did=ANDROID_03c600e64ee0e3a7";Request build = new Request.Builder().url(url).addHeader("Cookie", "token=988045ae46624450873917df582dfd43-1355462031").addHeader("User-Agent", "kwai-android").addHeader("Connection", "keep-alive").addHeader("Accept-Language", "zh-cn").addHeader("X-REQUESTID", randomRequestId()).addHeader("Host", "www.hack95.com").build();String html = "";try {html = new OkHttpClient().newCall(build).execute().body().string();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(html);}/*** 随机请求id  //范围是   436650000 - 436669999** @return*/private static String randomRequestId() {int temp = 436669999 - 436650000;int nextInt = new Random().nextInt(temp) + 436650000;return String.valueOf(nextInt);}/*** https://www.hack95.com/u/3xwvjr74prbhz9s* 获取真实的用户id** @param userIdjiaMi 3xwvjr74prbhz9s* @return*/public static String getUserId(String userIdjiaMi) {String url = "https://www.hack95.com/u/" + userIdjiaMi;String temp = "";try {String html = new OkHttpClient().newCall(new Request.Builder().url(url).build()).execute().body().string();Document parse = Jsoup.parse(html);Elements eles = parse.getElementsByTag("script");for (Element ele : eles) {  //configModelString script = ele.toString();if (script.indexOf("configModel") > -1) {script = script.substring(script.indexOf("liveDetailModel") + 18, script.lastIndexOf("webSocketInfo") + 18);JSONObject jsonObject = new JSONObject(script);jsonObject = jsonObject.getJSONObject("user");Object object = jsonObject.get("userId");temp = String.valueOf(object);}}return temp;} catch (IOException e) {throw new RuntimeException("地址错误或者获取失败,联系Q群号414572608");}}/*** 获取签名后的请求连接** @param userid 真实的用户id    post请求* @return*/public static Map getSigUrl(String userid) {long time = new Date().getTime();return getSigUrl(userid,time,0,0);}public static Map getSigUrl(String userid,long time,int temp,long nexttime) {if(temp == 0){Map sig = getSig(userid, time, 30);String genSignature = genSignature(getMapFromStr(sig.get(SIGSTRING)), FANS_SALT);sig = getSigUrlT(userid, time, 30, genSignature);return sig;}else{Map sig = getSignextPage(userid, time, 30,nexttime);String genSignature = genSignature(getMapFromStr(sig.get(SIGSTRING)), FANS_SALT);sig = getSigUrlT(userid, time, 30, genSignature);return sig;}}/*** Post请求 异步* 使用 Callback 回调可返回子线程中获得的网络数据** @param url* @param params 参数*/public static void httpPost(final String url, final Map params, final Callback callback) {new Thread(new Runnable() {@Overridepublic void run() {OkHttpClient okHttpClient = new OkHttpClient();FormBody.Builder formBodyBuilder = new FormBody.Builder();Set keySet = params.keySet();for (String key : keySet) {String value = params.get(key);formBodyBuilder.add(key, value);}FormBody formBody = www.hack95.com();Request request = new Request.Builder().post(formBody).url(url).build();//Response response = null;okHttpClient.newCall(request).enqueue(callback);}}).start();}public static String genSignature(Map params, String salt) {if (params == null) {return null;}String sign = "";StringBuffer sb = new StringBuffer();try {// 1. 字典升序排序SortedMap sortedMap = new TreeMap<>(params);// 2. 拼按URL键值对Set keySet = sortedMap.keySet();for (String key : keySet) {//sign不参与算法if (key.equals("sig") || key.equals("__NStokensig")) {continue;}String value = sortedMap.get(key);sb.append(key + "=" + URLDecoder.decode(value, "UTF-8"));}String uriString = sb.toString();uriString = uriString + salt;//System.out.println("My String: \n" + uriString);// 3. MD5运算得到请求签名sign = www.hack95.com5(uriString);//System.out.println("My Sign:\n" +sign);} catch (Exception e) {e.printStackTrace();}return sign;}public static Map getMapFromStr(String str) {if (str == null || "".equalsIgnoreCase(str)) {return null;}String[] arr = str.split("\\&");Map map = new HashMap<>();for (String item : arr) {String[] itemArr = item.split("=", 2);map.put(itemArr[0], itemArr[1]);}return map;}private static Map getSig(String userid, long time, int size) {return getSigUrlT(userid, time, size, "001a0805a029a8a466f8492a37d077ae");}private static Map getSignextPage(String userid, long time, int size,long neexrtime) {return getSigUrlTnextPage(userid, time, size, "001a0805a029a8a466f8492a37d077ae",neexrtime);}private static Map getSigUrlTnextPage(String userid, long time, int size, String sig,long neexrtime) {String queryString = "app=0&kpf=ANDROID_PHONE&ver=6.4&c=HUAWEI_KWAI&mod=HUAWEI%28COL-AL10%29&appver=6.4.1.9151&ftt=&isp=CMCC&kpn=KUAISHOU&lon=0&language=zh-cn&sys=ANDROID_9&max_memory=384&ud=1355462031&country_code=cn&oc=HUAWEI_KWAI&hotfix_ver=&did_gt=" + time + "&iuid=&net=WIFI&did=ANDROID_03c600e64ee0e3a7&lat=0";String bodyString = "token=988045ae46624450873917df582dfd43-1355462031&user_id=" + userid + "&lang=zh&count=" + size + "&privacy=public&pcursor="+neexrtime+"&referer=1&browseType=1&sig=" + sig + "&client_key=3c2cd3f3&os=android&__NStokensig=8581c63e468fa7829def9cf79fdebae7fc8f15dd021aa68724928c86872dc554";String sigString = new StringBuilder().append(queryString).append("&").append(bodyString).toString();Map map = new HashMap();map.put(QUERYSTRING, queryString);map.put(BODYSTRING, bodyString);map.put(SIGSTRING, sigString);return map;}private static Map getSigUrlT(String userid, long time, int size, String sig) {String queryString = "app=0&kpf=ANDROID_PHONE&ver=6.4&c=HUAWEI_KWAI&mod=HUAWEI%28COL-AL10%29&appver=6.4.1.9151&ftt=&isp=CMCC&kpn=KUAISHOU&lon=0&language=zh-cn&sys=ANDROID_9&max_memory=384&ud=1355462031&country_code=cn&oc=HUAWEI_KWAI&hotfix_ver=&did_gt=" + time + "&iuid=&net=WIFI&did=ANDROID_03c600e64ee0e3a7&lat=0";String bodyString = "token=988045ae46624450873917df582dfd43-1355462031&user_id=" + userid + "&lang=zh&count=" + size + "&privacy=public&referer=1&browseType=1&sig=" + sig + "&client_key=3c2cd3f3&os=android&__NStokensig=8581c63e468fa7829def9cf79fdebae7fc8f15dd021aa68724928c86872dc554";String sigString = new StringBuilder().append(queryString).append("&").append(bodyString).toString();Map map = new HashMap();map.put(QUERYSTRING, queryString);map.put(BODYSTRING, bodyString);map.put(SIGSTRING, sigString);return map;}private static final String QUERYSTRING = "queryString";private static final String BODYSTRING = "bodyString";private static final String SIGSTRING = "sigString";private static final String FANS_SALT = "382700b563f4";private static final String READURL = "http://www.hack95.com/rest/n/feed/profile2?";
}

 

这个原文链接   http://www.hack95.com/article/detail/36