MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / parseDuckDuckGoHtml

Function parseDuckDuckGoHtml

src/tools/web/parse.ts:59–82  ·  view source on GitHub ↗
(html: string, limit: number)

Source from the content-addressed store, hash-verified

57
58/** Parse DuckDuckGo's main HTML results page (result__a / result__snippet). */
59export function parseDuckDuckGoHtml(html: string, limit: number): WebSearchResult[] {
60 const results: WebSearchResult[] = [];
61 const titleRegex = /<a[^>]*class="[^"]*\bresult__a\b[^"]*"[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/g;
62 const snippetRegex = /<a[^>]*class="[^"]*\bresult__snippet\b[^"]*"[^>]*>([\s\S]*?)<\/a>/g;
63
64 const titles: Array<{ href: string; text: string; offset: number }> = [];
65 for (const m of html.matchAll(titleRegex)) {
66 titles.push({ href: unwrapDdgRedirect(m[1] ?? ''), text: stripTags(m[2] ?? ''), offset: m.index ?? 0 });
67 }
68 const snippets: Array<{ text: string; offset: number }> = [];
69 for (const m of html.matchAll(snippetRegex)) {
70 snippets.push({ text: stripTags(m[1] ?? ''), offset: m.index ?? 0 });
71 }
72
73 let sIdx = 0;
74 for (const t of titles) {
75 if (results.length >= limit) break;
76 while (sIdx < snippets.length && snippets[sIdx]!.offset < t.offset) sIdx++;
77 const snippetText = sIdx < snippets.length ? snippets[sIdx]!.text : '';
78 if (!t.href || !t.text) continue;
79 results.push({ title: t.text, url: t.href, snippet: snippetText });
80 }
81 return results;
82}
83
84/** Parse the lite.duckduckgo.com/lite/ table-based results page (result-link / result-snippet). */
85export function parseDuckDuckGoLiteHtml(html: string, limit: number): WebSearchResult[] {

Callers 2

web-search.test.tsFile · 0.85

Calls 3

unwrapDdgRedirectFunction · 0.85
stripTagsFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected