fish2018/pansou · warning
[ ] 解析详情页失败
Error message
[%s] 解析详情页失败: %w
What it means
parseDetail hands the fetched HTML body to goquery.NewDocumentFromReader. goquery only errors when the underlying XML/HTML parser fails, which is rare; this error wraps that parser failure with the plugin name prefix. It means the document could not be constructed at all.
Solutions
- Verify the body passed to parseDetail is non-empty and is actually HTML (log a snippet on error)
- Since goquery tolerates most malformed HTML, check for a goquery/x-net-html version issue and update dependencies
- Rely on getDetailInfo's fallback: it continues to the next candidate URL, so ensure candidate list covers alternates
Defensive patterns
Strategy: try-catch
Try / catch
info, err := plugin.GetDetailInfo(ctx, url)
if err != nil && strings.Contains(err.Error(), "解析详情页失败") {
log.Printf("goquery parse failed for %s: %v", url, err)
return detailInfo{} // degrade gracefully; getDetailInfo already tries alternate URLs
} Prevention
- Keep goquery and golang.org/x/net updated
- getDetailInfo already falls back to other candidate URLs — ensure candidate lists are populated
- Log body snippets when parsing fails to detect non-HTML responses
When it happens
Trigger: goquery.NewDocumentFromReader(strings.NewReader(body)) returns a non-nil error inside parseDetail, called from getDetailInfo after a successful fetch of a detail candidate URL.
Common situations: Practically triggered by an empty or nil reader state rather than truly invalid HTML (goquery's parser is lenient); a body containing extremely malformed content in strict parsing configurations.
Related errors
AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07).
Data as JSON: /api/errors/baa4b2abeed32cc5.
Report an issue: GitHub.
Appendix: source
Thrown at plugin/qiwei/qiwei.go:420
if isVerifyPage(string(responseBody)) {
return fmt.Errorf("站点未接受验证参数")
}
return nil
}
func md5StringToHex(value string) string {
var builder strings.Builder
for _, r := range value {
builder.WriteString(fmt.Sprintf("%d", r+1))
}
sum := md5.Sum([]byte(builder.String()))
return hex.EncodeToString(sum[:])
}
func (p *QiweiPlugin) parseDetail(detailURL, body, fallbackTitle, fallbackPic string) (detailInfo, error) {
doc, err := goquery.NewDocumentFromReader(strings.NewReader(body))
if err != nil {
return detailInfo{}, fmt.Errorf("[%s] 解析详情页失败: %w", p.Name(), err)
}
title := cleanText(doc.Find(".main-ui-meta h1").First().Text())
title = yearSuffixRegex.ReplaceAllString(title, "")
if title == "" {
title = fallbackTitle
}
cover := normalizeURL(detailURL, attrOrEmpty(doc.Find(`meta[property="og:image"]`).First(), "content"))
if cover == "" {
cover = normalizeURL(detailURL, attrOrEmpty(doc.Find(".main-left .img img").First(), "src"))
}
if cover == "" {
cover = fallbackPic
}
contentParts := make([]string, 0, 3)
if meta := cleanText(doc.Find(".main-ui-meta .otherbox").First().Text()); meta != "" {View on GitHub (pinned to beaa561337)