fish2018/pansou · error
未找到formhash值
Error message
未找到formhash值
What it means
getFormhash scrapes the site's HTML to extract the anti-CSRF 'formhash' value required by the search form. If, after parsing the document with goquery, no formhash value is found in any input field or URL, it returns this error. It means the fetched page did not contain the expected hidden form token.
Solutions
- Log the fetched HTML (enable DebugLog or dump resp body) to see what page was actually returned
- Set/refresh realistic request headers (User-Agent, Referer, cookies) in setRequestHeaders so the site serves the real page
- Update the formhash selector in getFormhash to match the current site markup
- Add retry logic — the page may load correctly on a second attempt
- Check whether the site now requires login or JS challenge solving
Example fix
// before
if formhash == "" {
return "", fmt.Errorf("未找到formhash值")
}
// after
if formhash == "" {
return "", fmt.Errorf("未找到formhash值 (page status body snippet: %.200s)", pageBody)
} Defensive patterns
Strategy: retry
Validate before calling
// Before trusting the flow, verify the fetched page contains a formhash input
// (getFormhash's goquery scope) — e.g. in DebugLog:
// doc.Find("input[name='formhash']").Each(func(i int, s *goquery.Selection) {
// fmt.Println("formhash:", s.AttrOr("value", ""))
// })
if err != nil { /* handle fetch failure */ } Type guard
func hasFormhash(doc *goquery.Document) bool {
return doc.Find("input[name='formhash']").Length() > 0
} Try / catch
formhash, err := plugin.GetFormhash(ctx)
if err != nil {
if strings.Contains(err.Error(), "未找到formhash值") {
// page shape changed or was a block page — refresh cookies/headers and retry once
return plugin.GetFormhash(ctx)
}
return err
} Prevention
- Send realistic browser User-Agent and Referer headers to avoid block pages
- Log the raw HTML when formhash is empty to diagnose markup drift
- Periodically re-verify the site's search page structure
- Handle login-walls/captchas explicitly instead of blind retries
When it happens
Trigger: The GET request for the search page returned a login page, captcha page, Cloudflare challenge, or error page instead of the normal page containing <input name="formhash">; or the site's markup changed so the goquery selector no longer matches.
Common situations: Site is blocking the plugin's default User-Agent/headers; the target site changed its HTML template; the server redirected to an anti-bot interstitial; the site requires cookies/login to render the search form.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/27271fd33cf5b14b.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/qupanshe/qupanshe.go:211
// 查找formhash
formhash := ""
inputCount := doc.Find("input[name='formhash']").Length()
if DebugLog {
fmt.Printf("[qupanshe] 找到input[name='formhash']元素数量: %d\n", inputCount)
}
doc.Find("input[name='formhash']").Each(func(i int, s *goquery.Selection) {
if value, exists := s.Attr("value"); exists && value != "" {
formhash = value
if DebugLog {
fmt.Printf("[qupanshe] 找到formhash[%d]: %s\n", i, value)
}
}
})
if formhash == "" {
return "", fmt.Errorf("未找到formhash值")
}
return formhash, nil
}
// postSearchRequest 发送POST请求获取搜索结果URL
func (p *QupanshePlugin) postSearchRequest(client *http.Client, keyword, formhash string) (string, error) {
// 添加延时,避免请求过快
time.Sleep(2 * time.Second)
// 构建POST请求
searchURL := fmt.Sprintf("%s/search.php?mod=forum", BaseURL)
data := url.Values{}
data.Set("formhash", formhash)
data.Set("srchtxt", keyword)
data.Set("searchsubmit", "yes")
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)View on GitHub (pinned to beaa561337)