fish2018/pansou · error

[ ] 请求搜索页面失败,状态码

Error message

[%s] 请求搜索页面失败,状态码: %d

What it means

Returned by doSearch in the aikanzy plugin when the HTTP response status code is anything other than 200 OK. The body is not parsed; the actual status code is interpolated into the message. It signals the site responded but rejected or redirected the request (anti-bot, rate limit, moved page).

Solutions

  1. Log the status code and read a snippet of resp.Body to see whether it's Cloudflare, a redirect page, or 404.
  2. Update the User-Agent and headers to a current browser fingerprint (Chrome/91 is outdated and often blocked).
  3. Check if the site's search URL path changed and update baseURL/path construction.
  4. Back off and retry with jitter on 429/503 instead of hammering.
  5. Update the plugin to the site's new domain or a mirror if the site moved.

Example fix

// before
if resp.StatusCode != http.StatusOK {
	return nil, fmt.Errorf("[%s] 请求搜索页面失败,状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != http.StatusOK {
	body, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
	return nil, fmt.Errorf("[%s] 请求搜索页面失败,状态码: %d, body: %s", p.Name(), resp.StatusCode, string(body))
}
Defensive patterns

Strategy: fallback

Try / catch

if resp.StatusCode != http.StatusOK {
	switch {
	case resp.StatusCode == http.StatusTooManyRequests:
		// honor Retry-After header, then retry
	case resp.StatusCode == http.StatusForbidden:
		// refresh headers/cookies or rotate User-Agent
	default:
		return fmt.Errorf("unexpected status %d", resp.StatusCode)
	}
}

Prevention

When it happens

Trigger: p.doRequestWithRetry succeeds (a response was received) but resp.StatusCode != http.StatusOK — e.g. 403 from Cloudflare/anti-bot protection, 429 rate limit, 404 because the search URL path changed, or 301/302 not followed.

Common situations: The site enabled stricter anti-bot measures and rejects the hardcoded Chrome/91 User-Agent; search path/format changed after a site update; too many requests triggered rate limiting; the site moved to a new domain.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/7aa5118b9256cb87. Report an issue: GitHub.

Appendix: source

Thrown at plugin/aikanzy/aikanzy.go:168

	// 设置完整的请求头(避免反爬虫)
	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{}, nil
	}
	
	// 并发抓取详情页获取网盘链接
	results := p.fetchDetailsWithLinks(articleItems, client, keyword)
	
	// 使用过滤功能过滤结果

View on GitHub (pinned to beaa561337)