{"record":{"id":"18c445c8a7887583","repo":"fish2018/pansou","slug":"error-18c445","errorCode":null,"errorMessage":"验证脚本参数不完整","messagePattern":"验证脚本参数不完整","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/qiwei/qiwei.go","lineNumber":366,"sourceCode":"// solveVerification completes the site's deterministic slider challenge. The\n// challenge is session-bound, so the caller and this method must share a\n// cookie jar on the same http.Client.\nfunc (p *QiweiPlugin) solveVerification(client *http.Client, pageURL, verifyHTML string) error {\n\tscriptMatch := verificationScriptRegex.FindStringSubmatch(verifyHTML)\n\tif len(scriptMatch) < 2 {\n\t\treturn fmt.Errorf(\"未找到滑动验证脚本\")\n\t}\n\tscriptURL := normalizeURL(pageURL, scriptMatch[1])\n\tjsBody, err := p.fetchBody(client, scriptURL, pageURL, detailTimeout)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"获取验证脚本失败: %w\", err)\n\t}\n\n\ttypeMatch := verificationTypeRegex.FindStringSubmatch(jsBody)\n\tkeyMatch := verificationKeyRegex.FindStringSubmatch(jsBody)\n\tvalueMatch := verificationValueRegex.FindStringSubmatch(jsBody)\n\tif len(typeMatch) < 2 || len(keyMatch) < 2 || len(valueMatch) < 2 {\n\t\treturn fmt.Errorf(\"验证脚本参数不完整\")\n\t}\n\n\tencodedValue := md5StringToHex(valueMatch[1])\n\tendpointPath := \"/a20be899_96a6_40b2_88ba_32f1f75f1552_yanzheng_huadong.php\"\n\tif endpointMatch := verificationEndpointRegex.FindStringSubmatch(jsBody); len(endpointMatch) > 1 {\n\t\tendpointPath = \"/\" + endpointMatch[1]\n\t}\n\tparsedPage, err := url.Parse(pageURL)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"验证页面地址无效: %w\", err)\n\t}\n\tverifyURL := (&url.URL{Scheme: parsedPage.Scheme, Host: parsedPage.Host, Path: endpointPath}).String()\n\tquery := url.Values{}\n\tquery.Set(\"type\", typeMatch[1])\n\tquery.Set(\"key\", keyMatch[1])\n\tquery.Set(\"value\", encodedValue)\n\tverifyURL += \"?\" + query.Encode()\n","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/qiwei/qiwei.go#L348-L384","documentation":"solveVerification extracts the slider-challenge parameters (type, key, value) from the site's verification JavaScript using regexes. If any of the three regex matches is missing its capture group, the plugin cannot build a verification request and throws this error. It signals the anti-bot script changed shape or the wrong JS body was fetched.","triggerScenarios":"solveVerification runs verificationTypeRegex/verificationKeyRegex/verificationValueRegex on the fetched JS body and any match returns fewer than 2 elements; called from searchSuggest or getDetailInfo when fetchBody returns a verify page.","commonSituations":"The target site updated its slider-verification JS so the hardcoded regexes no longer match; a CDN/WAF served a different or minified script; fetchBody returned an HTML error page instead of the JS file (content negotiated differently) while still passing isVerifyPage checks.","solutions":["Fetch the verification JS manually and update verificationTypeRegex/verificationKeyRegex/verificationValueRegex to match the current script format","Log jsBody (or a snippet) on this error to confirm what was actually parsed","Verify the scriptURL resolution in normalizeURL actually points at the challenge script, not an HTML page","Check whether the site now serves a different challenge entirely and implement the new solver"],"exampleFix":"// before\ntypeMatch := verificationTypeRegex.FindStringSubmatch(jsBody)\n// after (log payload to debug mismatches)\ntypeMatch := verificationTypeRegex.FindStringSubmatch(jsBody)\nif typeMatch == nil {\n    log.Printf(\"verify js did not match, body head: %.200s\", jsBody)\n}","handlingStrategy":"validation","validationCode":"// Pre-fetch the verify script and confirm parameters exist before relying on the solve\nresp, _ := http.Get(scriptURL)\njs, _ := io.ReadAll(resp.Body)\nok := verificationTypeRegex.Match(js) && verificationKeyRegex.Match(js) && verificationValueRegex.Match(js)\nif !ok { /* site likely changed its challenge; skip or alert */ }","typeGuard":null,"tryCatchPattern":"info, err := plugin.GetDetailInfo(ctx, url)\nif err != nil && strings.Contains(err.Error(), \"验证脚本参数不完整\") {\n    log.Printf(\"anti-bot script changed, failing url=%s: %v\", url, err)\n    return fallbackInfo\n}","preventionTips":["Pin and test regexes against the live JS in CI with a canary fetch","Log a JS-body snippet whenever parameter extraction fails","Alert on this error since it indicates an upstream site change, not a transient fault"],"tags":["scraping","regex-mismatch","anti-bot","verification"],"backgroundTag":"unexpected-response-shape","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}