Add startup.si scraper
startup.si has no public jobs API or feed, so parse the listing page. It lists every posting since 2019 on one page, so only postings from the last 90 days are kept. Also decode common named HTML entities (š, ž, č, dashes, quotes) case-sensitively. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,8 @@ export async function fetchHtml(url: string): Promise<string> {
|
||||
|
||||
const NAMED_ENTITIES: Record<string, string> = {
|
||||
amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: " ", raquo: "»", laquo: "«",
|
||||
scaron: "š", Scaron: "Š", zcaron: "ž", Zcaron: "Ž", ccaron: "č", Ccaron: "Č",
|
||||
ndash: "–", mdash: "—", lsquo: "‘", rsquo: "’", ldquo: "“", rdquo: "”", bdquo: "„", hellip: "…",
|
||||
};
|
||||
|
||||
/** Decode HTML entities (HTMLRewriter text chunks are not decoded). */
|
||||
@@ -38,7 +40,7 @@ export function decodeEntities(s: string): string {
|
||||
const code = e[1] === "x" || e[1] === "X" ? parseInt(e.slice(2), 16) : parseInt(e.slice(1), 10);
|
||||
return Number.isFinite(code) ? String.fromCodePoint(code) : m;
|
||||
}
|
||||
return NAMED_ENTITIES[e.toLowerCase()] ?? m;
|
||||
return NAMED_ENTITIES[e] ?? NAMED_ENTITIES[e.toLowerCase()] ?? m;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user