fish2018/pansou · error

导出cookie失败

Error message

导出cookie失败: %w

What it means

Final login step: after collecting anti-bot cookies via a detail-page GET, gying calls p.exportCookies(scraper, p.getBaseURL()) to serialize the scraper's cookie jar into a cookie string for the site's base URL. If extraction fails (reflection into the scraper's internal http.Client cookie jar fails, or the jar is missing/empty in an unexpected way), the error is wrapped as '导出cookie失败: %w' and login aborts even though authentication itself succeeded.

Solutions

  1. Pin/align the cloudscraper version with what the plugin's exportCookies reflection expects — this error most often follows an upstream upgrade.
  2. Check DebugLog output before this point: if step 3 (detail page) showed no Set-Cookie headers, the jar may be empty; verify the detail-page GET succeeded.
  3. Verify p.getBaseURL() returns a valid URL; cookie extraction scoped to a bad domain can fail or return nothing.
  4. As a workaround, use the Set-Cookie headers already captured in cookieMap during steps 1–3 instead of jar export, then update the plugin properly.

Example fix

// before
require cloudscraper v1.2.3
// after
pin the version the plugin was built against:
require cloudscraper v1.1.2  // matches exportCookies' reflection layout
Defensive patterns

Strategy: try-catch

Try / catch

res, err := gyingLogin(ctx, creds)
if err != nil {
    if strings.Contains(err.Error(), "导出cookie失败") {
        // auth succeeded but cookie export failed: pin cloudscraper version,
        // or fall back to Set-Cookie headers captured during the login steps
        log.Printf("cookie export failed: %v", err)
        return fallbackToCapturedSetCookies(headers)
    }
    return err
}

Prevention

When it happens

Trigger: Calling gying login when exportCookies cannot read the cookies from the scraper — internal cookie-jar structure changed in a cloudscraper upgrade, or the jar is nil/uninitialized.

Common situations: Cloudscraper dependency upgraded so the plugin's reflection-based cookie-jar access no longer matches internal types; a code path where the scraper was constructed with a custom client lacking the expected jar; nil base URL causing cookie-domain matching to fail.

Related errors


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

Appendix: source

Thrown at plugin/gying/gying.go:2234

	// ========== 步骤3: GET详情页 (触发防爬cookies如vrg_sc、vrg_go等) ==========
	if DebugLog {
		fmt.Printf("[Gying] 步骤3: GET详情页收集完整Cookie\n")
	}

	_, warmupStatus, warmupHeaders, err := p.requestWithChallengeRetry(scraper, http.MethodGet, p.getWarmupDetailURL(), "", "")
	if err == nil {
		if DebugLog {
			fmt.Printf("[Gying] 详情页状态码: %d\n", warmupStatus)
		}
		// 从详情页响应中收集cookies
		collectSetCookies(warmupHeaders, cookieMap)
		logSetCookiesForDebug(warmupHeaders, "[Gying]   详情页Cookie: %s=%s\n", 30)
	}

	// 构建cookie字符串
	cookieStr, err := p.exportCookies(scraper, p.getBaseURL())
	if err != nil {
		return nil, "", fmt.Errorf("导出cookie失败: %w", err)
	}
	cookieMap = parseCookieString(cookieStr)

	if DebugLog {
		fmt.Printf("[Gying] ✅ 登录成功!提取到 %d 个Cookie\n", len(cookieMap))
		fmt.Printf("[Gying] Cookie字符串长度: %d\n", len(cookieStr))
		for name, value := range cookieMap {
			displayValue := value
			if len(displayValue) > 30 {
				displayValue = displayValue[:30] + "..."
			}
			fmt.Printf("[Gying]   %s=%s (len:%d)\n", name, displayValue, len(value))
		}
		fmt.Printf("[Gying] ========== 登录完成 ==========\n")
	}

	return scraper, cookieStr, nil
}

View on GitHub (pinned to beaa561337)