fish2018/pansou · error

未找到JS文件

Error message

未找到JS文件

What it means

The homepage was fetched successfully (HTTP 200, body read), but the regular expression `<script src="(/_next/static/[^"]+\.js)"` found no matches in the HTML. The discovery step depends on Next.js static script tags being present in the raw HTML; their absence means the page structure changed, the page is a client-rendered shell, or an anti-bot interstitial was served instead of the real homepage.

Solutions

  1. Dump the fetched HTML (log string(body)) and inspect what actually came back — determine whether it's a challenge page or a restructured app shell.
  2. Relax/update the regex: allow absolute URLs and other attribute orders, e.g. `<script[^>]+src="[^"]*?/_next/static/[^"]+\.js"`.
  3. If scripts are runtime-injected, fetch the build manifest directly (/_next/static/<buildId>/_buildManifest.js) or the __NEXT_DATA__ JSON instead of scraping script tags.
  4. Check whether the site changed frameworks entirely and update the discovery strategy in findPotentialActionIDs.
  5. Ensure an anti-bot challenge isn't the cause — a 200 HTML page containing 'cf-challenge' or similar means you need a browser-like fetch, not a regex change.

Example fix

// before
jsRegex := regexp.MustCompile(`<script src="(/_next/static/[^"]+\.js)"`)
// after — tolerate absolute URLs and attribute order
jsRegex := regexp.MustCompile(`<script[^>]+src="([^"]*?/_next/static/[^"]+\.js)"`)
Defensive patterns

Strategy: fallback

Type guard

func looksLikeAppHTML(body []byte) bool {
    s := string(body)
    if strings.Contains(s, "cf-challenge") || strings.Contains(s, "Just a moment") {
        return false // anti-bot interstitial
    }
    return strings.Contains(s, "_next/static") || strings.Contains(s, "__NEXT_DATA__")
}

Try / catch

ids, err := findPotentialActionIDs(client, homeURL)
if err != nil {
    if err.Error() == "未找到JS文件" {
        // fallback: fetch the Next.js build manifest instead
        return findActionIDsFromBuildManifest(client, homeURL)
    }
    return nil, err
}

Prevention

When it happens

Trigger: jsRegex.FindAllStringSubmatch returns zero matches on the fetched homepage HTML inside findPotentialActionIDs — page no longer uses the expected <script src="/_next/static/*.js"> tags, or the response is a challenge/consent page rather than the app HTML.

Common situations: The site upgraded Next.js or switched frameworks so scripts moved to different paths or are injected at runtime; Cloudflare served a challenge page with 200 OK; the site now renders via SSR streaming without those exact tags; regex broke due to attribute order/quotes changing (e.g. src="https://cdn.../_next/static/...").

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at plugin/panyq/panyq.go:687

		if err != nil {
			// 如果连响应体都读取失败,则返回状态码错误并附上读取错误
			return nil, fmt.Errorf("请求失败,状态码: %d,且读取响应体错误: %v", resp.StatusCode, err)
		}
		// 将更详细的状态信息 (如 "404 Not Found") 和响应体内容一起作为错误返回
		return nil, fmt.Errorf("请求失败,状态: %s, 详情: %s", resp.Status, string(bodyBytes))
	}

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %w", err)
	}
	
	// 提取JS文件路径
	jsRegex := regexp.MustCompile(`<script src="(/_next/static/[^"]+\.js)"`)
	matches := jsRegex.FindAllStringSubmatch(string(body), -1)
	
	if len(matches) == 0 {
		return nil, fmt.Errorf("未找到JS文件")
	}
	
	// 收集所有潜在的Action ID
	idSet := make(map[string]struct{})
	idRegex := regexp.MustCompile(`["\']([a-f0-9]{40})["\']{1}`)
	
	for _, match := range matches {
		jsURL := BaseURL + match[1]
		
		// 创建JS文件请求
		jsReq, err := http.NewRequest("GET", jsURL, nil)
		if err != nil {
			continue
		}
		
		// 设置JS文件请求头,保持与首页请求一致
		jsReq.Header.Set("Referer", BaseURL)
		jsReq.Header.Set("Origin", BaseURL)

View on GitHub (pinned to beaa561337)