添加代码
This commit is contained in:
當前提交
dddb8a4ac0
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.idea
|
14
go.mod
Normal file
14
go.mod
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
module sdu-auto-evaluation
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/PuerkitoBio/goquery v1.8.0 // indirect
|
||||||
|
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||||
|
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect
|
||||||
|
github.com/dop251/goja v0.0.0-20211217115348-3f9136fa235d // indirect
|
||||||
|
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // indirect
|
||||||
|
golang.org/x/text v0.3.6 // indirect
|
||||||
|
)
|
29
go.sum
Normal file
29
go.sum
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
|
||||||
|
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
||||||
|
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||||
|
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||||
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
|
||||||
|
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||||
|
github.com/dop251/goja v0.0.0-20211217115348-3f9136fa235d h1:XT7Qdmcuwgsgz4GXejX7R5Morysk2GOpeguYJ9JoF5c=
|
||||||
|
github.com/dop251/goja v0.0.0-20211217115348-3f9136fa235d/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
||||||
|
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
|
||||||
|
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
|
||||||
|
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=
|
||||||
|
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
159
main.go
Normal file
159
main.go
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"github.com/PuerkitoBio/goquery"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"net/url"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Username = flag.String("u", "", "统一认证学号/用户名")
|
||||||
|
var Password = flag.String("p", "", "统一认证密码")
|
||||||
|
var evaluationChan = make(chan struct{}, 3)
|
||||||
|
var waitGroup = sync.WaitGroup{}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
flag.Parse()
|
||||||
|
if *Username == "" || *Password == "" {
|
||||||
|
flag.Usage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("正在登入系统...")
|
||||||
|
res, err := Client.Do(createRequest("GET", "http://bkzhjx.wh.sdu.edu.cn/sso.jsp", nil))
|
||||||
|
_ = checkHttpError(res, err)
|
||||||
|
casUrl := "https://pass.sdu.edu.cn/cas/login?service=http%3A%2F%2Fbkzhjx.wh.sdu.edu.cn%2Fsso.jsp"
|
||||||
|
res, err = Client.Do(createRequest("GET", casUrl, nil))
|
||||||
|
err = checkHttpError(res, err)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
html, _ := io.ReadAll(res.Body)
|
||||||
|
ticket := regexp.MustCompile("name=\"lt\" value=\"(.*?)\"").FindStringSubmatch(string(html))[1]
|
||||||
|
rsa := strEnc(*Username + *Password + ticket)
|
||||||
|
loginValues := url.Values{
|
||||||
|
"rsa": {rsa},
|
||||||
|
"ul": {strconv.Itoa(utf8.RuneCountInString(*Username))},
|
||||||
|
"pl": {strconv.Itoa(utf8.RuneCountInString(*Password))},
|
||||||
|
"lt": {ticket},
|
||||||
|
"execution": {"e1s1"},
|
||||||
|
"_eventId": {"submit"},
|
||||||
|
}
|
||||||
|
res, err = Client.Do(createRequest("POST", casUrl, strings.NewReader(loginValues.Encode())))
|
||||||
|
err = checkHttpError(res, err)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
html, _ = io.ReadAll(res.Body)
|
||||||
|
if !strings.Contains(string(html), "强智科技教务系统欢迎") {
|
||||||
|
fmt.Println("用户名或密码错误")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("登入系统成功")
|
||||||
|
res, err = Client.Do(createRequest("GET", "https://bkzhjx.wh.sdu.edu.cn/jsxsd/xspj/xspj_find.do", nil))
|
||||||
|
err = checkHttpError(res, err)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
html, _ = io.ReadAll(res.Body)
|
||||||
|
evaluationLink := "https://bkzhjx.wh.sdu.edu.cn" + regexp.MustCompile("<a href=\"(.*?)\" title=\"点击进入评价\"").FindStringSubmatch(string(html))[1]
|
||||||
|
res, err = Client.Do(createRequest("GET", evaluationLink, nil))
|
||||||
|
err = checkHttpError(res, err)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
tableDocument, _ := goquery.NewDocumentFromReader(res.Body)
|
||||||
|
tableDocument.Find("table tr").Each(func(i int, selection *goquery.Selection) {
|
||||||
|
htmlOfTr, _ := selection.Html()
|
||||||
|
if strings.Contains(htmlOfTr, "Nsb_r_list_thb") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tdSelection := selection.Find("td")
|
||||||
|
var tds []string
|
||||||
|
tdSelection.Each(func(i int, selection *goquery.Selection) {
|
||||||
|
h, _ := selection.Html()
|
||||||
|
tds = append(tds, h)
|
||||||
|
})
|
||||||
|
if tds[7] == "是" {
|
||||||
|
fmt.Println(tds[2] + " 已评,自动忽略")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
evaluationFullURL := "https://bkzhjx.wh.sdu.edu.cn" + regexp.MustCompile("<a href=\"(.*?)\">评价").FindStringSubmatch(htmlOfTr)[1]
|
||||||
|
evaluationFullURL = strings.ReplaceAll(evaluationFullURL, "&", "&")
|
||||||
|
waitGroup.Add(1)
|
||||||
|
go evaluateByURL(tds[2], evaluationFullURL)
|
||||||
|
})
|
||||||
|
waitGroup.Wait()
|
||||||
|
}
|
||||||
|
func evaluateByURL(course string, fullURL string) {
|
||||||
|
evaluationChan <- struct{}{}
|
||||||
|
defer func() {
|
||||||
|
<-evaluationChan
|
||||||
|
waitGroup.Done()
|
||||||
|
}()
|
||||||
|
fmt.Println("正在评教:" + course)
|
||||||
|
res, err := Client.Do(createRequest("GET", fullURL, nil))
|
||||||
|
err = checkHttpError(res, err)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("评教 "+course+" 出错:%+v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
html, _ := io.ReadAll(res.Body)
|
||||||
|
postData := url.Values{
|
||||||
|
"issubmit": {"1"},
|
||||||
|
"kctzdnd": {"3"},
|
||||||
|
"yxjspx": {"1"},
|
||||||
|
"isxtjg": {"1"},
|
||||||
|
"jynr": {"课程良好"},
|
||||||
|
}
|
||||||
|
for _, key := range []string{"pj09id", "pj01id", "pj0502id", "jg0101id", "jx0404id", "xsflid", "xnxq01id", "jx02id", "pj02id", "ifypjxx", "pj03id", "pageIndex"} {
|
||||||
|
addStdHiddenFormValue(string(html), &postData, key)
|
||||||
|
}
|
||||||
|
doc, _ := goquery.NewDocumentFromReader(strings.NewReader(string(html)))
|
||||||
|
degree := 2
|
||||||
|
doc.Find("table tr").Each(func(i int, selection *goquery.Selection) {
|
||||||
|
htmlOfTr, _ := selection.Html()
|
||||||
|
if !strings.Contains(htmlOfTr, "pj06xh") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pj06ix := addStdHiddenFormValue(htmlOfTr, &postData, "pj06xh")
|
||||||
|
var selectedHash string
|
||||||
|
for _, item := range []int{1, 2, 3, 4, 5} {
|
||||||
|
hash, _ := selection.Find("input[id=pj0601id_" + pj06ix + "_" + strconv.Itoa(item) + "]").Attr("value")
|
||||||
|
currentScore, _ := selection.Find("input[name=pj0601fz_" + pj06ix + "_" + hash + "]").Attr("value")
|
||||||
|
postData.Add("pj0601fz_"+pj06ix+"_"+hash, currentScore)
|
||||||
|
if degree == item {
|
||||||
|
selectedHash = hash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
postData.Add("pj0601id_"+pj06ix, selectedHash)
|
||||||
|
if degree == 2 {
|
||||||
|
degree = 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res, err = Client.Do(createRequest("POST", "https://bkzhjx.wh.sdu.edu.cn/jsxsd/xspj/xspj_save.do", strings.NewReader(postData.Encode())))
|
||||||
|
err = checkHttpError(res, err)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("评教 "+course+" 出错:%+v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
html, _ = io.ReadAll(res.Body)
|
||||||
|
if !strings.Contains(string(html), "成功") {
|
||||||
|
fmt.Printf("评教 "+course+" 出错:%+v", err)
|
||||||
|
fmt.Println(string(html))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func addStdHiddenFormValue(html string, obj *url.Values, key string) string {
|
||||||
|
value := regexp.MustCompile("input type=\"hidden\" name=\"" + key + "\" value=\"(.*?)\"").FindStringSubmatch(html)[1]
|
||||||
|
obj.Add(key, value)
|
||||||
|
return value
|
||||||
|
}
|
39
network.go
Normal file
39
network.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/http/cookiejar"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Client *http.Client
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
transport := http.DefaultTransport.(*http.Transport).Clone()
|
||||||
|
transport.MaxIdleConnsPerHost = 10
|
||||||
|
jar, _ := cookiejar.New(nil)
|
||||||
|
Client = &http.Client{
|
||||||
|
Transport: transport,
|
||||||
|
CheckRedirect: nil,
|
||||||
|
Jar: jar,
|
||||||
|
Timeout: 15 * time.Second,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func createRequest(method string, url string, body io.Reader) *http.Request {
|
||||||
|
req, _ := http.NewRequest(method, url, body)
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
|
||||||
|
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0")
|
||||||
|
return req
|
||||||
|
}
|
||||||
|
func checkHttpError(res *http.Response, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
return errors.New(strconv.Itoa(res.StatusCode))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
26
util.go
Normal file
26
util.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"github.com/dop251/goja"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed des.js
|
||||||
|
var des string
|
||||||
|
|
||||||
|
func strEnc(data string) string {
|
||||||
|
vm := goja.New()
|
||||||
|
_, err := vm.RunString(des)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
sum, ok := goja.AssertFunction(vm.Get("strEnc"))
|
||||||
|
if !ok {
|
||||||
|
panic("Not a function")
|
||||||
|
}
|
||||||
|
res, err := sum(goja.Undefined(), vm.ToValue(data), vm.ToValue("1"), vm.ToValue("2"), vm.ToValue("3"))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return res.String()
|
||||||
|
}
|
載入中…
x
新增問題並參考
Block a user