|
@@ -3,13 +3,13 @@ package student
|
|
import (
|
|
import (
|
|
"bufio"
|
|
"bufio"
|
|
"bytes"
|
|
"bytes"
|
|
|
|
+ "encoding/base64"
|
|
"encoding/json"
|
|
"encoding/json"
|
|
"errors"
|
|
"errors"
|
|
"fmt"
|
|
"fmt"
|
|
"io"
|
|
"io"
|
|
"io/ioutil"
|
|
"io/ioutil"
|
|
"math/rand"
|
|
"math/rand"
|
|
- "mime/multipart"
|
|
|
|
"net/http"
|
|
"net/http"
|
|
"os"
|
|
"os"
|
|
"ouchn/config"
|
|
"ouchn/config"
|
|
@@ -110,7 +110,77 @@ func Check415Error(wd selenium.WebDriver) error {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
-func codeGet(data []byte, account string, token string) (bool, string) {
|
|
|
|
|
|
+func commonVerify(image string) string {
|
|
|
|
+ //# 数英汉字类型
|
|
|
|
+ //# 通用数英1-4位 10110
|
|
|
|
+ //# 通用数英5-8位 10111
|
|
|
|
+ //# 通用数英9~11位 10112
|
|
|
|
+ //# 通用数英12位及以上 10113
|
|
|
|
+ //# 通用数英1~6位plus 10103
|
|
|
|
+ //# 定制-数英5位~qcs 9001
|
|
|
|
+ //# 定制-纯数字4位 193
|
|
|
|
+ //# 中文类型
|
|
|
|
+ //# 通用中文字符1~2位 10114
|
|
|
|
+ //# 通用中文字符 3~5位 10115
|
|
|
|
+ //# 通用中文字符6~8位 10116
|
|
|
|
+ //# 通用中文字符9位及以上 10117
|
|
|
|
+ //# 定制-XX西游苦行中文字符 10107
|
|
|
|
+ //# 计算类型
|
|
|
|
+ //# 通用数字计算题 50100
|
|
|
|
+ //# 通用中文计算题 50101
|
|
|
|
+ //# 定制-计算题 cni 452
|
|
|
|
+ config := map[string]interface{}{}
|
|
|
|
+ config["image"] = image
|
|
|
|
+ config["type"] = "10110"
|
|
|
|
+ config["token"] = "2EEYFMjDVpMTky-Z_BCgt_I14g4qq_D63S3NsQesfMc"
|
|
|
|
+ configData, _ := json.Marshal(config)
|
|
|
|
+ body := bytes.NewBuffer([]byte(configData))
|
|
|
|
+ resp, err := http.Post("http://api.jfbym.com/api/YmServer/customApi", "application/json;charset=utf-8", body)
|
|
|
|
+ defer resp.Body.Close()
|
|
|
|
+ if err != nil {
|
|
|
|
+ return ""
|
|
|
|
+ }
|
|
|
|
+ data, _ := ioutil.ReadAll(resp.Body)
|
|
|
|
+ fmt.Println(string(data), err)
|
|
|
|
+ return string(data)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func codeGetNew(data []byte, account string, token string) string {
|
|
|
|
+ name := account + ".png"
|
|
|
|
+ ioutil.WriteFile(name, data, 0666)
|
|
|
|
+ defer func() {
|
|
|
|
+ os.Remove(name)
|
|
|
|
+ }()
|
|
|
|
+ /* bodyBuffer := &bytes.Buffer{}
|
|
|
|
+ bodyWriter := multipart.NewWriter(bodyBuffer)
|
|
|
|
+ bodyWriter.WriteField("token", token)
|
|
|
|
+ bodyWriter.WriteField("type", "local")
|
|
|
|
+ fileWriter, _ := bodyWriter.CreateFormFile("file", name)
|
|
|
|
+ */
|
|
|
|
+ file, _ := os.Open(name)
|
|
|
|
+ defer file.Close()
|
|
|
|
+
|
|
|
|
+ fileInfo, _ := file.Stat()
|
|
|
|
+ imageSize := fileInfo.Size()
|
|
|
|
+ imageData := make([]byte, imageSize)
|
|
|
|
+ _, err := file.Read(imageData)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println("保存文件失败")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ base64Data := base64.StdEncoding.EncodeToString(imageData)
|
|
|
|
+ respData := commonVerify(base64Data)
|
|
|
|
+ fmt.Println("验证码识别结果:", respData)
|
|
|
|
+
|
|
|
|
+ code := gjson.Get(respData, "code").Int()
|
|
|
|
+ if code != 10000 {
|
|
|
|
+ fmt.Println("验证码识别失败:", gjson.Get(respData, "msg").String())
|
|
|
|
+ return ""
|
|
|
|
+ }
|
|
|
|
+ return gjson.Get(respData, "data.data").String()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*func codeGet(data []byte, account string, token string) (bool, string) {
|
|
name := account + ".png"
|
|
name := account + ".png"
|
|
ioutil.WriteFile(name, data, 0666)
|
|
ioutil.WriteFile(name, data, 0666)
|
|
defer func() {
|
|
defer func() {
|
|
@@ -136,7 +206,7 @@ func codeGet(data []byte, account string, token string) (bool, string) {
|
|
|
|
|
|
resp_body, _ := ioutil.ReadAll(resp.Body)
|
|
resp_body, _ := ioutil.ReadAll(resp.Body)
|
|
defer resp.Body.Close()
|
|
defer resp.Body.Close()
|
|
- fmt.Printf("%s\n", resp_body)
|
|
|
|
|
|
+ fmt.Printf("验证码识别响应 %s\n", resp_body)
|
|
timesExist := gjson.GetBytes(resp_body, "times").Exists()
|
|
timesExist := gjson.GetBytes(resp_body, "times").Exists()
|
|
//fmt.Printf("%v,%v\n", gjson.GetBytes(resp_body, "times").Exists(),gjson.GetBytes(resp_body, "times").Int())
|
|
//fmt.Printf("%v,%v\n", gjson.GetBytes(resp_body, "times").Exists(),gjson.GetBytes(resp_body, "times").Int())
|
|
if !timesExist {
|
|
if !timesExist {
|
|
@@ -148,7 +218,7 @@ func codeGet(data []byte, account string, token string) (bool, string) {
|
|
}
|
|
}
|
|
return false, gjson.GetBytes(resp_body, "data").String()
|
|
return false, gjson.GetBytes(resp_body, "data").String()
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+*/
|
|
var dbMutex sync.Mutex
|
|
var dbMutex sync.Mutex
|
|
var db *leveldb.DB
|
|
var db *leveldb.DB
|
|
|
|
|
|
@@ -202,7 +272,9 @@ func TokenDbPut(token string, value string) {
|
|
}
|
|
}
|
|
|
|
|
|
func codeGetHandle(data []byte, account string, tokens []string) string {
|
|
func codeGetHandle(data []byte, account string, tokens []string) string {
|
|
- now := time.Now()
|
|
|
|
|
|
+ return codeGetNew(data, account, "")
|
|
|
|
+
|
|
|
|
+ /*now := time.Now()
|
|
day := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
|
day := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
|
dayStr := fmt.Sprintf("%d", day.Unix())
|
|
dayStr := fmt.Sprintf("%d", day.Unix())
|
|
for _, token := range tokens {
|
|
for _, token := range tokens {
|
|
@@ -224,7 +296,7 @@ func codeGetHandle(data []byte, account string, tokens []string) string {
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
- return ""
|
|
|
|
|
|
+ return ""*/
|
|
}
|
|
}
|
|
func StartOneStudent(usernameText string, passwordText string, realName string) (service *selenium.Service, wd selenium.WebDriver, err error) {
|
|
func StartOneStudent(usernameText string, passwordText string, realName string) (service *selenium.Service, wd selenium.WebDriver, err error) {
|
|
defer func() {
|
|
defer func() {
|
|
@@ -283,7 +355,7 @@ func StartOneStudentHandle(usernameText string, passwordText string, realName st
|
|
|
|
|
|
var (
|
|
var (
|
|
//driverPath = `C:\Users\lqzlt\AppData\Local\Google\Chrome\Application\chromedriver.exe`
|
|
//driverPath = `C:\Users\lqzlt\AppData\Local\Google\Chrome\Application\chromedriver.exe`
|
|
- driverPath = `chromedriver.exe`
|
|
|
|
|
|
+ driverPath = `./chromedriver.exe`
|
|
port = 60002
|
|
port = 60002
|
|
)
|
|
)
|
|
|
|
|
|
@@ -605,11 +677,13 @@ func shortAnswer(question QuestionInfo, questionM map[string][]string) error {
|
|
if len(question.AnswerArray) == 0 {
|
|
if len(question.AnswerArray) == 0 {
|
|
return errors.New(fmt.Sprintf("%s 选项为空", question.Text))
|
|
return errors.New(fmt.Sprintf("%s 选项为空", question.Text))
|
|
}
|
|
}
|
|
|
|
+ //fmt.Println("收集的答案000000000000000000000000:", questionM)
|
|
str := TrimSpace(question.Text)
|
|
str := TrimSpace(question.Text)
|
|
str = ParseHan(str)
|
|
str = ParseHan(str)
|
|
str = fmt.Sprintf("%d-", question.Tag) + str
|
|
str = fmt.Sprintf("%d-", question.Tag) + str
|
|
-
|
|
|
|
|
|
+ //fmt.Println("问答题目1111111111111111111111111:", str)
|
|
answerstrs, _ := questionM[str]
|
|
answerstrs, _ := questionM[str]
|
|
|
|
+ //fmt.Println("问答答案2222222222222222222222222:", answerstrs)
|
|
if len(answerstrs) == 0 {
|
|
if len(answerstrs) == 0 {
|
|
str = strings.TrimRight(str, "分")
|
|
str = strings.TrimRight(str, "分")
|
|
answerstrs, _ = questionM[str]
|
|
answerstrs, _ = questionM[str]
|
|
@@ -620,6 +694,7 @@ func shortAnswer(question QuestionInfo, questionM map[string][]string) error {
|
|
index := GenerateRandom(len(answerstrs))
|
|
index := GenerateRandom(len(answerstrs))
|
|
question.AnswerArray[0].Ptag.Element.Clear()
|
|
question.AnswerArray[0].Ptag.Element.Clear()
|
|
question.AnswerArray[0].Ptag.Element.SendKeys(answerstrs[index])
|
|
question.AnswerArray[0].Ptag.Element.SendKeys(answerstrs[index])
|
|
|
|
+ //fmt.Println("问答选择答案2222222222222222222222222:", answerstrs[index])
|
|
time.Sleep(500 * time.Millisecond)
|
|
time.Sleep(500 * time.Millisecond)
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
@@ -1194,6 +1269,7 @@ type ModuleSubInfo struct {
|
|
Id string
|
|
Id string
|
|
Stype string
|
|
Stype string
|
|
SyllabusId int64
|
|
SyllabusId int64
|
|
|
|
+ Type int // 1 page,2 vedio
|
|
}
|
|
}
|
|
|
|
|
|
type ModuleInfo struct {
|
|
type ModuleInfo struct {
|
|
@@ -1262,9 +1338,12 @@ func GetModuleInfo(courseId string, moduleId string, cookie string) (*ModuleInfo
|
|
}
|
|
}
|
|
item.Id = array[1]
|
|
item.Id = array[1]
|
|
if stype == "page" {
|
|
if stype == "page" {
|
|
|
|
+ item.Type = 1
|
|
texts = append(texts, item)
|
|
texts = append(texts, item)
|
|
|
|
+ vedios = append(vedios, item)
|
|
} else if stype == "online_video" || (stype == "web_link" && strings.Contains(item.Name, "视频")) || stype == "material" {
|
|
} else if stype == "online_video" || (stype == "web_link" && strings.Contains(item.Name, "视频")) || stype == "material" {
|
|
index := -1
|
|
index := -1
|
|
|
|
+ item.Type = 2
|
|
for i := len(vedios) - 1; i >= 0; i-- {
|
|
for i := len(vedios) - 1; i >= 0; i-- {
|
|
if item.SyllabusId == vedios[i].SyllabusId {
|
|
if item.SyllabusId == vedios[i].SyllabusId {
|
|
index = i
|
|
index = i
|
|
@@ -1505,6 +1584,10 @@ func examHandleSpecialQuestion(wd selenium.WebDriver) ([]QuestionInfo, error) {
|
|
if strings.Contains(attr, "multiple_selection") {
|
|
if strings.Contains(attr, "multiple_selection") {
|
|
tag = 3
|
|
tag = 3
|
|
}
|
|
}
|
|
|
|
+ if strings.Contains(attr, "short_answer") {
|
|
|
|
+ tag = 4
|
|
|
|
+ }
|
|
|
|
+
|
|
if tag == 0 {
|
|
if tag == 0 {
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
@@ -1514,55 +1597,84 @@ func examHandleSpecialQuestion(wd selenium.WebDriver) ([]QuestionInfo, error) {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
txt, _ := p.Text()
|
|
txt, _ := p.Text()
|
|
|
|
+
|
|
item.Text = trimQuestionPrefix(txt)
|
|
item.Text = trimQuestionPrefix(txt)
|
|
|
|
+ //fmt.Println("1111111111111111112222222222222222222222222222222 text:", txt, item.Text)
|
|
|
|
+ if tag == 4 {
|
|
|
|
+ ptag, err := li1.FindElement(selenium.ByXPATH, "./div/div/div/div/div/div/div/p")
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Printf("简单题err:%v\n", err)
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
|
|
- // 题目选项
|
|
|
|
- ol, _ := li1.FindElement(selenium.ByXPATH, "./div/div/ol")
|
|
|
|
- lis, _ := ol.FindElements(selenium.ByXPATH, "./li")
|
|
|
|
- for _, li := range lis {
|
|
|
|
|
|
+ item.Text = TrimSpace(item.Text)
|
|
|
|
+ item.Text = ParseHan(item.Text)
|
|
|
|
|
|
- answerIterm := AnswerInfo{}
|
|
|
|
- if tag == 2 {
|
|
|
|
- radio, err := li.FindElement(selenium.ByXPATH, "./label/span/input")
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
- answerIterm.Radio = &ElementInfo{Element: radio}
|
|
|
|
- answer, err := li.FindElement(selenium.ByXPATH, "./label/div/span")
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
- txt, _ := answer.Text()
|
|
|
|
- answerIterm.Text = txt
|
|
|
|
- //fmt.Printf("收集题目答案:%s\n", txt)
|
|
|
|
- } else if tag == 1 || tag == 3 {
|
|
|
|
- radio, err := li.FindElement(selenium.ByXPATH, "./label/span/input")
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
- answerIterm.Radio = &ElementInfo{Element: radio}
|
|
|
|
- answer, err := li.FindElement(selenium.ByXPATH, "./label/div/span")
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, err
|
|
|
|
- }
|
|
|
|
- txt, _ := answer.Text()
|
|
|
|
- answerIterm.Text = txt
|
|
|
|
- //fmt.Printf("收集题目答案:%s\n", txt)
|
|
|
|
- if tag == 3 {
|
|
|
|
- txt, _ := radio.GetAttribute("class")
|
|
|
|
- if strings.Contains(txt, "ng-not-empty") {
|
|
|
|
- //radio.Click()
|
|
|
|
- tryClick(wd, radio)
|
|
|
|
|
|
+ /*itemTxt := ""
|
|
|
|
+ itemList := strings.Split(item.Text, ".")
|
|
|
|
+ if len(itemList) > 1 {
|
|
|
|
+ for index, v := range itemList {
|
|
|
|
+ if index == 0 {
|
|
|
|
+ continue
|
|
}
|
|
}
|
|
|
|
+ itemTxt = itemTxt + v
|
|
}
|
|
}
|
|
|
|
+ item.Text = strings.TrimSpace(itemTxt)
|
|
|
|
+ }
|
|
|
|
+ */
|
|
|
|
+ //fmt.Println("1111111111111111112222222222222222222222222222222 text finishi:", item.Text)
|
|
|
|
+ anserItem := &AnswerInfo{Ptag: &ElementInfo{Element: ptag}}
|
|
|
|
+ item.AnswerArray = append(item.AnswerArray, anserItem)
|
|
|
|
+ ret = append(ret, item)
|
|
|
|
+ continue
|
|
|
|
+ } else {
|
|
|
|
+ // 题目选项
|
|
|
|
+ ol, _ := li1.FindElement(selenium.ByXPATH, "./div/div/ol")
|
|
|
|
+ lis, _ := ol.FindElements(selenium.ByXPATH, "./li")
|
|
|
|
+ for _, li := range lis {
|
|
|
|
+ answerIterm := AnswerInfo{}
|
|
|
|
+ if tag == 2 {
|
|
|
|
+ radio, err := li.FindElement(selenium.ByXPATH, "./label/span/input")
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+ answerIterm.Radio = &ElementInfo{Element: radio}
|
|
|
|
+ answer, err := li.FindElement(selenium.ByXPATH, "./label/div/span")
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+ txt, _ := answer.Text()
|
|
|
|
+ answerIterm.Text = txt
|
|
|
|
+ //fmt.Printf("收集题目答案:%s\n", txt)
|
|
|
|
+ } else if tag == 1 || tag == 3 {
|
|
|
|
+ radio, err := li.FindElement(selenium.ByXPATH, "./label/span/input")
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+ answerIterm.Radio = &ElementInfo{Element: radio}
|
|
|
|
+ answer, err := li.FindElement(selenium.ByXPATH, "./label/div/span")
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+ txt, _ := answer.Text()
|
|
|
|
+ answerIterm.Text = txt
|
|
|
|
+ //fmt.Printf("收集题目答案:%s\n", txt)
|
|
|
|
+ if tag == 3 {
|
|
|
|
+ txt, _ := radio.GetAttribute("class")
|
|
|
|
+ if strings.Contains(txt, "ng-not-empty") {
|
|
|
|
+ //radio.Click()
|
|
|
|
+ tryClick(wd, radio)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- //ppp, _ := radio.FindElement(selenium.ByXPATH, "./following-sibling::span")
|
|
|
|
- //txt, _ = ppp.Text()
|
|
|
|
- //fmt.Printf("kkkkkkkkkkkkkkkkkkkaa:%s,%s\n", txt, answerIterm.Text)
|
|
|
|
|
|
+ //ppp, _ := radio.FindElement(selenium.ByXPATH, "./following-sibling::span")
|
|
|
|
+ //txt, _ = ppp.Text()
|
|
|
|
+ //fmt.Printf("kkkkkkkkkkkkkkkkkkkaa:%s,%s\n", txt, answerIterm.Text)
|
|
|
|
|
|
- }
|
|
|
|
- item.AnswerArray = append(item.AnswerArray, &answerIterm)
|
|
|
|
|
|
+ }
|
|
|
|
+ item.AnswerArray = append(item.AnswerArray, &answerIterm)
|
|
|
|
|
|
|
|
+ }
|
|
}
|
|
}
|
|
ret = append(ret, item)
|
|
ret = append(ret, item)
|
|
}
|
|
}
|
|
@@ -1887,15 +1999,24 @@ func examHandleSubmit(wd selenium.WebDriver) error {
|
|
|
|
|
|
func examHandle(wd selenium.WebDriver, courseId, moduleId, id string, qustionM map[string][]string, specialCourse bool) error {
|
|
func examHandle(wd selenium.WebDriver, courseId, moduleId, id string, qustionM map[string][]string, specialCourse bool) error {
|
|
cookie, _ := getCookies(wd)
|
|
cookie, _ := getCookies(wd)
|
|
- finsh, submited := checkExamFinish(id, cookie)
|
|
|
|
|
|
+ finsh, submited, noScore := checkExamFinish(id, cookie)
|
|
|
|
+ if noScore {
|
|
|
|
+ fmt.Printf("不计分,该试题不做\n")
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
if finsh {
|
|
if finsh {
|
|
fmt.Printf("试题达到最大提交次数\n")
|
|
fmt.Printf("试题达到最大提交次数\n")
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
if submited {
|
|
if submited {
|
|
- fmt.Printf("已完成该试题\n")
|
|
|
|
- return nil
|
|
|
|
|
|
+ isFinsh := checkExamScore(id, cookie)
|
|
|
|
+ if isFinsh {
|
|
|
|
+ fmt.Printf("已完成该试题,并满足分数\n")
|
|
|
|
+ return nil
|
|
|
|
+ } else {
|
|
|
|
+ fmt.Printf("已完成该试题,不满足分数,继续答题\n")
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// 跳转页面
|
|
// 跳转页面
|
|
@@ -1926,6 +2047,8 @@ func examHandle(wd selenium.WebDriver, courseId, moduleId, id string, qustionM m
|
|
if true {
|
|
if true {
|
|
//time.Sleep(4000 * time.Second)
|
|
//time.Sleep(4000 * time.Second)
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ fmt.Println("--------------------------------------------------------题目和答案:", questions)
|
|
// 匹配题库并选择答案
|
|
// 匹配题库并选择答案
|
|
fmt.Printf("*****************开始匹配答案\n")
|
|
fmt.Printf("*****************开始匹配答案\n")
|
|
if err := examHandleMatch(wd, questions, qustionM); err != nil {
|
|
if err := examHandleMatch(wd, questions, qustionM); err != nil {
|
|
@@ -1958,11 +2081,44 @@ func examHandle(wd selenium.WebDriver, courseId, moduleId, id string, qustionM m
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
-func checkExamFinish(id string, cookie string) (finish bool, submited bool) {
|
|
|
|
|
|
+func checkExamScore(id string, cookie string) (finish bool) {
|
|
|
|
+ url := fmt.Sprintf("https://lms.ouchn.cn/api/exams/%s/submissions", id)
|
|
|
|
+ request, err := http.NewRequest("GET", url, nil)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return false
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
+ request.Header.Set("Cookie", cookie)
|
|
|
|
+ request.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36")
|
|
|
|
+ //request.Header.Set("Host", "chengdu.ouchn.cn")
|
|
|
|
+
|
|
|
|
+ client := http.Client{}
|
|
|
|
+ resp, err := client.Do(request)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return false
|
|
|
|
+ }
|
|
|
|
+ defer resp.Body.Close()
|
|
|
|
+
|
|
|
|
+ respBytes, err := ioutil.ReadAll(resp.Body)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return false
|
|
|
|
+ }
|
|
|
|
+ examScore := gjson.GetBytes(respBytes, "exam_score").Int()
|
|
|
|
+ fmt.Println("分数:", examScore, " 最低要求分数:", config.Conf.MinScore)
|
|
|
|
+ if int(examScore) >= config.Conf.MinScore {
|
|
|
|
+ return true
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func checkExamFinish(id string, cookie string) (finish bool, submited bool, noScore bool) {
|
|
url := fmt.Sprintf("https://lms.ouchn.cn/api/exams/%s", id)
|
|
url := fmt.Sprintf("https://lms.ouchn.cn/api/exams/%s", id)
|
|
request, err := http.NewRequest("GET", url, nil)
|
|
request, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return false, false
|
|
|
|
|
|
+ return false, false, false
|
|
}
|
|
}
|
|
|
|
|
|
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
@@ -1973,24 +2129,29 @@ func checkExamFinish(id string, cookie string) (finish bool, submited bool) {
|
|
client := http.Client{}
|
|
client := http.Client{}
|
|
resp, err := client.Do(request)
|
|
resp, err := client.Do(request)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return false, false
|
|
|
|
|
|
+ return false, false, false
|
|
}
|
|
}
|
|
defer resp.Body.Close()
|
|
defer resp.Body.Close()
|
|
|
|
|
|
respBytes, err := ioutil.ReadAll(resp.Body)
|
|
respBytes, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return false, false
|
|
|
|
|
|
+ return false, false, false
|
|
}
|
|
}
|
|
|
|
+ scorePercentage := gjson.GetBytes(respBytes, "score_percentage").String()
|
|
|
|
+ if scorePercentage == "0" || scorePercentage == "0.0" || scorePercentage == "0.00" {
|
|
|
|
+ return true, false, true
|
|
|
|
+ }
|
|
|
|
+
|
|
submitTimes := gjson.GetBytes(respBytes, "submit_times").Int()
|
|
submitTimes := gjson.GetBytes(respBytes, "submit_times").Int()
|
|
submittedTimes := gjson.GetBytes(respBytes, "submitted_times").Int()
|
|
submittedTimes := gjson.GetBytes(respBytes, "submitted_times").Int()
|
|
if submittedTimes > 0 {
|
|
if submittedTimes > 0 {
|
|
submited = true
|
|
submited = true
|
|
}
|
|
}
|
|
if submitTimes == submittedTimes && submitTimes > 0 {
|
|
if submitTimes == submittedTimes && submitTimes > 0 {
|
|
- return true, submited
|
|
|
|
|
|
+ return true, submited, false
|
|
}
|
|
}
|
|
|
|
|
|
- return false, submited
|
|
|
|
|
|
+ return false, submited, false
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2116,7 +2277,7 @@ func CourseHandle(wd selenium.WebDriver, username string) error {
|
|
}
|
|
}
|
|
|
|
|
|
// 获取某栏目下的试题和视频数据
|
|
// 获取某栏目下的试题和视频数据
|
|
- //fmt.Println("111111111111111111:", courseId, module.ModuleId)
|
|
|
|
|
|
+
|
|
moduleInfo, err := GetModuleInfo(courseId, module.ModuleId, cookie)
|
|
moduleInfo, err := GetModuleInfo(courseId, module.ModuleId, cookie)
|
|
if err != nil {
|
|
if err != nil {
|
|
return errors.New(fmt.Sprintf("获取module(%s)详细信息失败:%s", module.Name, err.Error()))
|
|
return errors.New(fmt.Sprintf("获取module(%s)详细信息失败:%s", module.Name, err.Error()))
|
|
@@ -2147,66 +2308,83 @@ func CourseHandle(wd selenium.WebDriver, username string) error {
|
|
|
|
|
|
// 处理视频数据
|
|
// 处理视频数据
|
|
for _, info := range moduleInfo.VedioInfos {
|
|
for _, info := range moduleInfo.VedioInfos {
|
|
|
|
+ if config.Conf.HandlePage {
|
|
|
|
+ if info.Type == 1 {
|
|
|
|
+ fmt.Printf("*****正在处理网页数据:%s\n", info.Name)
|
|
|
|
+ url := MakeTxtUrl(courseId, module.ModuleId, info.Id)
|
|
|
|
+ wd.Get(url)
|
|
|
|
+ count := 0
|
|
|
|
+ for count < 10 {
|
|
|
|
+ curl, _ := wd.CurrentURL()
|
|
|
|
+ if strings.Contains(curl, info.Id) {
|
|
|
|
+ time.Sleep(5 * time.Second)
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ count++
|
|
|
|
+ time.Sleep(1 * time.Second)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if info.Type == 2 {
|
|
|
|
+ fmt.Printf("*****正在处理视频数据:%s\n", info.Name)
|
|
|
|
|
|
- fmt.Printf("*****正在处理视频数据:%s\n", info.Name)
|
|
|
|
|
|
+ if info.Stype == "material" {
|
|
|
|
+ doMaterial(info.Id, cookie)
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
|
|
- if info.Stype == "material" {
|
|
|
|
- doMaterial(info.Id, cookie)
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
|
|
+ url := MakeTxtUrl(courseId, module.ModuleId, info.Id)
|
|
|
|
+ wd.Get(url)
|
|
|
|
+ cookie, _ := getCookies(wd)
|
|
|
|
|
|
- url := MakeTxtUrl(courseId, module.ModuleId, info.Id)
|
|
|
|
- wd.Get(url)
|
|
|
|
- cookie, _ := getCookies(wd)
|
|
|
|
|
|
+ // 特殊视频
|
|
|
|
+ if info.Stype == "web_link" {
|
|
|
|
+ array := strings.Split(info.Name, ":")
|
|
|
|
+ if len(array) > 1 {
|
|
|
|
+ array[0] = array[1]
|
|
|
|
+ }
|
|
|
|
|
|
- // 特殊视频
|
|
|
|
- if info.Stype == "web_link" {
|
|
|
|
- array := strings.Split(info.Name, ":")
|
|
|
|
- if len(array) > 1 {
|
|
|
|
- array[0] = array[1]
|
|
|
|
|
|
+ str := fmt.Sprintf("//iframe[contains(@ng-src, '%s')]", array[0])
|
|
|
|
+ wd.WaitWithTimeout(Displayed(selenium.ByXPATH, str), time.Duration(config.Conf.Timeout)*time.Second)
|
|
|
|
+ continue
|
|
}
|
|
}
|
|
|
|
|
|
- str := fmt.Sprintf("//iframe[contains(@ng-src, '%s')]", array[0])
|
|
|
|
- wd.WaitWithTimeout(Displayed(selenium.ByXPATH, str), time.Duration(config.Conf.Timeout)*time.Second)
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- err = wd.WaitWithTimeout(Displayed(selenium.ByXPATH, "//button[@class='mvp-toggle-play mvp-first-btn-margin']"), time.Duration(config.Conf.Timeout)*time.Second)
|
|
|
|
- if err != nil {
|
|
|
|
- wd.Get(url)
|
|
|
|
err = wd.WaitWithTimeout(Displayed(selenium.ByXPATH, "//button[@class='mvp-toggle-play mvp-first-btn-margin']"), time.Duration(config.Conf.Timeout)*time.Second)
|
|
err = wd.WaitWithTimeout(Displayed(selenium.ByXPATH, "//button[@class='mvp-toggle-play mvp-first-btn-margin']"), time.Duration(config.Conf.Timeout)*time.Second)
|
|
if err != nil {
|
|
if err != nil {
|
|
- fmt.Printf("获取播放按钮失败\n")
|
|
|
|
|
|
+ wd.Get(url)
|
|
|
|
+ err = wd.WaitWithTimeout(Displayed(selenium.ByXPATH, "//button[@class='mvp-toggle-play mvp-first-btn-margin']"), time.Duration(config.Conf.Timeout)*time.Second)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Printf("获取播放按钮失败\n")
|
|
|
|
+ }
|
|
|
|
+ continue
|
|
|
|
+ //return err
|
|
}
|
|
}
|
|
- continue
|
|
|
|
- //return err
|
|
|
|
- }
|
|
|
|
|
|
|
|
- playButton, _ := wd.FindElement(selenium.ByXPATH, "//button[@class='mvp-toggle-play mvp-first-btn-margin']")
|
|
|
|
- er := playButton.Click()
|
|
|
|
- //er := tryClick(wd, playButton)
|
|
|
|
- if er != nil {
|
|
|
|
- fmt.Printf("播放点击失败:%v\n", er)
|
|
|
|
- return er
|
|
|
|
- }
|
|
|
|
|
|
+ playButton, _ := wd.FindElement(selenium.ByXPATH, "//button[@class='mvp-toggle-play mvp-first-btn-margin']")
|
|
|
|
+ er := playButton.Click()
|
|
|
|
+ //er := tryClick(wd, playButton)
|
|
|
|
+ if er != nil {
|
|
|
|
+ fmt.Printf("播放点击失败:%v\n", er)
|
|
|
|
+ return er
|
|
|
|
+ }
|
|
|
|
|
|
- //fmt.Printf("cookie:%s\n", cookie)
|
|
|
|
- time.Sleep(time.Duration(config.Conf.VideoInterval) * time.Second)
|
|
|
|
|
|
+ //fmt.Printf("cookie:%s\n", cookie)
|
|
|
|
+ time.Sleep(time.Duration(config.Conf.VideoInterval) * time.Second)
|
|
|
|
|
|
- //er = tryClick(wd, playButton)
|
|
|
|
- //if er != nil {
|
|
|
|
- // fmt.Printf("停止播放点击失败:%v\n", er)
|
|
|
|
- //}
|
|
|
|
- //wd.Get(fmt.Sprintf("https://lms.ouchn.cn/course/%s/ng#/my-stat", courseId))
|
|
|
|
|
|
+ //er = tryClick(wd, playButton)
|
|
|
|
+ //if er != nil {
|
|
|
|
+ // fmt.Printf("停止播放点击失败:%v\n", er)
|
|
|
|
+ //}
|
|
|
|
+ //wd.Get(fmt.Sprintf("https://lms.ouchn.cn/course/%s/ng#/my-stat", courseId))
|
|
|
|
|
|
- //time.Sleep(2*time.Second)
|
|
|
|
- err := VedioCompleteHandle(cookie, info.Id)
|
|
|
|
- if err != nil {
|
|
|
|
- fmt.Printf(" 视频%s处理失败(%s)\n", info.Name, err.Error())
|
|
|
|
- return err
|
|
|
|
|
|
+ //time.Sleep(2*time.Second)
|
|
|
|
+ err := VedioCompleteHandle(cookie, info.Id)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Printf(" 视频%s处理失败(%s)\n", info.Name, err.Error())
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ //time.Sleep(10000*time.Second)
|
|
}
|
|
}
|
|
- //time.Sleep(10000*time.Second)
|
|
|
|
-
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|