Stellen Sie sich vor, Sie wachen jeden Morgen auf und finden eine Datenbank voller aktueller Nachrichtenartikel, bereits bereinigt, strukturiert und bereit zur Analyse. Kein manuelles Durchsuchen, kein Kopieren und Einfügen, keine Formatierungsprobleme. Nur frische Daten, die auf Sie warten.
Genau das haben wir gebaut: einen universellen Nachrichtenscraper, der auf praktisch jeder Nachrichtenwebsite funktioniert, natürliche Sprachdaten in jedem Format versteht, automatisch Paginierungslinks entdeckt, stoppt, wenn er die Artikel von gestern erreicht, und alles ordentlich in einer lokalen SQLite-Datenbank speichert.
Der entscheidende Einblick ist die Nutzung von KI nicht als Chatbot, sondern als intelligentes Parsing-Engine. Anstatt fragile CSS-Selektoren zu schreiben, die jedes Mal brechen, wenn eine Seite neu gestaltet wird, lassen wir Gemini die Seite wie ein Mensch lesen und das Wesentliche extrahieren.
Architekturübersicht
Das System besteht aus drei Komponenten, die lokal auf Ihrem Rechner laufen:
Proxy-Server (Port 3001) — Ein Node.js HTTP-Server mit zwei Endpunkten. Der /fetch-Endpunkt lädt jede URL herunter, entfernt Skripte und Stile, bewahrt strukturelle HTML-Tags, extrahiert Paginierungslinks aus rohem HTML vor der Kürzung und gibt sauberen, strukturierten Inhalt zurück. Der /ai-Endpunkt empfängt Seiteninhalte und eine Eingabeaufforderung, sendet sie an die Gemini-API mit automatischem Wiederholungsversuch bei Rate-Limit-Fehlern und gibt die Antwort des Modells zurück.
Scraper-Skript — Ein Node.js-Skript, das alles orchestriert. Es läuft in zwei Phasen: Phase 1 sammelt alle Artikellinks von Listen-Seiten, indem es automatisch der Paginierung folgt, Phase 2 besucht jede Artikel-URL, extrahiert den vollständigen Inhalt über Gemini und speichert ihn in der Datenbank.
SQLite-Datenbank — Eine lokale Ein-Datei-Datenbank, die Artikel mit Feldern für URL (einzigartig, verhindert Duplikate), Titel, Inhalt, Datum, Quelle und Erstellungszeitstempel speichert.
[Jede Nachrichtenwebsite]
↓ HTTP-Abruf (browserähnliche Header)
[Proxy-Server — server.js :3001]
↓ sauberes HTML + Paginierungslink
[Gemini 2.5 Flash Lite API]
↓ strukturiertes JSON
[scrape.js]
↓ INSERT OR IGNORE
[news.db — SQLite]
Warum Gemini und nicht ein lokales Modell?
Wir haben lokale Modelle (Llama 3.2, Mistral 7B über Ollama) für diese Aufgabe getestet. Die Ergebnisse waren enttäuschend — kleine Modelle, die auf der CPU laufen, sind zu langsam, um Hunderte von Seiten zu verarbeiten, sie halluzinieren Paginierungslinks, die nicht existieren, und sie haben Schwierigkeiten, den Hauptinhalt von Seitenleisten-Widgets zu unterscheiden, wenn die Seitenstruktur komplex ist.
Gemini 2.5 Flash Lite löst all diese Probleme. Es verarbeitet eine vollständig bereinigte Seite in 1–2 Sekunden, identifiziert Artikel-Daten korrekt in jeder Sprache und jedem Format, versteht die semantische HTML-Struktur und kostet praktisch nichts — ungefähr €0,55 pro 200 Artikel.
Schritt 1: Holen Sie sich Ihren Gemini-API-Schlüssel
Gehen Sie zu aistudio.google.com/api-keys und erstellen Sie einen neuen Schlüssel. Die kostenlose Stufe bietet 20 Anfragen pro Minute, was für die Entwicklung ausreicht. Für das Scraping in der Produktion fügen Sie eine Zahlungsmethode hinzu — kostet ungefähr €0,25 pro Monat bei typischer täglicher Nutzung.
Fügen Sie Ihren Schlüssel in server.js in Zeile 10 ein:
const GEMINI_KEY = 'your_key_here';
Schritt 2: Der Proxy-Server (server.js)
Der Proxy-Server ist das Herzstück des Systems. Seine wichtigste Aufgabe ist das Extrahieren des nächsten Seitenlinks bevor HTML-Attribute entfernt werden — ein subtiler, aber wichtiger Punkt.
Wenn wir HTML bereinigen, entfernen wir Attribute wie rel="next" und aria-label, um die Inhaltsgröße für die KI zu reduzieren. Aber genau diese Attribute identifizieren den Paginierungslink. Daher rufen wir extractNextPage() zuerst auf rohem HTML auf und bereinigen dann alles andere.
Die Funktion sucht nach drei Mustern, die die überwiegende Mehrheit der Nachrichtenseiten abdecken:
rel="next"— das Standard-HTML5-Paginierungsattributaria-labelenthält “next”, “далі”, “вперед”, “следующая”- Elemente mit der Klasse
is-next— häufig in CSS-Frameworks
// server.js
// [VOLLSTÄNDIGEN server.js CODE HIER EINFÜGEN]
Die cleanHtml()-Funktion behält strukturelle Tags (<main>, <article>, <section>, <aside>, <nav>, <time datetime>) bei, während alles andere entfernt wird. Dies gibt Gemini genug Kontext, um den Hauptinhalt von Seitenleisten zu unterscheiden, ohne Megabytes an rohem HTML zu verarbeiten.
Die askGemini()-Funktion liest die tatsächliche Wartezeit aus der Rate-Limit-Fehlerantwort von Gemini (retry in 23.9s) und wartet genau so lange, bevor sie es erneut versucht. Kein Raten, keine festen Verzögerungen.
Schritt 3: Abhängigkeiten installieren und den Server ausführen
cd your-project-folder
npm install better-sqlite3
node server.js
Sie sollten sehen:
Server läuft unter http://localhost:3001
Testen Sie es, indem Sie diese URL in Ihrem Browser öffnen:
http://localhost:3001/fetch?url=https://example.com
Sie erhalten eine JSON-Antwort mit den Feldern text, links und nextPage.
Schritt 4: Intelligente Paginierungsentdeckung
Der Scraper hat niemals eine fest codierte Liste von Seiten-URLs. Er beginnt mit einer URL und folgt automatisch dem “nächste Seite”-Link auf jeder Seite.
Verschiedene Seiten verwenden völlig unterschiedliche Paginierungsmuster:
https://site.com/news/page/2— WordPress-Stilhttps://site.com/news/page-2— Bindestrich-Trenner (TSN.ua als Beispiel für den Artikel)https://site.com/news?page=2— Abfrageparameterhttps://site.com/news-2.html— flacher HTML-Stil
Der Proxy behandelt alle, weil er nach semantischen Attributen im HTML sucht, nicht nach URL-Mustern. Der Scraper liest einfach pageData.nextPage aus der Proxy-Antwort und folgt ihm blind.
Schritt 5: KI-gestützte Datumsfilterung
Hier zeigt sich der Ansatz wirklich überlegen gegenüber traditionellen Scrapers. Nachrichtenseiten zeigen Daten in völlig unterschiedlichen Formaten an:
<time datetime="2026-04-21T17:30:00+03:00">— Standard-HTML521 квітня 2026— Ukrainische LangformСьогодні, 17:30— “Heute” auf Ukrainisch- Nur
17:30— nur Zeit, was heute impliziert
Ein traditioneller Scraper würde für jedes Format auf jeder Seite eine benutzerdefinierte Parsing-Logik benötigen. Wir sagen Gemini einfach das heutige Datum und bitten es zu filtern:
Heute ist der 2026-04-21.
Extrahiere Nachrichtenartikellinks aus dem HAUPTINHALTSBEREICH, die NUR HEUTE veröffentlicht wurden.
Daten können in jedem Format vorliegen: <time datetime>, "21.04.26", "17:30" (nur Zeit = heute), "сьогодні", etc.
AUSSCHLIESSEN: Seitenleisten, "читайте також", Werbung, Navigation, Kategorie-/Tag-/Autorenseiten.
Setze "stop": true, wenn du Artikel von GESTERN oder früher im Hauptinhalt siehst.
Gib NUR gültiges JSON zurück:
{"articles":[{"title":"...","url":"https://..."}],"stop":false,"reason":"..."}
Das stop-Flag ist der Schlüsselmechanismus. Wenn Gemini Artikel von gestern im Hauptinhalt sieht, gibt es "stop": true zurück und der Scraper hört auf, der Paginierung zu folgen — egal auf welcher Seitennummer wir uns befinden.
Schritt 6: Artikelinhaltsextraktion
Phase 2 besucht jede Artikel-URL und extrahiert den tatsächlichen Inhalt. Die Eingabeaufforderung ist bewusst minimal:
Extrahiere das Folgende von dieser Nachrichtenartikel-Seite:
1. "title" — die Artikelüberschrift
2. "date" — Veröffentlichungsdatum im Format JJJJ-MM-TT
3. "content" — vollständiger Artikeltext, sauber, keine Werbung oder Navigation
Gib NUR gültiges JSON zurück, ohne Erklärung, ohne Markdown, ohne Text davor oder danach:
{"title":"...","date":"2026-04-21","content":"..."}
Beachten Sie, dass es kein Zusammenfassungsfeld gibt. Es ist verlockend, Zusammenfassungen beim Scraping zu generieren, aber es verschwendet Tokens und Zeit für etwas, das Sie möglicherweise nie verwenden. Speichern Sie jetzt den Rohinhalt, generieren Sie Zusammenfassungen bei Bedarf, wenn Sie sie tatsächlich für die Analyse benötigen.
Schritt 7: Das Scraper-Skript (scrape.js)
// scrape.js
// [VOLLSTÄNDIGEN scrape.js CODE HIER EINFÜGEN]
Die INSERT OR IGNORE-SQL-Anweisung in Kombination mit der UNIQUE-Einschränkung auf der url-Spalte behandelt alle Duplikate automatisch. Führen Sie den Scraper jede Stunde aus — er überspringt stillschweigend jeden Artikel, der bereits in der Datenbank ist.
Ausführen
Sie benötigen zwei Terminalfenster:
Terminal 1 — Proxy-Server (weiterlaufen lassen):
node server.js
Terminal 2 — Scraper (ausführen, wenn Sie frische Artikel möchten):
node scrape.js
Um eine andere Nachrichtenwebsite zu scrapen, ändern Sie nur eine Zeile oben in scrape.js:
const START = 'https://your-news-site.com/news';
Ergebnisse
Ausführung gegen TSN.ua (große ukrainische Nachrichtenwebsite, als Beispiel für den Artikel) am 21. April 2026:
- Phase 1: 198 Artikellinks von 20 Seiten gesammelt — automatisch gestoppt, als Artikel von gestern erschienen
- Phase 2: 198 Artikel abgerufen, bereinigt und gespeichert
- Gesamtzeit: ~11 Minuten
- Gesamtkosten: €0,55 in Gemini-API-Guthaben
- Datenbankgröße: ~8MB
Der Scraper ignorierte korrekt Seitenleisten-Widgets mit alten beliebten Artikeln, Horoskopen, Wettervorhersagen und Währungsseiten. Nur tatsächlich an diesem Tag veröffentlichte Nachrichtenartikel gelangten in die Datenbank.
Die Datenbank anzeigen
Laden Sie DB Browser for SQLite herunter — kostenlos, Open Source. Öffnen Sie news.db und Sie sehen alle Artikel in einer tabellenähnlichen Ansicht. Sie können nach Datum filtern, Inhalte durchsuchen, in CSV exportieren.
Was kommt als Nächstes
WordPress-Autoveröffentlichung — ein Skript, das aus der Datenbank liest und über die REST-API auf WordPress veröffentlicht. In Kombination mit Claude, der Inhalte auf Spanisch, Deutsch oder Polnisch umschreibt, wird dies zu einer vollständig automatisierten mehrsprachigen Nachrichtenwebsite.
Mehrere Quellen — derselbe Server und Scraper funktionieren auf jeder Nachrichtenwebsite. BBC, Reuters, TechCrunch, regionale Seiten in jeder Sprache — eine Codebasis behandelt sie alle.
Geplante Ausführung — fügen Sie einen Windows-Task-Scheduler-Job oder Linux-Cron hinzu, um node scrape.js jeden Morgen auszuführen. Wachen Sie mit einer vollständigen Datenbank der heutigen Nachrichten auf.
Analyseebene — ein zweites Skript liest die heutigen Artikel aus SQLite, sendet sie an die Claude-API und generiert ein Morgenbriefing: Schlüsselgeschichten, Trends, Implikationen. Die Datenbank wird zu einem Informationsfeed.
In einem Tag gebaut mit Node.js 23, Gemini 2.5 Flash Lite und better-sqlite3. Der schwierigste Teil war die Entdeckung, dass Paginierungslinks verschwinden, wenn Sie HTML-Attribute entfernen — weshalb extractNextPage() auf rohem HTML ausgeführt werden muss, bevor eine Bereinigung erfolgt.
Quellcode herunterladen
- Quellen — Proxy-Server mit Gemini-Integration + zweiphasiger Scraper mit SQLite-Speicherung