Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加vip自动订阅指定分类的课程 #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/main/java/online/githuboy/lagou/course/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;

/**
* 启动类
Expand All @@ -35,7 +36,10 @@ public static void main(String[] args) throws IOException, InterruptedException
List<String> allCoursePurchasedRecordForPC = CollectionUtil.isNotEmpty(ConfigUtil.getCourseIds()) ?
ConfigUtil.getCourseIds() :
Course.getAllCoursePurchasedRecordForPC();


// 如果是vip,可以选择自动订阅课程。
Set<String> courseIds = Course.drawCourse();
allCoursePurchasedRecordForPC.addAll(courseIds) ;
log.info("开始下载课程 专栏ID列表:{}", allCoursePurchasedRecordForPC);
//倒叙
//Collections.reverse(allCoursePurchasedRecordForPC);
Expand Down
77 changes: 77 additions & 0 deletions src/main/java/online/githuboy/lagou/course/request/HttpAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
Expand All @@ -31,6 +33,8 @@ public class HttpAPI {
private final static String COURSE_INFO_API = "https://gate.lagou.com/v1/neirong/kaiwu/getCourseLessons?courseId={0}";
private final static String COURSE_COMMENT_LIST_API = "https://gate.lagou.com/v1/neirong/course/comment/getCourseCommentList?courseId={0}&lessonId={1}&pageNum={2}&needCount=true";
private final static String PURCHASED_COURSE_API = "https://gate.lagou.com/v1/neirong/kaiwu/getAllCoursePurchasedRecordForPC?t={0}";
private final static String COURSE_LIST_API = "https://gate.lagou.com/v1/neirong/edu/homepage/getCourseListV2?isPc=true&t={0}";
private final static String COURSE_DRAW_API = "https://gate.lagou.com/v1/neirong/edu/member/drawCourse?courseId={0}";

public static CourseInfo getCourseInfo(String courseId) {
String url = MessageFormat.format(COURSE_INFO_API, courseId);
Expand Down Expand Up @@ -197,4 +201,77 @@ public static PurchasedCourseRecord getPurchasedCourseRecord() {
}
return record;
}

/**
* 列出所有的课程
*
* @return Map<String, List<String>> 课程类别->课程id集合
*/
public static Map<String, List<String>> listCourse() {
String url = MessageFormat.format(COURSE_LIST_API, System.currentTimeMillis());
String body = HttpUtils.get(url, CookieStore.getCookie()).header("x-l-req-header", "{deviceType:1}").execute().body();
JSONObject json = JSON.parseObject(body);
Integer state = json.getInteger("state");
if (state != null && state != 1) {
log.info("获取所有课程失败:json:{}", body);
throw new RuntimeException("获取所有课程失败:" + json.getString("message"));
}

JSONObject result = json.getJSONObject("content");
JSONArray cardListJsonArray = result.getJSONArray("contentCardList");
Map<String, List<String>> map = new HashMap<String, List<String>>();

for (int i = 0; i < cardListJsonArray.size(); i++) {
JSONObject card = cardListJsonArray.getJSONObject(i);
JSONArray courseList = card.getJSONArray("courseList");
for (int j = 0; j < courseList.size(); j++) {
JSONObject course = courseList.getJSONObject(j);

JSONArray classifyIds = course.getJSONArray("classifyIds");
if (classifyIds != null) {

for (int k = 0; k < classifyIds.size(); k++) {
String classify = classifyIds.get(k).toString();
List<String> list = map.get(classify);
if (list == null) {
list = new ArrayList<>();
map.put(classify, list);
}
list.add(course.getString("id"));
}
}
}
}
return map;

}
/**
* vip订阅课程
* @param courseId
*/
public static void drawCourse(String courseId) {

String url = MessageFormat.format(COURSE_DRAW_API, courseId);
log.debug("订阅课程:{},url:{}", courseId, url);
HttpRequest httpRequest = HttpUtils.get(url, CookieStore.getCookie()).header("x-l-req-header", "{deviceType:1}");
String body;
try {
body = httpRequest.execute().body();
} catch (Exception e) {
try {
Thread.sleep(RandomUtil.randomLong(500L, TimeUnit.SECONDS.toMillis(1)));
} catch (InterruptedException interruptedException) {
log.error(interruptedException.getMessage(), interruptedException);
}
log.info("订阅课程 重试1次");
body = httpRequest.execute().body();
}

JSONObject jsonObject = JSON.parseObject(body);
Integer state = jsonObject.getInteger("state");
if (state != null && state != 1) {
log.info("订阅课程失败:json:{}", body);
throw new RuntimeException("订阅课程失败:" + jsonObject.getString("message"));
}
}
}
42 changes: 42 additions & 0 deletions src/main/java/online/githuboy/lagou/course/support/Course.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

import online.githuboy.lagou.course.domain.PurchasedCourseRecord;
import online.githuboy.lagou.course.request.HttpAPI;
import online.githuboy.lagou.course.utils.ConfigUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @author eric
Expand Down Expand Up @@ -36,4 +41,41 @@ public static List<String> getAllCoursePurchasedRecordForPC() {
log.info("一共有{}门课程", courseIdSets.size());
return courseIdSets;
}
/**
* 获取指定类别的课程id
* @param classifyIds 课程类别集合
* @return
*/
public static Set<String> getAllCourseVipForPC(List<String> classifyIds) {
Set<String> set = new HashSet<String>();
Map<String, List<String>> courses = HttpAPI.listCourse();

if (classifyIds.size() == 1 && classifyIds.get(0).equals("0")) {
for (List<String> list : courses.values()) {
set.addAll(list);
}
} else {
for (String classify : classifyIds) {
set.addAll(courses.get(classify));
}
}

return set;
}
/**
* vip自动订阅指定类别的课程
* @return 成功订阅的课程id
*/
public static Set<String> drawCourse() {

List<String> allCoursePurchasedRecordForPC = Course.getAllCoursePurchasedRecordForPC();
// 所有指定订阅的课程
List<String> classifyIds = ConfigUtil.getClassifyIds();
Set<String> courseIds = Course.getAllCourseVipForPC(classifyIds);
courseIds.removeAll(allCoursePurchasedRecordForPC) ;
for (String courseId : courseIds) {
HttpAPI.drawCourse(courseId);
}
return courseIds ;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ public static List<String> getCourseIds() {
Set<String> set = ArrayUtils.isEmpty(split) ? new HashSet<>() : new HashSet<>(Arrays.asList(split));
return set.stream().map(String::trim).collect(Collectors.toList());
}
public static List<String> getClassifyIds() {
String courseIds = readValue("classifyIds");
String[] split = StringUtils.split(courseIds, ",");
Set<String> set = ArrayUtils.isEmpty(split) ? new HashSet<>() : new HashSet<>(Arrays.asList(split));
return set.stream().map(String::trim).collect(Collectors.toList());
}

public static void main(String[] args) {
System.out.println(ConfigUtil.readValue("mp4_dir"));
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/config/config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ mp4_xunlianying_dir=~/Downloads/lagou-xunlianying-mp4
courseIds=
# 要排除的课程列表,用逗号分割 格式例如:6,16,356 716_Python入门与实战-至尊 这个视频有毒
remove_course=716
#vip账号订阅指定类别的课程,用逗号分割,如果不指定,不会进行自动订阅,格式例如:1,3 ;如果是单独的0表示订阅所有
#类别说明:1 后端&架构 2 前端&移动 3 数据分析 4 产品&设计 5 市场&运营 6 大数据&AI 7 测试&运维 8 职场&管理 9 学生&入门
classifyIds=
# 视频下载超时(分钟)默认10分钟, 如果下载的文件可能较大,超过10分钟,那么可以把时间调长
mp4_download_timeout=10