fish2018/pansou · error

[ ] 搜索请求返回状态码

Error message

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

What it means

The duoduo search HTTP request succeeded at the transport level but returned a status code other than 200, so searchImpl rejects the response instead of parsing it. The plugin treats any non-200 as fatal because it expects an HTML search results page. This is an upstream site behavior problem, not a bug in the caller's request.

Solutions

  1. Log resp.StatusCode and the response body snippet to identify whether it's a WAF block, rate limit, or server error.
  2. Rotate/randomize User-Agent and consider cookie handling or a real browser-like header set to pass anti-bot checks.
  3. Back off and retry with exponential delay on 429/5xx instead of failing immediately.
  4. If 403 persists, the site likely blocks non-browser clients — switch data source or use a headless-browser fetch.

Example fix

// before
if resp.StatusCode != 200 {
    return nil, fmt.Errorf("[%s] 搜索请求返回状态码: %d", p.Name(), resp.StatusCode)
}
// after
if resp.StatusCode == 429 || resp.StatusCode >= 500 {
    time.Sleep(retryBackoff)
    // retry once before giving up
} else if resp.StatusCode != 200 {
    return nil, fmt.Errorf("[%s] 搜索请求返回状态码: %d", p.Name(), resp.StatusCode)
}
Defensive patterns

Strategy: retry

Try / catch

if err != nil {
    var statusErr interface{ StatusCode() int }
    // or inspect resp.StatusCode before parsing:
    if resp.StatusCode == 429 {
        time.Sleep(backoff)
        // retry
    } else if resp.StatusCode >= 500 {
        // retry with backoff
    } else {
        // 403/404: likely blocked; disable source or change headers
    }
}

Prevention

When it happens

Trigger: The GET to the search URL returns 403/429/503 etc., typically when anti-bot protection (Cloudflare or similar) blocks the request, the Referer/UA headers are insufficient, or the site is rate-limiting frequent searches.

Common situations: Repeated automated searches trigger rate limiting (429); Cloudflare/WAF challenge page returned (403 or 503); site moved and old URL now redirects to an error page; server temporarily overloaded (5xx).

Related errors


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

Appendix: source

Thrown at plugin/duoduo/duoduo.go:184

	
	// 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("Upgrade-Insecure-Requests", "1")
	req.Header.Set("Cache-Control", "max-age=0")
	req.Header.Set("Referer", "https://tv.yydsys.top/")
	
	// 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)