fish2018/pansou · error

[ ] 请求返回状态码

Error message

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

What it means

CldiPlugin.searchPage returns this when the search endpoint responds with a status code other than 200. It reports the plugin name and the actual code but discards the response body, so the reason (block page, rate-limit notice, server error) is not visible. It indicates an upstream/API-level rejection rather than a transport failure.

Solutions

  1. Read and log a snippet of resp.Body before returning so the actual rejection reason is visible.
  2. If 429, reduce request rate or honor Retry-After; add backoff in doRequestWithRetry.
  3. If 403, refresh headers (User-Agent, Referer, cookies) via setRequestHeaders to mimic a real browser.
  4. Confirm the endpoint path is still valid on the live site.

Example fix

// before
if resp.StatusCode != 200 {
    return nil, fmt.Errorf("[%s] 请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode != 200 {
    snippet, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
    return nil, fmt.Errorf("[%s] 请求返回状态码: %d, body: %s", p.Name(), resp.StatusCode, snippet)
}
Defensive patterns

Strategy: fallback

Try / catch

results, err := plugin.Search(ctx, keyword)
if err != nil {
    if m := regexp.MustCompile(`状态码: (\d+)`).FindStringSubmatch(err.Error()); m != nil {
        switch m[1] {
        case "429":
            // back off / slow down request rate
        case "403", "404":
            // endpoint blocked or moved: switch to fallback source
        }
    }
}

Prevention

When it happens

Trigger: resp.StatusCode != 200 after doRequestWithRetry succeeds in searchPage — e.g. 403 from anti-bot WAF, 429 rate limit, 503 maintenance, or a changed endpoint returning 404.

Common situations: Scraping too aggressively triggering rate limits, IP banned by the site, site redesign moving the endpoint, or missing/rotated cookies and User-Agent headers.

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/4d5c81e1a3bd5cc3. Report an issue: GitHub.

Appendix: source

Thrown at plugin/cldi/cldi.go:151

	// 创建请求
	req, err := http.NewRequestWithContext(ctx, "GET", searchURL, nil)
	if err != nil {
		return nil, fmt.Errorf("[%s] 创建请求失败: %w", p.Name(), err)
	}

	// 设置请求头
	p.setRequestHeaders(req)

	// 发送请求
	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)
	}

	// 读取响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("[%s] 读取响应失败: %w", p.Name(), err)
	}

	// 解析HTML
	doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(body)))
	if err != nil {
		return nil, fmt.Errorf("[%s] HTML解析失败: %w", p.Name(), err)
	}

	// 提取搜索结果
	return p.extractSearchResults(doc), nil
}

View on GitHub (pinned to beaa561337)