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

Function parseDuckDuckGoLiteHtml

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

Source from the content-addressed store, hash-verified

83
84/** Parse the lite.duckduckgo.com/lite/ table-based results page (result-link / result-snippet). */
85export function parseDuckDuckGoLiteHtml(html: string, limit: number): WebSearchResult[] {
86 const results: WebSearchResult[] = [];
87 const linkRegex = /<a[^>]*class="[^"]*\bresult-link\b[^"]*"[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/g;
88 const snipRegex = /<td[^>]*class="[^"]*\bresult-snippet\b[^"]*"[^>]*>([\s\S]*?)<\/td>/g;
89
90 const links: Array<{ href: string; text: string; offset: number }> = [];
91 for (const m of html.matchAll(linkRegex)) {
92 links.push({ href: unwrapDdgRedirect(m[1] ?? ''), text: stripTags(m[2] ?? ''), offset: m.index ?? 0 });
93 }
94 const snips: Array<{ text: string; offset: number }> = [];
95 for (const m of html.matchAll(snipRegex)) {
96 snips.push({ text: stripTags(m[1] ?? ''), offset: m.index ?? 0 });
97 }
98
99 let sIdx = 0;
100 for (const l of links) {
101 if (results.length >= limit) break;
102 while (sIdx < snips.length && snips[sIdx]!.offset < l.offset) sIdx++;
103 const snippetText = sIdx < snips.length ? snips[sIdx]!.text : '';
104 if (!l.href || !l.text) continue;
105 results.push({ title: l.text, url: l.href, snippet: snippetText });
106 }
107 return results;
108}
109
110/** Unwrap DuckDuckGo's `//duckduckgo.com/l/?uddg=<encoded>` tracking redirect. */
111export function unwrapDdgRedirect(url: string): string {

Callers 1

Calls 3

unwrapDdgRedirectFunction · 0.85
stripTagsFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected