获取今日头条西瓜视频下载地址

获取今日头条西瓜视频下载地址

通过该方式可以通过今日头条和西瓜视频的视频详情页面获取,视频的下载地址和播放地址(该地址是动态生成的)。

实现方式

通过该网站可以实现上述功能,但是必须访问该网页,还需要手动输入地址。具体如下:
这里写图片描述
通过分析,其实调用的是http://service.iiilab.com/video/toutiao 接口。我们通过network查看请求head:
这里写图片描述
首先请求类型是POST 请求参数包括三个:
- link,我们输入的视频详情url
- r ,随机数
- s, 随机数
我们使用postman模拟请求试试,并不可以直接请求,说明另外两个参数还是必须的
这里写图片描述

分析请求过程

上面的放个行不通,只能通过分析代码找出rs 参数的生成规则。首先找到调用的js文件。通过Chrome浏览器的Sources发现静态资源,具体如下:
这里写图片描述
我们需要再次确定解析视频的提交方法就在该js中,具体如下:
这里写图片描述
没有输入视频地址,前端有提示请先将视频链接粘贴到上面的输入框 错误信息。通过该关键字在js文件中查找。在该js文件中有一个submit方法,并且上面的错误提示信息也在该方法中
这里写图片描述
这个方法主要是校验,核心方法在parseVideo
这里写图片描述
该方法也暴露了请求参数的生成方法,r参数的在这里已经可以看出来了。但是s参数的还需要通过generateStr 方法查看,具体如下:
这里写图片描述
至此我们至少知道参数r和s的生成策略。

通过Java代码模拟请求

通过上面的分析,我们现在的关键点是需要生成r和s参数,r参数还好说,但是s参数要转换成Java代码太麻烦了。
但是Java可以直接调用js方法,具体实现如下:

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

public class XiGuaTest {

    @Test
    public void test1() throws Exception {

        String uriAPI = "http://service.iiilab.com/video/toutiao";// Post方式没有参数在这里
        HttpPost httpRequst = new HttpPost(uriAPI);// 创建HttpPost对象

        String link = "http://www.toutiao.com/a6456372102038553101/";
        Map<String, String> map = excuteJs(link);

        httpRequst.setHeader("Origin", "http://toutiao.iiilab.com");        

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("link", link));
        params.add(new BasicNameValuePair("r", map.get("r")));
        params.add(new BasicNameValuePair("s", map.get("s")));

        httpRequst.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
        HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequst);
        String result = "";
        if (httpResponse.getStatusLine().getStatusCode() == 200) {
            HttpEntity httpEntity = httpResponse.getEntity();
            result = EntityUtils.toString(httpEntity);// 取出应答字符串
        }
        System.out.println(result);
    }

    private Map<String, String> excuteJs(String link) throws ScriptException,
            FileNotFoundException, NoSuchMethodException {
        ScriptEngineManager engineManager = new ScriptEngineManager();
        ScriptEngine engine = engineManager.getEngineByName("JavaScript"); // 得到脚本引擎
        engine.eval(new FileReader(
                "E:\\application\\workspace\\test\\test\\src\\test\\test.js"));
        Invocable inv = (Invocable) engine;
        Object test2 = inv.invokeFunction("test2");
        String param = link + "@" + test2.toString();
        Object a = inv.invokeFunction("test", param);
        Map<String, String> hashMap = new HashMap<String, String>();
        hashMap.put("r", test2.toString());
        hashMap.put("s", a.toString());
        return hashMap;
    }

}

js代码如下:

      function test(a) {
            var c = function() {
                for (var d = 0,
                f = new Array(256), g = 0; 256 != g; ++g) {
                    d = g,
                    d = 1 & d ? -306674912 ^ d >>> 1 : d >>> 1,
                    d = 1 & d ? -306674912 ^ d >>> 1 : d >>> 1,
                    d = 1 & d ? -306674912 ^ d >>> 1 : d >>> 1,
                    d = 1 & d ? -306674912 ^ d >>> 1 : d >>> 1,
                    d = 1 & d ? -306674912 ^ d >>> 1 : d >>> 1,
                    d = 1 & d ? -306674912 ^ d >>> 1 : d >>> 1,
                    d = 1 & d ? -306674912 ^ d >>> 1 : d >>> 1,
                    d = 1 & d ? -306674912 ^ d >>> 1 : d >>> 1,
                    f[g] = d
                }
                return "undefined" != typeof Int32Array ? new Int32Array(f) : f
            } (),
            b = function(g) {
                for (var j, k, h = -1,
                f = 0,
                d = g.length; f < d;) {
                    j = g.charCodeAt(f++),
                    j < 128 ? h = h >>> 8 ^ c[255 & (h ^ j)] : j < 2048 ? (h = h >>> 8 ^ c[255 & (h ^ (192 | j >> 6 & 31))], h = h >>> 8 ^ c[255 & (h ^ (128 | 63 & j))]) : j >= 55296 && j < 57344 ? (j = (1023 & j) + 64, k = 1023 & g.charCodeAt(f++), h = h >>> 8 ^ c[255 & (h ^ (240 | j >> 8 & 7))], h = h >>> 8 ^ c[255 & (h ^ (128 | j >> 2 & 63))], h = h >>> 8 ^ c[255 & (h ^ (128 | k >> 6 & 15 | (3 & j) << 4))], h = h >>> 8 ^ c[255 & (h ^ (128 | 63 & k))]) : (h = h >>> 8 ^ c[255 & (h ^ (224 | j >> 12 & 15))], h = h >>> 8 ^ c[255 & (h ^ (128 | j >> 6 & 63))], h = h >>> 8 ^ c[255 & (h ^ (128 | 63 & j))])
                }
                return h ^ -1
            };
            var f = b(a) >>> 0;
            return f.toString(10);
        }


      function test2(){
          return Math.random().toString(10).substring(2);
      }

执行结果如下:

{
    "retCode": 200,
    "retDesc": "成功",
    "data": {
        "text": "农村二货小伙玉米地偶遇媳妇,这个都要把我笑岔气了",
        "video": {
            "link": [
                {
                    "url": "http://v3-tt.ixigua.com/6fa8e337a4bb0e291df12bfb467bb96c/59a4d89d/video/m/220490affee2214417cbb3ddbcd2037d9c3114f56700004805cf0a468f/#mp4",
                    "buttonText": "极速(360p)视频地址1",
                    "type": "极速(360p)"
                },
                {
                    "url": "http://v1-tt.ixiguavideo.com/c31e23f19a1553cde0359a08cce9701b/59a4d89d/video/m/220490affee2214417cbb3ddbcd2037d9c3114f56700004805cf0a468f/#mp4",
                    "buttonText": "极速(360p)视频地址2",
                    "type": null
                },
                {
                    "url": "http://v3-tt.ixigua.com/ced8474825e27b0585c7ed5c535101a5/59a4d89d/video/m/22020a871736eaf4e1695f2efca5d050e5b114f5320000a3774f5d4b3b/#mp4",
                    "buttonText": "高清(480p)视频地址1",
                    "type": "高清(480p)"
                },
                {
                    "url": "http://v1-tt.ixiguavideo.com/ab4820fc709fe1b45f224406d6249cda/59a4d89d/video/m/22020a871736eaf4e1695f2efca5d050e5b114f5320000a3774f5d4b3b/#mp4",
                    "buttonText": "高清(480p)视频地址2",
                    "type": null
                },
                {
                    "url": "http://v3-tt.ixigua.com/5db838d2555dd769f97a5d30c2e1b4f0/59a4d89d/video/m/22059ee25d2362645b7ab11544897329132114f6220000aad5618c70f3/#mp4",
                    "buttonText": "超清(720p)视频地址1",
                    "type": "超清(720p)"
                },
                {
                    "url": "http://v1-tt.ixiguavideo.com/c89c2a44bed1d74c1ea530f691645d6a/59a4d89d/video/m/22059ee25d2362645b7ab11544897329132114f6220000aad5618c70f3/#mp4",
                    "buttonText": "超清(720p)视频地址2",
                    "type": null
                }
            ],
            "download": [
                {
                    "url": "http://v3-tt.ixigua.com/6fa8e337a4bb0e291df12bfb467bb96c/59a4d89d/video/m/220490affee2214417cbb3ddbcd2037d9c3114f56700004805cf0a468f/#mp4",
                    "buttonText": "极速(360p)视频地址1",
                    "type": "极速(360p)"
                },
                {
                    "url": "http://v3-tt.ixigua.com/ced8474825e27b0585c7ed5c535101a5/59a4d89d/video/m/22020a871736eaf4e1695f2efca5d050e5b114f5320000a3774f5d4b3b/#mp4",
                    "buttonText": "高清(480p)视频地址1",
                    "type": "高清(480p)"
                },
                {
                    "url": "http://v3-tt.ixigua.com/5db838d2555dd769f97a5d30c2e1b4f0/59a4d89d/video/m/22059ee25d2362645b7ab11544897329132114f6220000aad5618c70f3/#mp4",
                    "buttonText": "超清(720p)视频地址1",
                    "type": "超清(720p)"
                }
            ]
        }
    },
    "succ": true
}

播放如下:
这里写图片描述

总结

至此,我们就可以通过视频详情的url解析到视频的播放地址。通过一步步分析http请求过程,达到解析的效果

猜你喜欢

转载自blog.csdn.net/qq455276333/article/details/77675537
今日推荐