fish2018/pansou · error
[ ] 请求搜索页面失败
Error message
[%s] 请求搜索页面失败: %w
What it means
Returned by doSearch in the aikanzy plugin when the retrying HTTP client (p.doRequestWithRetry) fails to send the search request at all — no response was obtained. All underlying transport errors (connection refused, DNS, timeout, TLS) are wrapped here with the plugin name prefix.
Solutions
- Unwrap the error to identify the transport cause (timeout vs connection refused vs TLS).
- Confirm the site's current domain is correct and reachable (curl -v).
- Increase defaultTimeout if requests time out on slow connections.
- Add or update a proxy configuration if the site is blocked in your network.
- If TLS errors occur, verify system CA certificates are up to date.
Example fix
// before
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 请求搜索页面失败: %w", p.Name(), err)
}
// after
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
return nil, fmt.Errorf("[%s] search request timed out (increase defaultTimeout or use proxy): %w", p.Name(), err)
}
return nil, fmt.Errorf("[%s] 请求搜索页面失败: %w", p.Name(), err)
} Defensive patterns
Strategy: retry
Validate before calling
// preflight check before searching
resp, err := http.Head(baseURL)
if err != nil {
return fmt.Errorf("source site unreachable: %w", err)
}
resp.Body.Close() Try / catch
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
var dnsErr *net.DNSError
if errors.As(err, &dnsErr) {
// wrong/dead domain — refresh base URL
}
if errors.Is(err, context.DeadlineExceeded) {
// timeout — raise timeout or add proxy, then retry
}
return err
} Prevention
- Set explicit connect/request timeouts instead of relying on defaults.
- Monitor source-site reachability and update domains promptly.
- Use exponential backoff with jitter between retry attempts.
- Configure a proxy for networks that block the source site.
When it happens
Trigger: After the request is built with browser-like headers, p.doRequestWithRetry(req, client) exhausts its attempts because client.Do returns an error each time (site unreachable, TLS handshake failure, context deadline exceeded from defaultTimeout).
Common situations: The aikanzy site is down or its domain has changed; corporate firewall/GFW blocks the site; the per-request context times out on slow links; TLS certificate mismatch after the site migrates hosts.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/bbadd356a079e3ca.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/aikanzy/aikanzy.go:162
// 创建请求
req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
if err != nil {
return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
}
// 设置完整的请求头(避免反爬虫)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Referer", "https://www.aikanzy.com/")
req.Header.Set("Upgrade-Insecure-Requests", "1")
req.Header.Set("Cache-Control", "max-age=0")
// 使用带重试的请求方法发送HTTP请求
resp, err := p.doRequestWithRetry(req, client)
if err != nil {
return nil, fmt.Errorf("[%s] 请求搜索页面失败: %w", p.Name(), err)
}
defer resp.Body.Close()
// 检查状态码
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("[%s] 请求搜索页面失败,状态码: %d", p.Name(), resp.StatusCode)
}
// 使用goquery解析HTML
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return nil, fmt.Errorf("[%s] 解析HTML失败: %w", p.Name(), err)
}
// 解析搜索结果列表
articleItems := p.parseArticleList(doc)
if len(articleItems) == 0 {
return []model.SearchResult{}, nilView on GitHub (pinned to beaa561337)