作者:mobiledu2502930997 | 来源:互联网 | 2023-05-19 06:27
首先,必须得说,慕课网是一个非常棒的网站,上面很多很好的视频教程,在此表示感谢!
马上过年回家,因为家里没网,所以想把慕课上的视频下载下来在家里看,于是乎在网上找了半天下载工具,有的工具做的牛逼,直接给你把慕课网上全部的视频下载下来,我想说做这个软件的哥们真是缺心眼,谁疯了去下载那么多视频?于是找了一个别人写好的项目,里面有一个imoocDownloader.jar文件,和一个run.bat批处理文件,意思是要先安装好jar包,然后执行run.bat批处理文件,然后根据提示输入要下载的视频的编号,就可以开始下载了,于是乎我激动的不行,我根据提示输入要下载的视频的编号后,直接给我抛一个ArrayOutOfIndexException,我也是醉了。这东西能用吗?好在有imoocDownloader.jar包,那就好弄了。
我用了jd-gui工具将这个jar反编译拿到了java源代码,有了源代码,那就简单了,但是源代码直接运行的时候各种错误,于是我在idea下新建了一个工工程,然后把他的代码移植到了我的项目中,并通过maven管理依赖的jar包,依赖的jar有jsoup和json。项目移植完毕后,debug发现了抛出上面异常的原因,那家伙,那代码懂编程的都知道写到不对,于是对代码做了修改,并去掉了源代码中对于非视频类教程的下载,即只下载了视频类的课程。
但是还是得感谢这个兄台。
慕课网视频url格式说明
http://www.imooc.com/learn/699 这个url,你会发现,这是一个完整的关于Lavarel-表单篇的教程地址
我下载我当然希望一次把这个下面的所有章节的视频全部下载了。所以main函数运行后,根据提示你可以输入699启动下载
我下载下来的原始代码里面,还可以让你对期望下载的视频类型,比如高清,超清,标清进行输入选择,我索性去掉了,我只看超清,所以给了一个默认值
好吧,本想直接把我的项目传上来,发现太大了,还是给大家写下几个主要的类吧
1. 首先是main函数类
package com.immoc.controller;
import com.immoc.service.DownloadFile;
import com.immoc.service.GetInput;
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 java.io.File;
public class ImoocMain {
static int curruntCount;
static int curruntGlobalCount;
public static void main(String[] args) throws Exception {
while (true) {
curruntCount = 0;
curruntGlobalCount = 0;
int classNo = GetInput.getInputClassNo();
Document doc = Jsoup.connect("http://www.imooc.com/learn/" + classNo).get();
String title = doc.getElementsByTag("h2").html();
Elements videos = doc.select(".video a");
if ((title.equals("")) && (videos.size() == 0)) {
System.out.println("抱歉,没有该课程!\n");
} else {
int count = 0;
for (Element video : videos) {
String[] videOnos= video.attr("href").split("/");
if (videoNos.length >= 2 && videoNos[1].equals("video")) {
count++;
}
}
System.out.print("\n要下载的课程标题为【" + title + "】,");
System.out.println("本次要下载的视频课程有 " + count + " 节\n");
// int videoDef = GetInput.getInputVideoDef();
int videoDef = 0; //这里默认下载超清的
String savePath = "./download/" + title + "/";
File file = new File(savePath);
file.mkdirs();
System.out.println("\n准备开始下载,请耐心等待…\n");
for (Element video : videos) {
String[] videOnos= video.attr("href").split("/");
//只下载视频
if (videoNos.length > 1 && videoNos[1].equals("video")) {
video.select("button").remove();
String videOname= video.text().trim();
videOname= videoName.substring(0, videoName.length() - 7).trim();
String videOno= videoNos[2];
Document jsOnDoc= Jsoup.connect(
"http://www.imooc.com/course/ajaxmediainfo/?mid=" +
videoNo + "&mode=flash").get();
String jsOnData= jsonDoc.text();
JSONObject jsOnObject= new JSONObject(jsonData);
JSONArray mpath = jsonObject.optJSONObject("data")
.optJSONObject("result").optJSONArray("mpath");
String downloadPath = mpath.getString(videoDef).trim();
DownloadFile.downLoadFromUrl(downloadPath, videoName + ".mp4",
savePath);
curruntCount += 1;
System.out.println("【" + curruntCount + "】:\t" + videoName +
" \t下载成功!");
}
}
System.out.println("\n恭喜!【" + title + "】课程的所有视频已经下载完成!!!下载的文件在该程序所在目录下的download文件夹中。\n-------------------------------------------------------\n");
}
}
}
}
在main函数类中调用了几个其他的类
2. GetInput类,主要用于读取用户的输入
package com.immoc.service;
public class GetInput {
public static int getInputClassNo() {
int classNo = 0;
java.util.Scanner scanner = new java.util.Scanner(System.in);
for (;;)
{
System.out.println("请输入需要下载的课程编号(如:http://www.imooc.com/learn/601,则输入601):");
try {
classNo = scanner.nextInt();
break;
} catch (Exception e) {
System.out.println("课程编号填写错误,只能输入数字!\n");
scanner.nextLine();
}
}
return classNo;
}
public static int getInputVideoDef()
{
int videoDef = 0;
java.util.Scanner scanner = new java.util.Scanner(System.in);
for (;;) {
System.out.println("请输入要下载的清晰度,【0】超清,【1】高清,【2】普清:");
try {
videoDef = scanner.nextInt();
if ((videoDef <= 2) && (videoDef >= 0)) {
break;
}
throw new Exception();
}
catch (Exception e) {
System.out.println("只能输入【0】【1】【2】中的一个数!\n");
scanner.nextLine();
}
}
return videoDef;
}
}
3. DownloadFile类,主要负责下载
package com.immoc.service;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownloadFile
{
public static void downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException
{
URL url = new URL(urlStr);
HttpURLConnection cOnn= (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(3000);
conn.setRequestProperty("User-Agent",
"Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
InputStream inputStream = conn.getInputStream();
byte[] getData = readInputStream(inputStream);
java.io.File saveDir = new java.io.File(savePath);
if (!saveDir.exists()) {
saveDir.mkdir();
}
java.io.File file = new java.io.File(saveDir + java.io.File.separator + fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(getData);
if (fos != null) {
fos.close();
}
if (inputStream != null) {
inputStream.close();
}
}
public static byte[] readInputStream(InputStream inputStream)
throws IOException
{
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
return bos.toByteArray();
}
}
此外,你的项目里面必须引入如下两个依赖
org.jsoup
jsoup
1.7.2
org.json
json
20160212
Ok,大功告成!