fish2018/pansou · error

详情页请求返回状态码

Error message

详情页请求返回状态码: %d

What it means

Status error in pianku's fetchDetailPageLinks (plugin/pianku/pianku.go:399): a result's detail page returned a non-200 status. The search listing succeeded but this specific detail fetch was rejected (rate limit or removed page).

Solutions

  1. Log the failing URL and status; on 404 treat the detail page as gone and skip it.
  2. Add exponential backoff between detail-page requests and honor Retry-After on 429/503 to avoid rate limiting.
  3. Send realistic browser headers (setRequestHeaders) including a current User-Agent and Referer to bypass simple bot checks.
  4. For 403 with Cloudflare, consider a cookie/session bootstrap or reduce request concurrency.

Example fix

// before
if resp.StatusCode != 200 {
    return nil, fmt.Errorf("详情页请求返回状态码: %d", resp.StatusCode)
}
// after
if resp.StatusCode == http.StatusNotFound {
    return nil, nil // dead link, skip
}
if resp.StatusCode != 200 {
    return nil, fmt.Errorf("详情页请求返回状态码: %d (url=%s)", resp.StatusCode, detailURL)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// probe the URL before extraction and treat 4xx as expected
resp, err := client.Head(detailURL)
if err == nil && (resp.StatusCode == 404 || resp.StatusCode == 410) {
    return // dead link, skip
}

Type guard

func isNotFoundStatus(err error) bool {
    return err != nil && strings.Contains(err.Error(), "状态码: 404")
}

Try / catch

results, err := plugin.Search(keyword)
if err != nil && strings.Contains(err.Error(), "详情页请求返回状态码") {
    if strings.Contains(err.Error(), ": 429") {
        time.Sleep(30 * time.Second) // honor rate limit then retry
    } else {
        return fallbackResults, nil
    }
}

Prevention

When it happens

Trigger: p.doRequestWithRetry succeeded (transport OK) but resp.StatusCode != 200 — e.g. 403/429 from anti-bot, 404 from a dead link, or 5xx from the site while searchImpl was processing detail pages.

Common situations: 详情页防盗链触发;帖子已删除。

Related errors


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

Appendix: source

Thrown at plugin/pianku/pianku.go:399

	// 创建请求
	req, err := http.NewRequestWithContext(ctx, "GET", detailURL, nil)
	if err != nil {
		return nil, fmt.Errorf("创建详情页请求失败: %w", err)
	}
	
	// 设置请求头
	p.setRequestHeaders(req)
	
	// 发送HTTP请求
	resp, err := p.doRequestWithRetry(req, client)
	if err != nil {
		return nil, fmt.Errorf("详情页请求失败: %w", err)
	}
	defer resp.Body.Close()
	
	// 检查状态码
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("详情页请求返回状态码: %d", resp.StatusCode)
	}
	
	// 解析HTML
	doc, err := goquery.NewDocumentFromReader(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("详情页HTML解析失败: %w", err)
	}
	
	// 提取下载链接
	return p.extractDownloadLinks(doc), nil
}

// extractDownloadLinks 提取详情页中的下载链接
func (p *PiankuPlugin) extractDownloadLinks(doc *goquery.Document) []model.Link {
	var links []model.Link
	seenURLs := make(map[string]bool) // 用于去重
	
	// 查找下载链接区域

View on GitHub (pinned to beaa561337)