{"record":{"id":"16146476f57ae40a","repo":"fish2018/pansou","slug":"parse-html-failed-w","errorCode":null,"errorMessage":"parse html failed: %w","messagePattern":"parse html failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"plugin/yunso/yunso.go","lineNumber":199,"sourceCode":"\t\treturn nil, fmt.Errorf(\"read response failed: %w\", err)\n\t}\n\n\tvar apiResp YunsoAPIResponse\n\tif err := jsonutil.Unmarshal(body, &apiResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"decode response failed: %w\", err)\n\t}\n\n\tif apiResp.Code != 0 {\n\t\treturn nil, fmt.Errorf(\"api returned error: %s\", apiResp.Msg)\n\t}\n\n\treturn p.parseItems(apiResp.Data)\n}\n\nfunc (p *YunsoAsyncPlugin) parseItems(fragment string) ([]YunsoItem, error) {\n\tdoc, err := goquery.NewDocumentFromReader(strings.NewReader(`<div id=\"yunso-root\">` + fragment + `</div>`))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parse html failed: %w\", err)\n\t}\n\n\titems := make([]YunsoItem, 0, 16)\n\tdoc.Find(\"div.layui-card[data-qid]\").Each(func(_ int, card *goquery.Selection) {\n\t\tanchor := card.Find(`a[onclick*=\"open_sid\"]`).First()\n\t\tif anchor.Length() == 0 {\n\t\t\treturn\n\t\t}\n\n\t\ttitle := cleanYunsoText(anchor.Text())\n\t\tif title == \"\" {\n\t\t\treturn\n\t\t}\n\n\t\tencryptedURL, _ := anchor.Attr(\"url\")\n\t\tdecryptedURL := \"\"\n\t\tif encryptedURL != \"\" {\n\t\t\tif decoded, err := decryptYunsoURL(encryptedURL); err == nil {","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/fish2018/pansou/blob/beaa56133755a548ebc51b090b3816e2ae044aa6/plugin/yunso/yunso.go#L181-L217","documentation":"parseItems failed to parse the API-provided HTML fragment with goquery. goquery (via go-htmltransform/html parsing) rarely errors, so this usually indicates nil input or a parser-level failure; more practically it signals the fragment could not be turned into a queryable document for extracting div.layui-card results.","triggerScenarios":"goquery.NewDocumentFromReader errors when parsing `<div id=\"yunso-root\">` + fragment + `</div>` — e.g. apiResp.Data is empty or the fragment is not HTML as expected.","commonSituations":"The yunso API changed its result format (no longer HTML fragments), Data is empty/null for queries with no hits, or malformed HTML causes the underlying parser to fail.","solutions":["Log the fragment before parsing to confirm it contains expected markup","Guard against empty apiResp.Data before parsing and return an empty result instead","Update selectors if the site changed its markup (div.layui-card, a[onclick*=open_sid])","Verify the goquery/html parser dependency versions are healthy"],"exampleFix":"// before\ndoc, err := goquery.NewDocumentFromReader(strings.NewReader(`<div id=\"yunso-root\">` + fragment + `</div>`))\nif err != nil {\n    return nil, fmt.Errorf(\"parse html failed: %w\", err)\n}\n// after\nif strings.TrimSpace(fragment) == \"\" {\n    return []YunsoItem{}, nil\n}\ndoc, err := goquery.NewDocumentFromReader(strings.NewReader(`<div id=\"yunso-root\">` + fragment + `</div>`))\nif err != nil {\n    return nil, fmt.Errorf(\"parse html failed: %w\", err)\n}","handlingStrategy":"fallback","validationCode":"if strings.TrimSpace(fragment) == \"\" {\n    return []YunsoItem{}, nil\n}\nif !strings.Contains(fragment, \"layui-card\") {\n    log.Warn(\"yunso fragment missing expected markup\")\n}","typeGuard":"func hasExpectedMarkup(fragment string) bool {\n    return strings.Contains(fragment, \"layui-card\") && strings.Contains(fragment, \"data-qid\")\n}","tryCatchPattern":"items, err := parseItems(fragment)\nif err != nil {\n    log.Warn(\"yunso parse failed, returning empty\", \"err\", err)\n    items = []YunsoItem{}\n}","preventionTips":["Short-circuit on empty fragments before parsing","Alert when selectors match zero cards — it usually means markup changed","Pin goquery versions and test parsing against recorded fixtures"],"tags":["html","parsing","goquery","scraping"],"backgroundTag":"unexpected-response-shape","analyzedSha":"beaa56133755a548ebc51b090b3816e2ae044aa6","analyzedAt":"2026-09-07T00:31:18.025Z","contentChangedAt":"2026-09-07T00:31:18.025Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}