热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java代码实现下载慕课网视频

首先,必须得说,慕课网是一个非常棒的网站,上面很多很好的视频教程,在此表示感谢!马上过年回家,因为家里没网,所以想把慕课上的视频下载下来在家里看,于是乎

首先,必须得说,慕课网是一个非常棒的网站,上面很多很好的视频教程,在此表示感谢!

马上过年回家,因为家里没网,所以想把慕课上的视频下载下来在家里看,于是乎在网上找了半天下载工具,有的工具做的牛逼,直接给你把慕课网上全部的视频下载下来,我想说做这个软件的哥们真是缺心眼,谁疯了去下载那么多视频?于是找了一个别人写好的项目,里面有一个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,大功告成!




推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了作者在开发过程中遇到的问题,即播放框架内容安全策略设置不起作用的错误。作者通过使用编译时依赖注入的方式解决了这个问题,并分享了解决方案。文章详细描述了问题的出现情况、错误输出内容以及解决方案的具体步骤。如果你也遇到了类似的问题,本文可能对你有一定的参考价值。 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
author-avatar
mobiledu2502930997
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有