feat: 登陆时不再需要打开浏览器,可以检测到答题出现滑块的情况

This commit is contained in:
johlanse 2022-03-06 22:03:14 +08:00
parent 067a353f18
commit e6c80e8567
8 changed files with 171 additions and 4 deletions

5
go.mod
View File

@ -27,6 +27,9 @@ require (
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/imroc/req/v3 v3.8.2 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/lestrrat-go/strftime v1.0.5 // indirect
@ -37,7 +40,7 @@ require (
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect
golang.org/x/net v0.0.0-20220111093109-d55c255bac03 // indirect
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect

11
go.sum
View File

@ -32,6 +32,12 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/guonaihong/gout v0.2.9 h1:8nU5hrtwP1qDwiadFvU+D+z3ud9WEk8iPSfxQDiebng=
github.com/guonaihong/gout v0.2.9/go.mod h1:H1JqEuZmK4h/urWUq/LnIOEzS1kxl5rK3NkFqZ6Rn48=
github.com/h2non/filetype v1.1.1/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/imroc/req/v3 v3.8.2 h1:wFZ7B0dclCQyjClP5GwXRboUGIek5l0mCpodrGgT01c=
github.com/imroc/req/v3 v3.8.2/go.mod h1:3JIicOKEDHfCSYYNLb/ObZNpx64EV5y40VlHMwhUCzU=
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
@ -99,14 +105,19 @@ golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeap
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20220111093109-d55c255bac03 h1:0FB83qp0AzVJm+0wcIlauAjJ+tNdh7jLuacRYCIVv7s=
golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

View File

@ -13,9 +13,12 @@ import (
"net/url"
"os"
"runtime"
"strings"
"time"
qrcodeTerminal "github.com/Baozisoftware/qrcode-terminal-go"
"github.com/google/uuid"
"github.com/imroc/req/v3"
"github.com/makiuchi-d/gozxing"
"github.com/makiuchi-d/gozxing/qrcode"
"github.com/mxschmitt/playwright-go"
@ -49,6 +52,29 @@ type Cookie struct {
SameSite string `json:"same_site" yaml:"same_site"`
}
type signResp struct {
Data struct {
Sign string `json:"sign"`
} `json:"data"`
Message string `json:"message"`
Code int `json:"code"`
Error interface{} `json:"error"`
Ok bool `json:"ok"`
}
type gennerateResp struct {
Success bool `json:"success"`
ErrorCode interface{} `json:"errorCode"`
ErrorMsg interface{} `json:"errorMsg"`
Result string `json:"result"`
Arguments interface{} `json:"arguments"`
}
type checkQrCodeResp struct {
Code string `json:"code"`
Success bool `json:"success"`
Message string `json:"message"`
Data string `json:"data"`
}
// Init
/**
* @Description:
@ -62,6 +88,110 @@ func (c *Core) Init() {
}
}
func (c *Core) L() ([]Cookie, error) {
client := req.C()
client.OnAfterResponse(func(client *req.Client, response *req.Response) error {
return nil
})
client.SetCommonHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36")
s := new(signResp)
_, err := client.R().SetResult(s).Get("https://pc-api.xuexi.cn/open/api/sns/sign")
if err != nil {
log.Errorln(err.Error())
return nil, err
}
log.Debugln("获取sign成功==》" + s.Data.Sign)
g := new(gennerateResp)
_, err = client.R().SetResult(g).Get("https://login.xuexi.cn/user/qrcode/generate")
if err != nil {
log.Errorln(err.Error())
return nil, err
}
log.Infoln(g.Result)
codeURL := fmt.Sprintf("https://login.xuexi.cn/login/qrcommit?showmenu=false&code=%v&appId=dingoankubyrfkttorhpou", g.Result)
qrCodeString := qrcodeTerminal.New2(qrcodeTerminal.ConsoleColors.BrightBlack, qrcodeTerminal.ConsoleColors.BrightWhite, qrcodeTerminal.QRCodeRecoveryLevels.Low).Get(codeURL)
qrCodeString.Print()
c.Push("text", "https://johlanse.github.io/study_xxqg/scheme.html?"+url.QueryEscape(codeURL))
checkQrCode := func() (bool, string) {
res := new(checkQrCodeResp)
_, err := client.R().SetResult(res).SetFormData(map[string]string{
"qrCode": g.Result,
"goto": "https://oa.xuexi.cn",
"pdmToken": ""}).SetHeader("content-type", "application/x-www-form-urlencoded;charset=UTF-8").Post("https://login.xuexi.cn/login/login_with_qr")
if err != nil {
return false, ""
}
if res.Success {
return true, res.Data
} else {
return false, ""
}
}
for i := 0; i < 150; i++ {
code, data := checkQrCode()
if code {
s2 := strings.Split(data, "=")[1]
response, err := client.R().SetQueryParams(map[string]string{
"code": s2,
"state": s.Data.Sign + uuid.New().String(),
}).Get("https://pc-api.xuexi.cn/login/secure_check")
if err != nil {
return nil, err
}
var (
cos []Cookie
)
for _, c := range response.Cookies() {
co := Cookie{}
co.Name = c.Name
co.Path = c.Path
co.Value = c.Value
co.Domain = c.Domain
co.Expires = int(c.Expires.Unix())
co.SameSite = "Strict"
co.HTTPOnly = c.HttpOnly
co.Secure = c.Secure
cos = append(cos, co)
}
resp, err := client.R().Get("https://pc.xuexi.cn/points/my-points.html")
if err != nil {
return nil, err
}
for _, c := range resp.Cookies() {
co := Cookie{}
co.Name = c.Name
co.Path = c.Path
co.Value = c.Value
co.Domain = c.Domain
co.Expires = int(c.Expires.Unix())
co.SameSite = "Strict"
co.HTTPOnly = c.HttpOnly
co.Secure = c.Secure
cos = append(cos, co)
}
info, nick, err := GetUserInfo(cos)
if err != nil {
return cos, err
}
c.Push("text", "登录成功,用户名:"+nick)
err = SaveUser(User{
Cookies: cos,
Nick: nick,
Uid: info,
Time: time.Now().Add(time.Hour * 24).Unix(),
})
if err != nil {
return cos, err
}
return cos, err
}
}
return nil, errors.New("time out")
}
func (c *Core) initWondows() {
dir, err := os.Getwd()
if err != nil {

View File

@ -18,3 +18,11 @@ func TestName(t *testing.T) {
}
fmt.Println(score)
}
func TestLogin(t *testing.T) {
core := Core{}
core.Push = func(kind string, message string) {
fmt.Println(message)
}
core.L()
}

View File

@ -48,8 +48,10 @@ func (c *Core) RespondDaily(cookies []Cookie, model string) {
return
}
page.Goto("https://pc.xuexi.cn/points/my-points.html")
err = (*c.context).AddCookies(cookieToParam(cookies)...)
if err != nil {
log.Errorln(err.Error())
log.Errorln("添加cookie信息失败已退出答题")
return
@ -150,6 +152,19 @@ func (c *Core) RespondDaily(cookies []Cookie, model string) {
log.Errorln("提交答案失败")
}
}
handle, _ := page.QuerySelector("#nc_mask > div")
if handle != nil {
log.Infoln(handle)
en, err := handle.IsVisible()
if err != nil {
return
}
if en {
log.Infoln("可能存在滑块")
c.Push("text", "答题过程出现滑块")
return
}
}
switch model {
case "daily":
{

View File

@ -174,7 +174,7 @@ func login(bot *Telegram, args []string) {
}
core.Init()
defer core.Quit()
_, err := core.Login()
_, err := core.L()
if err != nil {
bot.SendMsg(err.Error())
return

View File

@ -101,7 +101,7 @@ func do() {
switch {
case len(users) < 1:
log.Infoln("未检测到有效用户信息,将采用登录模式")
cookies, _ = core.Login()
cookies, _ = core.L()
case len(users) == 1:
log.Infoln("检测到1位有效用户信息采用默认用户")
cookies = users[0].Cookies

View File

@ -94,7 +94,7 @@ func binaryName() string {
}
ext := "tar.gz"
if runtime.GOOS == "windows" {
ext = "zip"
ext = "exe"
}
return fmt.Sprintf("study_xxqg_%v_%v.%v", runtime.GOOS, goarch, ext)
}