package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "net/url" "os" "os/exec" "strings" "time" "golang.org/x/net/html" ) // Config represents the configuration structure type Config struct { Username string `json:"username"` Password string `json:"password"` Domain string `json:"domain"` } func main() { // Load or create the configuration file config, err := readOrCreateConfig("config.json") if err != nil { fmt.Println("配置文件处理出错:", err) return } // Schedule a task to run every 5 seconds ticker := time.NewTicker(5 * time.Second) defer ticker.Stop() for { select { case <-ticker.C: // Check if baidu.com is reachable if !ping("180.101.50.242") { fmt.Println("keep alive no res") if err := performLogin(config); err != nil { fmt.Println("执行登录操作出错:", err) } } } } } // performLogin performs the login operation func performLogin(config Config) error { // Fetch the HTML content resp, err := http.Get("http://211.70.248.14/srun_portal_pc.php?ac_id=9&") if err != nil { return fmt.Errorf("GET请求出错: %w", err) } defer resp.Body.Close() // Read the response body body, err := ioutil.ReadAll(resp.Body) if err != nil { return fmt.Errorf("读取响应出错: %w", err) } htmlContent := string(body) // Parse HTML to extract form information action, acID, userIP := parseForm(htmlContent) action = "http://211.70.248.14/srun_portal_pc.php?ac_id=9&" fmt.Printf("Form Info:\nAction: %s\nAC_ID: %s\nUser_IP: %s\n", action, acID, userIP) // Construct POST data formData := url.Values{ "action": {"login"}, "ac_id": {acID}, "user_ip": {userIP}, "username": {config.Username}, "password": {config.Password}, } // Set domain based on the configuration switch config.Domain { case "CT": formData.Add("domain", "@telcom") case "CM": formData.Add("domain", "@cmcc") default: formData.Add("domain", "") } // Send POST request resp, err = http.PostForm(action, formData) if err != nil { return fmt.Errorf("POST请求出错: %w", err) } defer resp.Body.Close() return nil } // readOrCreateConfig reads or creates the configuration file func readOrCreateConfig(filePath string) (Config, error) { var config Config // Try reading the configuration file configFile, err := ioutil.ReadFile(filePath) if err == nil { // File exists, parse the configuration file err = json.Unmarshal(configFile, &config) if err != nil { return config, fmt.Errorf("解析配置文件出错: %w", err) } return config, nil } // File does not exist, create a default configuration file if os.IsNotExist(err) { defaultConfig := Config{ Username: "your_username", Password: "your_password", Domain: "CT", } configJSON, _ := json.MarshalIndent(defaultConfig, "", " ") err = ioutil.WriteFile(filePath, configJSON, 0644) if err != nil { return config, fmt.Errorf("创建配置文件出错: %w", err) } fmt.Println("配置文件已创建,使用默认值。请编辑配置文件以更新信息。") return defaultConfig, nil } return config, fmt.Errorf("读取配置文件出错: %w", err) } // parseForm parses the HTML content to extract form information func parseForm(htmlContent string) (action, acID, userIP string) { doc, err := html.Parse(strings.NewReader(htmlContent)) if err != nil { fmt.Println("解析HTML出错:", err) return } var parse func(*html.Node) parse = func(n *html.Node) { if n.Type == html.ElementNode && n.Data == "form" { for _, a := range n.Attr { if a.Key == "action" { action = a.Val } } } if n.Type == html.ElementNode && n.Data == "input" { for _, a := range n.Attr { if a.Key == "name" { switch a.Val { case "ac_id": acID = getInputValue(n) case "user_ip": userIP = getInputValue(n) } } } } for c := n.FirstChild; c != nil; c = c.NextSibling { parse(c) } } parse(doc) return } // getInputValue gets the value of an input element func getInputValue(n *html.Node) string { for _, a := range n.Attr { if a.Key == "value" { return a.Val } } return "" } // ping checks if the given host is reachable func ping(host string) bool { cmd := exec.Command("ping", "-c", "1", host) err := cmd.Run() if err != nil { fmt.Println("Ping 错误:", err) return false } return true }