fish2018/pansou · error
解析搜索数据失败
Error message
解析搜索数据失败: %w
What it means
Wraps a json.Unmarshal failure while parsing the extracted _obj.search JSON (matches[1]) into the SearchData struct. The regex found candidate JSON but its content is not valid JSON or does not fit SearchData's expected shape (e.g. type mismatch on Q/N fields).
Solutions
- Inspect the wrapped %w error and the raw JSON printed under DebugLog to see the exact mismatch.
- Update the SearchData struct to match the site's current field names/types (use json.RawMessage or flexible types).
- Tighten or update searchDataPattern so it captures only the complete JSON object.
- Check the site for a frontend/API update and adjust the parser accordingly.
Example fix
// before
type SearchData struct {
N string `json:"n"`
}
// after — tolerate number-or-string count
type SearchData struct {
N json.Number `json:"n"`
} Defensive patterns
Strategy: try-catch
Validate before calling
if len(matches) < 2 || !json.Valid(matches[1]) {
return errors.New("extracted search JSON is not valid")
} Try / catch
var searchData SearchData
if err := json.Unmarshal(matches[1], &searchData); err != nil {
var ute *json.UnmarshalTypeError
if errors.As(err, &ute) {
// field type changed upstream: log field and raw payload for triage
log.Printf("field %s type mismatch, raw: %s", ute.Field, matches[1])
}
return err
} Prevention
- Use tolerant types (json.Number, json.RawMessage) for fields prone to type changes.
- Keep the extraction regex tight so it captures only complete JSON.
- Snapshot known-good page payloads and diff them after site updates.
When it happens
Trigger: searchWithScraper extracts matches[1] from the page and json.Unmarshal returns an error: malformed/truncated JSON in the page, JSON field types changed (e.g. N became a number instead of string), or the regex captured the wrong span of text.
Common situations: Site update changed the embedded JSON structure or field types; greedy/lazy regex captured trailing HTML; page truncated mid-JSON due to response size limits or proxy issues.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/501e521f35b1f067.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/gying/gying.go:2523
}
return nil, fmt.Errorf("未找到搜索结果数据")
}
if DebugLog {
jsonStr := string(matches[1])
if len(jsonStr) > 200 {
jsonStr = jsonStr[:200] + "..."
}
fmt.Printf("[Gying] 提取的JSON数据: %s\n", jsonStr)
}
var searchData SearchData
if err := json.Unmarshal(matches[1], &searchData); err != nil {
if DebugLog {
fmt.Printf("[Gying] JSON解析失败: %v\n", err)
fmt.Printf("[Gying] 原始JSON: %s\n", string(matches[1]))
}
return nil, fmt.Errorf("解析搜索数据失败: %w", err)
}
if DebugLog {
fmt.Printf("[Gying] 搜索数据解析成功:\n")
fmt.Printf("[Gying] - 关键词: %s\n", searchData.Q)
fmt.Printf("[Gying] - 结果数量字符串: %s\n", searchData.N)
fmt.Printf("[Gying] - 资源ID数组长度: %d\n", len(searchData.L.I))
fmt.Printf("[Gying] - 标题数组长度: %d\n", len(searchData.L.Title))
if len(searchData.L.I) > 0 {
fmt.Printf("[Gying] - 前3个资源ID: %v\n", searchData.L.I[:min(3, len(searchData.L.I))])
fmt.Printf("[Gying] - 前3个标题: %v\n", searchData.L.Title[:min(3, len(searchData.L.Title))])
}
}
// 3. 刷新防爬cookies(关键!访问详情页触发vrg_sc、vrg_go等防爬cookies)
if DebugLog {
fmt.Printf("[Gying] 刷新防爬cookies...\n")
}View on GitHub (pinned to beaa561337)