fish2018/pansou · error

[ ] 搜索请求返回状态码

Error message

[%s] 搜索请求返回状态码: %d

What it means

The huban plugin's searchAtBase method performs an HTTP search request and requires HTTP 200. Any other status code (403, 429, 500, etc.) aborts the search and returns this error, prefixed with the plugin name.

Solutions

  1. Log resp.StatusCode and inspect response headers/body (via a debug wrapper) to identify blocking (403/429/5xx)
  2. Slow down request rate / add backoff to avoid 429 rate limiting
  3. Rotate proxies or User-Agent to evade bot detection
  4. Check if the huban site is reachable in a browser; if it moved or changed protection, update the plugin's request headers or URL
  5. Surface the error to the user as a transient upstream failure and retry later

Example fix

// before
if resp.StatusCode != 200 {
	return nil, fmt.Errorf("[%s] 搜索请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != 200 {
	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: retry

Validate before calling

resp, err := http.Head(searchURL)
if err != nil || resp.StatusCode != 200 {
	// upstream unhealthy; skip or delay the search
}

Try / catch

results, err := plugin.Search(keyword)
if err != nil {
	if strings.Contains(err.Error(), "搜索请求返回状态码") {
		// extract status, back off or fail over to another plugin
		log.Printf("upstream non-200: %v", err)
		return partialResults, nil
	}
	return nil, err
}

Prevention

When it happens

Trigger: p.searchAtBase executes doRequestWithRetry (which itself retries non-200 responses) and the final response still has StatusCode != 200; e.g. the huban site returns 403 due to bot detection/Cloudflare, 429 rate limiting, or 5xx site outage.

Common situations: Target site blocking datacenter IPs or non-browser User-Agents, being rate-limited after heavy scraping, huban site temporarily down or moved behind anti-bot protection, expired cookies/TLS fingerprint rejected.

Related errors


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

Appendix: source

Thrown at plugin/huban/huban.go:269

		return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
	}

	// 4. 设置请求头
	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", strings.TrimRight(baseURL, "/")+"/")

	// 5. 发送请求
	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 != 200 {
		return nil, fmt.Errorf("[%s] 搜索请求返回状态码: %d", p.Name(), resp.StatusCode)
	}

	// 6. 解析搜索结果页面
	doc, err := goquery.NewDocumentFromReader(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("[%s] 解析搜索页面失败: %w", p.Name(), err)
	}

	// 7. 提取搜索结果
	var results []model.SearchResult

	doc.Find(".module-search-item").Each(func(i int, s *goquery.Selection) {
		result := p.parseSearchItem(s, keyword)
		if result.UniqueID != "" {
			results = append(results, result)
		}
	})

View on GitHub (pinned to beaa561337)