fish2018/pansou · error

未获取到重定向URL,状态码

Error message

未获取到重定向URL,状态码: %d

What it means

postSearchRequest expects the server to respond with a redirect (Location header) to the search results page. It collects the Location through the CheckRedirect callback; if the response ended with a non-redirect status and no Location was captured, it fails with this error including the final status code. It means the site's response shape did not match the expected redirect flow.

Solutions

  1. Enable DebugLog to dump the final status code and response body to see what the server actually returned
  2. Check whether the formhash (from getFormhash) was valid — an invalid token often causes a non-redirect response
  3. Handle 200 responses by parsing results directly if the site no longer redirects
  4. Update the expected redirect logic to the site's current behavior
  5. Look for rate-limiting/captcha pages in the body and add backoff

Example fix

// before
if location == "" {
    return "", fmt.Errorf("未获取到重定向URL,状态码: %d", resp.StatusCode)
}
// after
if location == "" {
    if resp.StatusCode == http.StatusOK {
        return p.parseInlineResults(resp.Body) // site may now return results directly
    }
    return "", fmt.Errorf("未获取到重定向URL,状态码: %d", resp.StatusCode)
}
Defensive patterns

Strategy: fallback

Validate before calling

// After the POST, verify a redirect actually occurred before expecting Location:
// resp.StatusCode must be 301/302/303/307/308 for a Location to exist
if resp.StatusCode >= 300 && resp.StatusCode < 400 && resp.Header.Get("Location") == "" {
    return fmt.Errorf("redirect without Location: %d", resp.StatusCode)
}

Try / catch

_, err := plugin.Search(ctx, kw)
if err != nil && strings.Contains(err.Error(), "未获取到重定向URL") {
    // dump the response body via DebugLog and fall back to inline parsing or abort
}

Prevention

When it happens

Trigger: The POST returned 200 (results inline or an error page), 4xx/5xx, or a login/captcha page instead of a 3xx redirect; the site removed the POST→redirect pattern; formhash was wrong causing the server to re-render the form.

Common situations: Target site redesigned its search endpoint; anti-bot protection returns 200 with a challenge; expired/invalid formhash; site rate-limits and returns 403/429 without redirect.

Related errors


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

Appendix: source

Thrown at plugin/qupanshe/qupanshe.go:302

	if DebugLog {
		fmt.Printf("[qupanshe] Location header: %s\n", location)
	}

	// 读取响应体用于调试(非重定向状态码时)
	if resp.StatusCode != 302 && resp.StatusCode != 301 && DebugLog {
		body, readErr := io.ReadAll(resp.Body)
		if readErr == nil {
			bodyStr := string(body)
			if len(bodyStr) > 1000 {
				fmt.Printf("[qupanshe] 响应体(前1000字符): %s\n", bodyStr[:1000])
			} else {
				fmt.Printf("[qupanshe] 响应体: %s\n", bodyStr)
			}
		}
	}

	if location == "" {
		return "", fmt.Errorf("未获取到重定向URL,状态码: %d", resp.StatusCode)
	}

	// 将相对路径转换为完整URL
	fullURL := BaseURL + "/" + strings.TrimPrefix(location, "/")

	return fullURL, nil
}

// getSearchResults 获取搜索结果
func (p *QupanshePlugin) getSearchResults(client *http.Client, searchURL, keyword string) ([]model.SearchResult, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

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

View on GitHub (pinned to beaa561337)