Rohe Feed-Antworten ablegen und Parser erweitern

Der Abruf warf bisher fast alles weg, was im XML stand. Neu ausgewertet
werden Kategorien (<category>, dc:subject, Atom-term), content:encoded
zusaetzlich zur kurzen description, Medien-URLs aus enclosure und Media
RSS, Verweise aus dem Teaser-HTML und die Position im Feed beim ersten
Sehen. Die Kategorien sind fuer Stufe 2 der wertvollste Posten: vom
Verlag selbst vergebene Themenlabel, brauchbar als Vorfilter und als
Prompt-Kontext. Gemessen an zwoelf Quellen tragen 189 von 814 Items
Kategorien, 315 einen laengeren Volltext, 430 Medien.

Ausserdem landen die rohen Antwortbytes gezippt in feed_abrufe,
dedupliziert ueber ihren sha256. Der Parser wird sich weiter aendern;
nur mit den Rohbytes laesst sich eine Verbesserung rueckwirkend auf die
Historie anwenden - dieselbe Ueberlegung wie bei der Trennung von
raw_items und codings. Kompression rund 22 %, etwa 20 kB je Abruf.

Items ohne Titel werden weiter uebersprungen, jetzt aber gezaehlt.

Bestandszeilen bekommen die neuen Felder beim naechsten Lauf nachgetragen,
ohne als Revision zu zaehlen; der Inhalts-Hash bleibt dafuer auf
Titel/Teaser/URL beschraenkt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ZAdZb3EifGb9nvQ5Zp2TE
This commit is contained in:
2026-09-05 18:21:06 +02:00
co-authored by Claude Opus 5
parent 4983662514
commit 5a9bbe6e92
4 changed files with 325 additions and 41 deletions
+38
View File
@@ -50,6 +50,12 @@ create table if not exists raw_items (
abgerufen_am timestamptz not null default now(),
slot timestamptz not null, -- auf den Poll-Takt abgerundet
sprache text not null default 'de',
position integer, -- Rang beim ersten Sehen
volltext text, -- content:encoded, falls zusaetzlich da
kategorien text[], -- <category> / dc:subject / Atom-term
medien jsonb, -- enclosure und Media RSS
links text[], -- Verweise aus dem Teaser-HTML
aktualisiert timestamptz, -- Atom <updated>, neben pubdate
inhalt_hash text not null, -- md5 ueber titel|teaser|url
revisionen integer not null default 0,
zuletzt_geaendert timestamptz,
@@ -58,6 +64,10 @@ create table if not exists raw_items (
unique (quelle, item_key)
);
comment on column raw_items.kategorien is
'Vom Verlag selbst vergebene Themenlabel - Vorfilter und Prompt-Kontext';
comment on column raw_items.position is
'Rang im Feed beim ersten Sehen. Spaeter nicht fortgeschrieben';
comment on column raw_items.revisionen is
'Wie oft die Quelle das Item nach der Erstveroeffentlichung geaendert hat';
@@ -108,6 +118,32 @@ join raw_item_versionen v on v.raw_item_id = r.id
where r.revisionen > 0
group by r.id, r.quelle, r.url, r.revisionen;
-- --------------------------------------------------------------------------
-- Rohe Feed-Antworten. Der Parser wird sich aendern; nur mit den Rohbytes
-- laesst sich eine spaetere Verbesserung rueckwirkend auf die Historie
-- anwenden. Dieselbe Ueberlegung wie bei der Trennung raw_items / codings.
--
-- Dedupliziert ueber (quelle, koerper_hash): ein unveraenderter Feed wird
-- nicht zweimal abgelegt, und ein 304 hat ohnehin keinen Koerper.
-- --------------------------------------------------------------------------
create table if not exists feed_abrufe (
id bigserial primary key,
quelle text not null references quellen(id),
slot timestamptz not null,
abgerufen_am timestamptz not null default now(),
http_status integer,
header jsonb, -- Date, Age, Cache-Control, ...
koerper_hash text not null, -- sha256 ueber die Rohbytes
koerper bytea not null, -- gzip
bytes_roh integer,
bytes_gz integer,
unique (quelle, koerper_hash)
);
create index if not exists feed_abrufe_quelle_idx
on feed_abrufe (quelle, abgerufen_am desc);
-- --------------------------------------------------------------------------
-- Kodierungen. Eine Zeile pro (Item, Kodierer-Version). Die Nutzlast bleibt
-- absichtlich jsonb, solange nicht gemessen ist, bis zu welcher CAMEO-Ebene
@@ -154,6 +190,8 @@ create table if not exists poll_laeufe (
items_gesehen integer not null default 0,
items_neu integer not null default 0,
items_geaendert integer not null default 0,
items_uebersprungen integer not null default 0, -- ohne Titel, unbrauchbar
bytes_roh integer,
fehler text
);