- flaresolverr.py: refactor stateless (create_session/destroy_session/get) L'ancienne approche warmup→cookies→requests était bloquée par Cloudflare (JA3 TLS fingerprinting). Toutes les requêtes passent maintenant via une session Chrome persistante FlareSolverr. - ma_http.py: MASession utilise les sessions FS persistantes. Ajout de _extract_json (html.unescape + extraction <pre>) et _build_url. Gestion du refresh sur 403/429 avec recréation de session. - db.py: ajout du champ data JSONB dans upsert_bands INSERT+ON CONFLICT. Avant ce fix, l'URL n'était jamais stockée → get_bands_to_enrich retournait toujours 0 résultats → enrichissement mort. - scraper_band.py: schéma band_page aligné sur l'historique DB (lineup structuré avec URLs artistes, discography_url, lyrical_themes, location, info_raw). Ajout de "Themes" dans _pick pour couvrir les deux variantes de clé HTML (MA utilise parfois "Themes", parfois "Lyrical themes"). - 005_fix_checkpoints_and_data.sql: renomme last_additions_check → last_created_check (clé morte vs clé utilisée par le code). Backfill enriched=true + colonnes top-level (formed_year, themes, status, location_text) depuis band_page JSONB pour les 85k bands de l'ancien scraper. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
47 lines
2.1 KiB
SQL
47 lines
2.1 KiB
SQL
-- 005: corriger les checkpoints + backfill enriched depuis les données de l'ancien scraper
|
|
|
|
-- 1. Renommer la clé checkpoint morte 'last_additions_check' → 'last_created_check'
|
|
-- (le code utilise last_{order_by}_check donc 'last_created_check', pas 'last_additions_check')
|
|
INSERT INTO crawl_checkpoint (key, value)
|
|
VALUES ('last_created_check', NULL)
|
|
ON CONFLICT (key) DO NOTHING;
|
|
|
|
DELETE FROM crawl_checkpoint WHERE key = 'last_additions_check';
|
|
|
|
-- 2. Backfill depuis les données de l'ancien scraper :
|
|
-- 85 829 bands ont data->'band_page' rempli mais enriched=false et colonnes top-level vides.
|
|
-- On remplit les colonnes à partir du JSONB existant.
|
|
UPDATE bands SET
|
|
enriched = true,
|
|
status = COALESCE(
|
|
NULLIF(trim(status), ''),
|
|
data->'band_page'->>'status'
|
|
),
|
|
genre = COALESCE(
|
|
NULLIF(trim(genre), ''),
|
|
data->'band_page'->>'genre',
|
|
data->'band_page'->'info_raw'->>'genre'
|
|
),
|
|
themes = COALESCE(
|
|
NULLIF(trim(themes), ''),
|
|
NULLIF(data->'band_page'->>'lyrical_themes', 'N/A'),
|
|
NULLIF(data->'band_page'->'info_raw'->>'themes', 'N/A')
|
|
),
|
|
formed_year = COALESCE(
|
|
formed_year,
|
|
CASE
|
|
WHEN (data->'band_page'->>'formed_in') ~ '^\d{4}$'
|
|
THEN (data->'band_page'->>'formed_in')::int
|
|
WHEN (data->'band_page'->>'formed_in') IS NOT NULL
|
|
THEN (regexp_match(data->'band_page'->>'formed_in', '\d{4}'))[1]::int
|
|
WHEN (data->'band_page'->'info_raw'->>'formed in') IS NOT NULL
|
|
THEN (regexp_match(data->'band_page'->'info_raw'->>'formed in', '\d{4}'))[1]::int
|
|
ELSE NULL
|
|
END
|
|
),
|
|
location_text = COALESCE(
|
|
NULLIF(trim(location_text), ''),
|
|
data->'band_page'->>'location',
|
|
data->'band_page'->'info_raw'->>'location'
|
|
)
|
|
WHERE data->'band_page' IS NOT NULL;
|