Greasy Fork

wsxy_getData

网上学院函数库:登录后获取解析数据

目前为 2020-02-02 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greasyfork.icu/scripts/395748/769523/wsxy_getData.js

// ==UserScript==
// @name          wsxy_getData
// @namespace     Vionlentmonkey
// @version       0.2
// @description   网上学院函数库:登录后获取解析数据
// @require       https://greasyfork.org/scripts/395959-binary2text/code/binary2Text.js
// @require       https://greasyfork.org/scripts/395958-htmltoelements/code/htmlToElements.js
// @grant         GM_xmlhttpRequest
// ==/UserScript==

// 登录后可获取数据
// 用户学习数据:http://218.94.1.175:8087/sfxzwsxy/jypxks/ajax/index_ajax.jsp?reqType=4
const getUserData = async () => {
  let response = await fetch(`${location.origin}/sfxzwsxy/jypxks/ajax/index_ajax.jsp?reqType=4`, {
    method: 'POST'
  });
  let jsonData = await response.json();
  let jsonDataObj = jsonData[0];
  return jsonDataObj;
  /*
    let stime = jsonDataObj.stime; //学年开始时间
    let etime = jsonDataObj.etime; //学年结束时间
    let total_hour = jsonDataObj.total_hour; //规定需达到的总学时
    let required_hour = jsonDataObj.required_hour; //规定需达到的必修学时
    let required_credit = jsonDataObj.required_credit; //规定需达到的总学分
    let user_total_hour = jsonDataObj.user_total_hour || 0; //用户已获得的总学时
    let user_required_hour = jsonDataObj.user_required_hour || 0; //用户已获得的必修学时
    let user_required_credit = jsonDataObj.user_required_credit || 0; //用户已获得的总学分
    let user_integral = jsonDataObj.user_integral || 0; //用户已获得的的总积分
    let syn_total_hour = jsonDataObj.syn_total_hour || 0; //从省委组织部同步到的总学时
    let syn_required_hour = jsonDataObj.syn_required_hour || 0; //从省委组织部同步到的的必修学时
    let show_total_hour = parseFloat(user_total_hour) + parseFloat(syn_total_hour);
    let show_total_required_hour = parseFloat(user_required_hour) + parseFloat(syn_required_hour);
    */
};

/* 未完成学习课程数据:http://218.94.1.175:8087/sfxzwsxy/jypxks/modules/homepage/ajax/homepage_ajax.jsp?ajaxType=10
  获取自 http://218.94.1.175:8087/sfxzwsxy/jypxks/modules/homepage/js/homepage.js
  初始化培训课程数据方法 function initCourseData()
  内含3个 Array:
  exam_courses: 已听课待考试的必修课
  required_courses: 待报名听课的必修课
  selected_courses:选修课
  各 Array 又以对象形式存储各课程,如
  {"course_pk":2466,"course_name":"行政机关不履行法定职责(投诉举报)类行政复议案件审查要点","topic_name":"司法行政专业课程","apply_pk":3033781,"is_finish":1,"course_type":1,"course_rate":90,"use_flag":1}
  */
const getCourseData = async () => {
  let response = await fetch(
    `${location.origin}/sfxzwsxy/jypxks/modules/homepage/ajax/homepage_ajax.jsp?ajaxType=10`,
    {
      method: 'POST',
      body: 'blob'
    }
  );
  // https://developer.mozilla.org/zh-CN/docs/Web/API/Blob
  let blob = await response.blob();
  let utf8Text = await binary2Text(blob);
  let jsonData = JSON.parse(utf8Text);
  let jsonDataObj = jsonData[0];
  console.log('已成功获取课程数据');
  return jsonDataObj;
  /*
    let exam_courses = jsonDataObj.exam_courses;
    console.log('exam_courses:' + exam_courses);
    let required_courses = jsonDataObj.required_courses;
    console.log(required_courses);
    let selected_courses = jsonDataObj.selected_courses;
    console.log(selected_courses);
    */
};

const csPk2applyPk = async csPk => {
  const csDataObj = await getCourseData();
  let exam_courses = csDataObj.exam_courses;
  let required_courses = csDataObj.required_courses;
  let applyPk = '';
  for (let e of exam_courses) {
    if (e.course_pk === Number(csPk)) {
      applyPk = String(e.apply_pk);
      return applyPk;
    }
  }
  for (let r of required_courses) {
    if (r.course_pk === Number(csPk)) {
      applyPk = String(r.apply_pk);
      return applyPk;
    }
  }
};

// 课程学分学时等信息
const getCourseInfo = async coursePk => {
  let viewURL = `${location.origin}/sfxzwsxy//jypxks/modules/train/course/course_view.jsp?coursePk=${coursePk}`;
  let response = await fetch(viewURL, {
    method: 'POST',
    body: 'blob'
  });
  let blob = await response.blob();
  let csInfoHtml = await binary2Text(blob);
  let elements = htmlToElements(csInfoHtml);
  let courseCredit = Number(elements.querySelectorAll('#subjectInfo td')[7].textContent.trim());
  let courseTime = Number(elements.querySelectorAll('#extendInfo td')[3].textContent.trim());
  let courseInfo = {
    courseCredit: courseCredit,
    courseTime: courseTime
  };
  return courseInfo;
};

// 获取课程对应的 iframe 资源地址,为获取播放器类型做准备。
const getFrameURL = async applyPk => {
  let trainURL =
    location.origin +
    '/sfxzwsxy/jypxks/modules/train/ware/course_ware_view.jsp?applyPk=' +
    applyPk +
    '&courseType=1';
  let response = await fetch(trainURL, {
    method: 'POST',
    body: 'blob'
  });
  let blob = await response.blob();
  let csInfoHtml = await binary2Text(blob);
  let elements = htmlToElements(csInfoHtml);
  let warePath = elements.getElementById('warePath').value;
  let iframeURL = 'http://218.94.1.181:5088/unzipapp/project/ware' + warePath;
  //console.log('iframeURL: ' + iframeURL);
  return iframeURL;
};

// 部分少见的新型播放器会弹出 confirm,避开为宜。
const skipNewVideoPlayerType = async (applyPk, callback) => {
  // 未报名课程 applyPk === ''
  if (applyPk) {
    let iframeVideoPlayerType = {
      method: 'POST',
      // Fetch 不能获取跨域数据
      url: await getFrameURL(applyPk),
      onload: response => {
        let csInfoHtml = response.responseText;
        let elements = htmlToElements(csInfoHtml);
        let isNewPlayer = elements.getElementById('video');
        // return 疑似永远为假,暂以回调处理
        callback(applyPk, isNewPlayer);
      }
    };
    GM_xmlhttpRequest(iframeVideoPlayerType);
  }
};

const getSubjectData = async subjectPk => {
  let subjectURL = `${location.origin}/sfxzwsxy//jypxks/modules/train/course/subject_view.jsp?subjectPk=${subjectPk}`;
  let response = await fetch(subjectURL, {
    method: 'POST',
    body: 'blob'
  });
  let blob = await response.blob();
  let subjectHtml = await binary2Text(blob);
  let elements = htmlToElements(subjectHtml);
  // https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map
  let subjectDataMap = new Map();
  // 题目类型:判断题/单选题/多选题
  let questionType = elements
    .querySelectorAll('table')[0]
    .querySelectorAll('tr')[0]
    .querySelectorAll('td')[1]
    .textContent.trim();
  subjectDataMap.set('questionType', questionType);
  // 题目内容:string
  let questionContent = elements
    .querySelectorAll('table')[0]
    .querySelectorAll('tr')[1]
    .querySelectorAll('td')[1]
    .textContent.trim();
  // 判断题答案,选择题此处为空值
  let judgementAnswer = elements
    .querySelectorAll('table')[0]
    .querySelectorAll('tr')[2]
    .querySelectorAll('td')[1]
    .textContent.trim();
  subjectDataMap.set('questionContent', questionContent);

  if (questionType === '判断题') {
    subjectDataMap.set('judgementAnswer', judgementAnswer);
  } else {
    // 选择题答案表格第一行为标题:序号 	 选项内容 	 类型 	 是否为标准答案
    // 此表格中答案选项与试题选项顺序打乱,序号没有意义,类型已获取也没有意义
    let options = elements.querySelectorAll('table')[1].querySelectorAll('tr');
    for (let option of options) {
      let optionContent = option.querySelectorAll('td')[1].textContent.trim();
      let optionAnswer = option.querySelectorAll('td')[3].textContent.trim();
      if (optionContent !== '选项内容' && optionAnswer !== '是否为标准答案') {
        subjectDataMap.set(optionContent, optionAnswer);
      }
    }
  }
  //console.log(subjectDataMap.get('questionContent'));
  //console.log(subjectDataMap);
  return subjectDataMap;
};