远程文件下载/小电影下载

场景:某些网站只提供了在线预览,或你充值了1天会员、但想把所有电影都看完 -> OK,咱们下载下来慢慢看

分析:目标网站的电影是分块加载的,一次加载3-4个文件,播放完毕再发起请求获取后面的资源,举例如下:

http://IP:PORT/1jxxl/JXXL846JDG/JXXL846JDG0.ts

http://IP:PORT/1jxxl/JXXL846JDG/JXXL846JDG1.ts

.......

http://IP:PORT/1jxxl/JXXL846JDG/JXXL846JDG218.ts

http://IP:PORT/1jxxl/JXXL846JDG/JXXL846JDG219.ts

这里可以看到,电影的资源加载是有规律可循的,都是后面的数字累加,对此我只能呵呵呵了...

可以理解为闲得无聊吧,写了个下载电影的程序

基本思路:取得电影分块文件其中一个下载链接,存入text文件中,根据后面资源文件有迹可循的加载规律,自动切换下载地址,并将目标文件下载到本地

亲测功能正常...直接上代码了:

import java.io.*;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 * 小电影下载
 * @date 2019/9/15 16:27
 * @author wei.heng
 */
public class FilmDownload {

    public static void main(String[] args) {
        // 下载到哪个目录下
        final String root = "G:/haha";
        String path = "C:/Users/Thinkpad/Desktop/test.txt";
        String prefixAlia = "American_";
        List<String> pathList = getFilePath(path);
        for (String p : pathList) {
            System.out.println(p);
            ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 8, 60L
                        , TimeUnit.SECONDS, new LinkedBlockingQueue<>(50), new NameTreadFactory());
            executor.execute(() -> downloadTs(prefixAlia, root, p));
        }
    }

    static class NameTreadFactory implements ThreadFactory {

        private final AtomicInteger mThreadNum = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement());
            System.out.println(t.getName() + " has been created");
            return t;
        }
    }

    private static List<String> getFilePath(String filePath){
        List<String> list = null;
        try {
            list = Files.readAllLines(Paths.get(filePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 按文件名建立目录,下载远程文件(网上这些个电影全是分块加载的,后续下载完还要做合并)
     * @param dirAlias 目录别名(下载的数据太多了,我按电影类型分类吧)
     * @param targetPath 输出的目标文件目录
     * @param path 远程文件地址
     * @date 2019/9/15 15:06
     * @author wei.heng
     */
    private static void downloadTs(String dirAlias, String targetPath, String path) {
        final String fileSeperator = "/";
        int speratorIndex = path.lastIndexOf(fileSeperator);
        // 获取远程文件名
        String filename = path.substring(speratorIndex + 1);
        // 远程文件目录
        String remoteDir = path.substring(0, speratorIndex);
        // 获取远程文件目录名称
        String dir = remoteDir.substring(remoteDir.lastIndexOf(fileSeperator) + 1);
        // 文件太多,前缀加个别名吧
        dir = dirAlias + dir;
        // 分块文件名称
        String dynamicFileName = filename.substring(0,filename.length() - 4);
        String suffix = ".ts";

        BufferedInputStream bis = null;
        HttpURLConnection conn = null;
        // 这里随意给了个值,保证文件能够全部读取完就成
        int filePartSize = 3000;
        for (int partIndex = 0; partIndex < filePartSize; partIndex++) {
            try {
                System.out.println("partIndexIndex:" + partIndex);
                // 检查文件是否已存在,避免浪费资源,重复请求
                // 文件名 = 本地目录(入参) + 文件名命名的目录(程序常见) + 分块文件名称(dynamicFileName + partIndex + suffix)
                String outputFile = targetPath + fileSeperator + dir + fileSeperator + dynamicFileName + partIndex + suffix;
                File f = new File(outputFile);
                if(f.exists()){
                    System.out.println("文件已存在:" + f);
                    continue;
                }
                String targetUrl = remoteDir + fileSeperator + dynamicFileName + partIndex + suffix;
                URL url = new URL(targetUrl);
                conn = (HttpURLConnection)url.openConnection();
                // 设置通用的请求属性
                setRequestProperties(conn);
                // 建立连接
                conn.connect();
                // 获取响应码
                int httpResult = conn.getResponseCode();
                System.out.println("httpResult::"+httpResult);
                if(httpResult==HttpURLConnection.HTTP_OK){
                    // 创建文件目录
                    File direction = new File(targetPath + fileSeperator + dir);
                    if(!direction.exists()){
                        if(!direction.mkdirs()){
                            throw new RuntimeException("创建文件目录失败");
                        }
                    }
                    Files.copy(conn.getInputStream(), Paths.get(outputFile));
                    System.out.println("real length::"+conn.getContentLength());
                } else if(httpResult==HttpURLConnection.HTTP_NOT_FOUND){
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                releaseSource(bis, conn);
            }
        }

    }

    private static void releaseSource(BufferedInputStream bis, HttpURLConnection conn) {
        if(bis != null){
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(conn != null){
            conn.disconnect();
        }
    }

    private static void setRequestProperties(HttpURLConnection conn) throws ProtocolException {
        // 使用 URL 连接进行输出
        conn.setDoOutput(true);
        // 使用 URL 连接进行输入
        conn.setDoInput(true);
        // 忽略缓存
        conn.setUseCaches(false);
        conn.setRequestMethod("GET");
        conn.setRequestProperty("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
        conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
        conn.setRequestProperty("connection", "Keep-Alive");
        conn.setRequestProperty("user-agent",
            "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0");
        conn.setRequestProperty("Host", "video7.achxc.com:8083");
    }

}

到这里基本就OK了...

是不是觉得少了点什么??

1、爬虫什么的,Java也可以写,请求网站地址页面解析获取对应title或src就好了

2、后面我会再贴一篇文件合并的文章(将下载后的电影分块文件合并成一个)...其实就是分块文件合并为一个...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值