package bing import ( "github.com/PuerkitoBio/goquery" "github.com/go-rod/rod" "github.com/karust/openserp/core" ) func extractBingFeatures(doc *goquery.Document) []core.SerpFeature { features := core.ExtractSerpFeaturesBySelectors(doc, []core.SerpFeatureSelector{ { Type: core.ResultTypeAnswerBox, // Only treat a b_ans block as an answer box when it carries an // actual answer/entity payload. A bare li.b_ans also wraps related // modules ("Searches you might like", "Get a detailed look at ..."), // so require a focus/fact/xl text node to be present. Container: []string{"li.b_ans:has(.b_focusTextLarge)", "li.b_ans:has(.b_focusLabel)", "li.b_ans:has(.b_xlText)", "li.b_ans:has(.b_factrow)"}, TitleSelector: []string{".b_focusLabel", "h2"}, TextSelector: []string{".b_focusTextLarge", ".b_xlText", ".b_vPanel .b_factrow", ".b_caption p"}, LinkSelector: []string{"a[href^='http']"}, Position: 1, Confidence: 0.8, }, { Type: core.ResultTypeRelatedQuestions, Title: "People also ask", Container: []string{".b_rrsr", ".rqnaacfacc", "li.b_ans:has(.df_alaskcr)"}, ItemSelector: []string{".df_qntext", ".rqnaacfacc a", "li a"}, LinkSelector: []string{"a[href^='http']"}, Confidence: 0.7, }, { Type: core.ResultTypeRelatedSearches, Title: "Related searches", Container: []string{"#brsv3", "li.b_rs", "ol#b_rs"}, ItemSelector: []string{"li a", "a"}, LinkSelector: []string{"a[href^='http']", "a"}, Confidence: 0.75, }, { // Bing's "developer answer" / rich answer card is AI-generated // ("This summary was generated using AI based on multiple online // sources"). Title sits in h2.b_topTitle; cited sources are the // numbered superscript anchors. Copilot chat (#b_sydConvCont) is kept // as a fallback for SERPs that render the chat answer inline instead. Type: core.ResultTypeAISummary, Title: "AI answer", Container: []string{".developer_answercard_wrapper", "#b_sydConvCont", ".b_sydConvCont", "[data-testid='bing-chat-answer']"}, TitleSelector: []string{"h2.b_topTitle", ".b_sydAns"}, // The full generated answer lives in .devmag_card_content, split across // many
/