fish2018/pansou · error
[ ] API 失败且网页搜索没有有效资源 (API: )
Error message
[%s] API 失败且网页搜索没有有效资源 (API: %v)
What it means
After the primary API call failed and the plugin fell back to scraping the web search page, zero parseable results were found. The plugin wraps both failures into this combined error because it has no usable data to return.
Solutions
- Inspect the fallback page HTML and update the plugin's CSS selectors to the current markup.
- Check whether the site serves a captcha/anti-bot page and add proper headers/cookies.
- Retry later or with a different keyword to distinguish 'no results' from a broken scraper.
- Fix the primary API error (apiErr) so the fallback is not required.
Defensive patterns
Strategy: fallback
Validate before calling
// probe the fallback page and count expected selector matches
n := doc.Find("div.result-item").Length()
if n == 0 {
log.Println("fallback page returned no items; markup may have changed")
} Try / catch
results, err := searchImpl(keyword)
if err != nil {
if strings.Contains(err.Error(), "没有有效资源") {
log.Printf("no results and API down: %v", err)
return emptyOrCachedResults()
}
return err
} Prevention
- Pin selector assumptions with a small integration test against live markup
- Distinguish 'genuinely no results' from 'scraping broke' before wrapping the error
- Monitor the API path so the fallback is not the normal code path
- Add headers/cookies to avoid captcha pages returning zero items
When it happens
Trigger: searchWeb: the API errored (apiErr non-nil) AND the DOM selector pass over the fallback HTML matched no result items (len(results) == 0).
Common situations: Site markup changed so the CSS selectors (.bm-file, .ext-meta, etc.) no longer match; the site served a captcha or empty results page; keyword genuinely has no results but is wrapped with the API error.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/d903d8300c828e4c.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/feikuai/feikuai.go:256
title = strings.TrimSpace(item.Find("h4").Text())
}
content := strings.TrimSpace(item.Find(".ext-meta").Text())
add(href, title, content, parseFeikuaiWebTime(content))
})
doc.Find("#panel-bm .bm-item a.module-row-text[href]").Each(func(_ int, item *goquery.Selection) {
if len(results) >= 100 {
return
}
href := item.AttrOr("href", "")
title := strings.TrimSpace(item.AttrOr("title", ""))
if title == "" {
title = strings.TrimSpace(item.Find(".bm-file").Text())
}
content := strings.TrimSpace(item.Find(".ext-meta").Text())
add(href, title, content, parseFeikuaiWebTime(content))
})
if len(results) == 0 {
return nil, fmt.Errorf("[%s] API 失败且网页搜索没有有效资源 (API: %v)", p.Name(), apiErr)
}
return plugin.FilterResultsByKeyword(results, keyword), nil
}
func extractWebPassword(linkURL, content string) string {
if parsed, err := url.Parse(linkURL); err == nil {
if pwd := parsed.Query().Get("pwd"); pwd != "" {
return pwd
}
}
if match := regexp.MustCompile(`(?i)(?:提取码|密码|pwd)[::]?\s*([a-z0-9]{4})`).FindStringSubmatch(content); len(match) > 1 {
return match[1]
}
return ""
}
func parseFeikuaiWebTime(text string) time.Time {
match := regexp.MustCompile(`\d{4}-\d{2}-\d{2}(?:[T ]\d{2}:\d{2}:\d{2})?`).FindString(text)View on GitHub (pinned to beaa561337)