Vague 3 : Realtor.ca (MLS pan-bannières via Scrapfly ASP), Sotheby's complet (AJAX interne, 60→869), 7 agences source.immo (dont chambre CIEMCQ ~3 900), Guide Habitation (projets neufs)
- realtor_ca.py : rejoue PropertySearch_Post via Scrapfly ASP sans render_js (DataDome contourné) ; 14 shards bbox QC, tri récentes d abord, budget IMMOKA_REALTOR_MAX (défaut 2 000/sync ≈ 10-14 appels) ; external_id = MLS + _ag_ → dédup Centris masque les recoupements (2 145 fiches, 343 uniques). - sothebys_quebec.py : endpoint /include/ajax_results.php débloqué (p_territories[]=4, p_status neutre, remap serveur documenté) ; 869 fiches à vendre au lieu de ~60 ; repli pages région conservé. - agences source.immo : si_ag_ciemcq (Mon-Toit, Estrie-Mauricie-CdQ, 3 920 fiches / 1 169 uniques), avenue, provad, peladeau, ferri, si_ag_jga, si_ag_katiasamson. - guidehabitation.py : répertoire des projets neufs (microdonnées schema.org, 9 régions, 95 projets à vendre, locatifs écartés). - sources.json + source_immo_agencies.json + docs régénérées (50 fiches). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
60 changed files +1,473 −275
modified
data/source_immo_agencies.json
+125 −55
@@ -1,56 +1,126 @@ | ||
| 1 | 1 | [ |
| 2 | − { | |
| 3 | − "id": "realta", | |
| 4 | − "name": "Réalta Agence Immobilière", | |
| 5 | − "domain": "www.realta.ca", | |
| 6 | − "account": "e194f20f-f55f-4667-969a-eaa682cf057e", | |
| 7 | − "api": "68a52c3d-0e3c-46fa-be6a-6a77b53f0941", | |
| 8 | − "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 9 | − "view": "c2c07cb5-2208-4d99-9011-e79f8e126230" | |
| 10 | − }, | |
| 11 | − { | |
| 12 | − "id": "immodev", | |
| 13 | − "name": "Immodev Agence Immobilière", | |
| 14 | − "domain": "www.immodev.ca", | |
| 15 | − "account": "4aabc46f-23a9-4933-8b7e-87fd85c87a18", | |
| 16 | − "api": "b495482c-5c80-4818-b225-ee79817d25db", | |
| 17 | − "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 18 | − "view": "18446f15-3781-487e-8758-58a1b9d53465" | |
| 19 | − }, | |
| 20 | − { | |
| 21 | − "id": "gaillardetz", | |
| 22 | − "name": "Gaillardetz Agence Immobilière", | |
| 23 | − "domain": "www.gaillardetz.ca", | |
| 24 | − "account": "44654d27-d2ef-4362-a408-8e5bc41ba147", | |
| 25 | − "api": "bc1adc4c-f206-4129-b3be-ae8b6206a7c2", | |
| 26 | − "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 27 | − "view": "d5368a27-402b-44b4-9f10-067af7e3f2f2" | |
| 28 | − }, | |
| 29 | − { | |
| 30 | − "id": "domicilia", | |
| 31 | − "name": "Domicilia Agence Immobilière", | |
| 32 | − "domain": "www.domicilia.com", | |
| 33 | − "account": "02f9532b-c512-483a-9354-5ddf9fda8468", | |
| 34 | − "api": "75a0468e-8405-410f-a80a-6ce87a975e80", | |
| 35 | − "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 36 | − "view": "eb448815-be1d-4592-91a5-12908bdc2e24" | |
| 37 | − }, | |
| 38 | − { | |
| 39 | − "id": "niddamour", | |
| 40 | − "name": "Nid d'Amour Agence Immobilière", | |
| 41 | − "domain": "www.niddamour.ca", | |
| 42 | − "account": "08d1a0fd-0673-48d0-bb86-e40fe529bfdb", | |
| 43 | − "api": "80e7941c-66b1-45a0-b6e0-622b401367e0", | |
| 44 | − "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 45 | − "view": "25cb8710-6c99-47ce-b137-8c667b63062c" | |
| 46 | − }, | |
| 47 | − { | |
| 48 | − "id": "si_ag_theagency", | |
| 49 | − "name": "The Agency Montréal", | |
| 50 | − "domain": "theagencymontreal.com", | |
| 51 | − "account": "dcb0f01e-8f29-4347-84f0-170875281872", | |
| 52 | − "api": "2941096d-6a2e-418e-9783-5c3d59790bd0", | |
| 53 | − "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 54 | − "view": "4cf4819e-a0e9-4288-93d2-002cd8f40435" | |
| 55 | − } | |
| 56 | −] | |
| \ No newline at end of file | ||
| 2 | + { | |
| 3 | + "id": "realta", | |
| 4 | + "name": "Réalta Agence Immobilière", | |
| 5 | + "domain": "www.realta.ca", | |
| 6 | + "account": "e194f20f-f55f-4667-969a-eaa682cf057e", | |
| 7 | + "api": "68a52c3d-0e3c-46fa-be6a-6a77b53f0941", | |
| 8 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 9 | + "view": "c2c07cb5-2208-4d99-9011-e79f8e126230" | |
| 10 | + }, | |
| 11 | + { | |
| 12 | + "id": "immodev", | |
| 13 | + "name": "Immodev Agence Immobilière", | |
| 14 | + "domain": "www.immodev.ca", | |
| 15 | + "account": "4aabc46f-23a9-4933-8b7e-87fd85c87a18", | |
| 16 | + "api": "b495482c-5c80-4818-b225-ee79817d25db", | |
| 17 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 18 | + "view": "18446f15-3781-487e-8758-58a1b9d53465" | |
| 19 | + }, | |
| 20 | + { | |
| 21 | + "id": "gaillardetz", | |
| 22 | + "name": "Gaillardetz Agence Immobilière", | |
| 23 | + "domain": "www.gaillardetz.ca", | |
| 24 | + "account": "44654d27-d2ef-4362-a408-8e5bc41ba147", | |
| 25 | + "api": "bc1adc4c-f206-4129-b3be-ae8b6206a7c2", | |
| 26 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 27 | + "view": "d5368a27-402b-44b4-9f10-067af7e3f2f2" | |
| 28 | + }, | |
| 29 | + { | |
| 30 | + "id": "domicilia", | |
| 31 | + "name": "Domicilia Agence Immobilière", | |
| 32 | + "domain": "www.domicilia.com", | |
| 33 | + "account": "02f9532b-c512-483a-9354-5ddf9fda8468", | |
| 34 | + "api": "75a0468e-8405-410f-a80a-6ce87a975e80", | |
| 35 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 36 | + "view": "eb448815-be1d-4592-91a5-12908bdc2e24" | |
| 37 | + }, | |
| 38 | + { | |
| 39 | + "id": "niddamour", | |
| 40 | + "name": "Nid d'Amour Agence Immobilière", | |
| 41 | + "domain": "www.niddamour.ca", | |
| 42 | + "account": "08d1a0fd-0673-48d0-bb86-e40fe529bfdb", | |
| 43 | + "api": "80e7941c-66b1-45a0-b6e0-622b401367e0", | |
| 44 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 45 | + "view": "25cb8710-6c99-47ce-b137-8c667b63062c" | |
| 46 | + }, | |
| 47 | + { | |
| 48 | + "id": "si_ag_theagency", | |
| 49 | + "name": "The Agency Montréal", | |
| 50 | + "domain": "theagencymontreal.com", | |
| 51 | + "account": "dcb0f01e-8f29-4347-84f0-170875281872", | |
| 52 | + "api": "2941096d-6a2e-418e-9783-5c3d59790bd0", | |
| 53 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 54 | + "view": "4cf4819e-a0e9-4288-93d2-002cd8f40435" | |
| 55 | + }, | |
| 56 | + { | |
| 57 | + "id": "si_ag_ciemcq", | |
| 58 | + "name": "Chambre immobilière Estrie–Mauricie–Centre-du-Québec (Mon-Toit)", | |
| 59 | + "domain": "www.mon-toit.net", | |
| 60 | + "account": "e494abe8-cb57-4f96-ad3f-19d3ee9829de", | |
| 61 | + "api": "fe3dbcfd-c48f-4a43-bcad-065f405df0df", | |
| 62 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 63 | + "view": "f05abe23-54e0-4f3b-9ac4-dc686a630818", | |
| 64 | + "note": "Chambre = flux co-listé avec les bannières (≈600 courtiers) → si_ag_ pour la dédup Centris. ~3 900 fiches à vendre (2026-08-18). Config aussi sur ciemcq.com." | |
| 65 | + }, | |
| 66 | + { | |
| 67 | + "id": "avenue", | |
| 68 | + "name": "Avenue Immobilier", | |
| 69 | + "domain": "avenueimmo.com", | |
| 70 | + "account": "abbb1cbd-d342-4ed4-8644-ac50392a8ad0", | |
| 71 | + "api": "96f47605-b917-494c-972d-f5b62e6cea29", | |
| 72 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 73 | + "view": "3f93275f-a8fb-442b-8604-c72e53e86bc2", | |
| 74 | + "note": "Agence indépendante (Brossard). ~42 fiches à vendre (2026-08-18)." | |
| 75 | + }, | |
| 76 | + { | |
| 77 | + "id": "provad", | |
| 78 | + "name": "Proulx Vadnais & Associés", | |
| 79 | + "domain": "provad.ca", | |
| 80 | + "account": "941e16f0-4cb6-413e-b9b1-257657b54717", | |
| 81 | + "api": "d0c3b02c-45e2-4406-94de-aa4be5ad5c3d", | |
| 82 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 83 | + "view": "2cf82736-4de7-44d2-bfa9-126d4874b872", | |
| 84 | + "note": "Agence indépendante commerciale/industrielle (Laval, Rive-Nord). ~80 fiches à vendre (2026-08-18)." | |
| 85 | + }, | |
| 86 | + { | |
| 87 | + "id": "peladeau", | |
| 88 | + "name": "Péladeau Agence Immobilière", | |
| 89 | + "domain": "www.epeladeau.com", | |
| 90 | + "account": "5602193c-a49c-4693-906f-8095cd5d2666", | |
| 91 | + "api": "6f4339b4-a5eb-4826-a98b-a8d3b85bc92b", | |
| 92 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 93 | + "view": "914b348a-48fe-42c5-96a2-52dd5f6c4307", | |
| 94 | + "note": "Agence indépendante. ~47 fiches à vendre (2026-08-18)." | |
| 95 | + }, | |
| 96 | + { | |
| 97 | + "id": "ferri", | |
| 98 | + "name": "Ferri Services Immobiliers", | |
| 99 | + "domain": "www.ferri.ca", | |
| 100 | + "account": "8b83609e-52b5-4955-8322-020d156e9198", | |
| 101 | + "api": "8a1d59c0-282b-43f4-a559-88f942a08036", | |
| 102 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 103 | + "view": "56eb1796-fae8-4ffa-86a3-90a6c59c414f", | |
| 104 | + "note": "Agence indépendante (Laval/Montréal). ~22 fiches à vendre (2026-08-18)." | |
| 105 | + }, | |
| 106 | + { | |
| 107 | + "id": "si_ag_jga", | |
| 108 | + "name": "JGA Équipe Commerciale (Royal LePage)", | |
| 109 | + "domain": "jgacommercial.com", | |
| 110 | + "account": "7d8a1086-f038-436d-ba6c-8fc1a81dc187", | |
| 111 | + "api": "66d60651-2d83-4e82-91cc-b80a0c7e07b1", | |
| 112 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 113 | + "view": "a1f2e4b6-ef44-4d97-a608-3cc9d7762f1f", | |
| 114 | + "note": "Équipe commerciale/industrielle Royal LePage → si_ag_ (co-inscriptions Centris). ~64 fiches à vendre (2026-08-18)." | |
| 115 | + }, | |
| 116 | + { | |
| 117 | + "id": "si_ag_katiasamson", | |
| 118 | + "name": "Katia Samson (RE/MAX L'Espace)", | |
| 119 | + "domain": "www.katiasamson.com", | |
| 120 | + "account": "5cd485f7-9aa3-4d32-a42a-1fbaff506ec7", | |
| 121 | + "api": "ede21420-ea2b-4027-b0eb-bb6d6f2d7446", | |
| 122 | + "app": "ead7575f-8d1c-42e7-9f59-4cf9e065167e", | |
| 123 | + "view": "f0319c2d-b2eb-4328-b32a-f7219f769708", | |
| 124 | + "note": "Équipe RE/MAX L'Espace → si_ag_ (co-inscriptions Centris, remax_ag_lespace couvert). ~30 fiches à vendre (2026-08-18)." | |
| 125 | + } | |
| 126 | +] | |
modified
data/sources.json
+100 −1
@@ -129,7 +129,7 @@ | ||
| 129 | 129 | "connector": "sothebys_quebec", |
| 130 | 130 | "status": "actif", |
| 131 | 131 | "type": "luxe", |
| 132 | − "note": "Recherche rendue côté client. Fiches enumérées via pages de résultats (grid public plafonné ~40 fiches province-wide ; pagination AJAX non exposée en URL). Chaque fiche enrichie via son JSON-LD Product : prix, galerie S3 complète (35-75 photos), description, MLS (sku), type. Limite : couverture = set public courant (~40) ; coverage complète nécessiterait l'endpoint AJAX de pagination." | |
| 132 | + "note": "Inventaire COMPLET via l'API AJAX interne /include/ajax_results.php (dowhat=getgridresults, jeton ajaxtoken de la page province, p_territories[]=4 = Québec, 64 fiches/page). Particularité : les valeurs du filtre statut de l'UI (1=For Sale, 3=For Rent) sont remappées côté serveur — on passe p_status[]=2 (neutre → aucun filtre → tout l'inventaire actif) et on écarte les locations («…/mo») au parsing. ~1 100 fiches QC dont ~965 à vendre (2026-08-18) contre ~40-60 avant (grid public plafonné). Enrichissement JSON-LD Product par fiche : prix, galerie S3 complète, description, MLS (sku). Repli : ancien parcours des pages région." | |
| 133 | 133 | }, |
| 134 | 134 | { |
| 135 | 135 | "id": "profusion", |
@@ -438,6 +438,105 @@ | ||
| 438 | 438 | "status": "actif", |
| 439 | 439 | "type": "franchise", |
| 440 | 440 | "note": "WordPress (MW Properties / marketingwebsites.ca), liste SSR paginée ?pages=N (~9/page, ~11 pages). Carte col-lg-4: no Centris (URL+image+property-meta), région, adresse, ville, prix ($US), chambres/sdb, photo. source_id _ag_ = dédup Centris." |
| 441 | + }, | |
| 442 | + { | |
| 443 | + "id": "realtor_ag_ca", | |
| 444 | + "name": "Realtor.ca (MLS Québec)", | |
| 445 | + "url": "https://www.realtor.ca", | |
| 446 | + "listing_url": "https://www.realtor.ca/map#view=list&Province=QC", | |
| 447 | + "coverage": "Toute la province — agrégateur MLS pan-bannières (SCI/CREA)", | |
| 448 | + "connector": "realtor_ca", | |
| 449 | + "status": "actif", | |
| 450 | + "type": "agrégateur", | |
| 451 | + "note": "API interne api2.realtor.ca/Listing.svc/PropertySearch_Post (POST form). Protégée DataDome/Incapsula : accès direct = 403, mais REJOUABLE via Scrapfly ASP SANS render_js (vérifié 2026-08-18) → JSON riche : MLS, GPS, prix, CAC/SDB, superficie, photos, courtier+agence. 200 fiches/page, plafond serveur 600/recherche → sharding par 14 boîtes lat/lng QC, tri plus récentes d'abord (Sort=6-D). Budget borné IMMOKA_REALTOR_MAX (défaut 2 000 fiches/sync ≈ 10 appels Scrapfly — les ~10 shards les plus denses ; augmenter pour couvrir les régions éloignées ; 0 = désactivé). external_id = n° MLS Centris + infixe _ag_ → la dédup masque tout recoupement avec les connecteurs directs ; seules les fiches des bannières non couvertes restent visibles. Fenêtre glissante : les fiches anciennes sortent du budget au fil des syncs (miss_count → inactif)." | |
| 452 | + }, | |
| 453 | + { | |
| 454 | + "id": "guidehabitation", | |
| 455 | + "name": "Guide Habitation (projets neufs)", | |
| 456 | + "url": "https://www.guidehabitation.ca", | |
| 457 | + "listing_url": "https://www.guidehabitation.ca/fr/projets-immobiliers/montreal/", | |
| 458 | + "coverage": "Québec habité (9 régions) — projets neufs des promoteurs (condos et maisons neuves à vendre)", | |
| 459 | + "connector": "guidehabitation", | |
| 460 | + "status": "actif", | |
| 461 | + "type": "répertoire", | |
| 462 | + "note": "Répertoire de référence des projets neufs. Pages région /fr/projets-immobiliers/{region}/ rendues serveur avec microdonnées schema.org par carte : adresse, ville, GPS, prix « À partir de » (itemprop=price), type, description, chambres, photo. Aucune clé, aucun JS. Projets LOCATIFS écartés (prix mensuel < 50 000 $ ou « locatif » dans le texte). 1 fiche = 1 projet (prix plancher, details.price_from)." | |
| 463 | + }, | |
| 464 | + { | |
| 465 | + "id": "si_ag_ciemcq", | |
| 466 | + "name": "Chambre immobilière Estrie–Mauricie–Centre-du-Québec (Mon-Toit)", | |
| 467 | + "url": "https://www.mon-toit.net", | |
| 468 | + "listing_url": "https://www.mon-toit.net/proprietes/", | |
| 469 | + "coverage": "Estrie, Mauricie, Centre-du-Québec — ~600 courtiers (chambre régionale)", | |
| 470 | + "connector": "si_ag_ciemcq", | |
| 471 | + "status": "actif", | |
| 472 | + "type": "chambre", | |
| 473 | + "note": "Plateforme source.immo (config publique _configs.json sur mon-toit.net et ciemcq.com). ~3 900 fiches à vendre (2026-08-18). Flux co-listé avec les bannières → si_ag_ (dédup Centris). Généré par agences_source_immo.py." | |
| 474 | + }, | |
| 475 | + { | |
| 476 | + "id": "avenue", | |
| 477 | + "name": "Avenue Immobilier", | |
| 478 | + "url": "https://avenueimmo.com", | |
| 479 | + "listing_url": "https://avenueimmo.com/proprietes/", | |
| 480 | + "coverage": "Agence indépendante (Brossard / Rive-Sud)", | |
| 481 | + "connector": "avenue", | |
| 482 | + "status": "actif", | |
| 483 | + "type": "agence", | |
| 484 | + "note": "Plateforme source.immo (API publique, config auto _configs.json). ~42 propriétés à vendre (2026-08-18). Généré par agences_source_immo.py." | |
| 485 | + }, | |
| 486 | + { | |
| 487 | + "id": "provad", | |
| 488 | + "name": "Proulx Vadnais & Associés", | |
| 489 | + "url": "https://provad.ca", | |
| 490 | + "listing_url": "https://provad.ca/nos-proprietes/", | |
| 491 | + "coverage": "Agence indépendante commerciale/industrielle (Laval, Rive-Nord)", | |
| 492 | + "connector": "provad", | |
| 493 | + "status": "actif", | |
| 494 | + "type": "agence", | |
| 495 | + "note": "Plateforme source.immo (API publique, config auto _configs.json). ~80 propriétés à vendre (2026-08-18). Généré par agences_source_immo.py." | |
| 496 | + }, | |
| 497 | + { | |
| 498 | + "id": "peladeau", | |
| 499 | + "name": "Péladeau Agence Immobilière", | |
| 500 | + "url": "https://www.epeladeau.com", | |
| 501 | + "listing_url": "https://www.epeladeau.com/proprietes/", | |
| 502 | + "coverage": "Agence indépendante", | |
| 503 | + "connector": "peladeau", | |
| 504 | + "status": "actif", | |
| 505 | + "type": "agence", | |
| 506 | + "note": "Plateforme source.immo (API publique, config auto _configs.json). ~47 propriétés à vendre (2026-08-18). Généré par agences_source_immo.py." | |
| 507 | + }, | |
| 508 | + { | |
| 509 | + "id": "ferri", | |
| 510 | + "name": "Ferri Services Immobiliers", | |
| 511 | + "url": "https://www.ferri.ca", | |
| 512 | + "listing_url": "https://www.ferri.ca/proprietes/", | |
| 513 | + "coverage": "Agence indépendante (Laval / Montréal)", | |
| 514 | + "connector": "ferri", | |
| 515 | + "status": "actif", | |
| 516 | + "type": "agence", | |
| 517 | + "note": "Plateforme source.immo (API publique, config auto _configs.json). ~22 propriétés à vendre (2026-08-18). Généré par agences_source_immo.py." | |
| 518 | + }, | |
| 519 | + { | |
| 520 | + "id": "si_ag_jga", | |
| 521 | + "name": "JGA Équipe Commerciale (Royal LePage)", | |
| 522 | + "url": "https://jgacommercial.com", | |
| 523 | + "listing_url": "https://jgacommercial.com/proprietes/", | |
| 524 | + "coverage": "Équipe commerciale/industrielle Royal LePage", | |
| 525 | + "connector": "si_ag_jga", | |
| 526 | + "status": "actif", | |
| 527 | + "type": "équipe", | |
| 528 | + "note": "Plateforme source.immo. ~64 fiches à vendre (2026-08-18). Équipe co-listée → si_ag_ (dédup Centris). Généré par agences_source_immo.py." | |
| 529 | + }, | |
| 530 | + { | |
| 531 | + "id": "si_ag_katiasamson", | |
| 532 | + "name": "Katia Samson (RE/MAX L'Espace)", | |
| 533 | + "url": "https://www.katiasamson.com", | |
| 534 | + "listing_url": "https://www.katiasamson.com/proprietes/", | |
| 535 | + "coverage": "Équipe RE/MAX L'Espace (Montréal)", | |
| 536 | + "connector": "si_ag_katiasamson", | |
| 537 | + "status": "actif", | |
| 538 | + "type": "équipe", | |
| 539 | + "note": "Plateforme source.immo. ~30 fiches à vendre (2026-08-18). Équipe co-listée (remax_ag_lespace couvert) → si_ag_ (dédup Centris). Généré par agences_source_immo.py." | |
| 441 | 540 | } |
| 442 | 541 | ] |
| 443 | 542 | } |
modified
docs/connecteurs/INDEX.md
+26 −17
@@ -1,10 +1,10 @@ | ||
| 1 | 1 | # Immo-Ka — Connecteurs (documentation standardisée) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | −**92 connecteurs** enregistrés (auto-découverte `immoka/connectors/__init__.py`) : 41 connecteurs nommés (`data/sources.json`) + 4 familles dynamiques (RE/MAX sous-agences, Via Capitale, Century 21, source.immo). | |
| 5 | +**101 connecteurs** enregistrés (auto-découverte `immoka/connectors/__init__.py`) : 50 connecteurs nommés (`data/sources.json`) + 4 familles dynamiques (RE/MAX sous-agences, Via Capitale, Century 21, source.immo). | |
| 6 | 6 | |
| 7 | −Base vivante `data/immoka.db` : 138 468 annonces, 122 797 actives, 77 668 visibles après dédup (45 129 masquées). | |
| 7 | +Base vivante `data/immoka.db` : 145 724 annonces, 129 862 actives, 79 229 visibles après dédup (50 633 masquées). | |
| 8 | 8 | |
| 9 | 9 | ## Mécanismes transverses (tous connecteurs) |
| 10 | 10 | |
@@ -15,14 +15,14 @@ Base vivante `data/immoka.db` : 138 468 annonces, 122 797 actives, 77 668 visibl | ||
| 15 | 15 | sur plusieurs cycles, tout le parc finit enrichi. |
| 16 | 16 | - **Dédup Centris + adresse** (`immoka/db.py`) : les doublons inter-sources |
| 17 | 17 | (même n° Centris via les sous-agences, ou même adresse normalisée) sont |
| 18 | − marqués `dup_hidden=1` — 45 129 annonces masquées actuellement — et la | |
| 18 | + marqués `dup_hidden=1` — 50 633 annonces masquées actuellement — et la | |
| 19 | 19 | lecture filtre en `AND dup_hidden=0`. |
| 20 | 20 | - **Jointure rôle d'évaluation** (`immoka/vraiprix_local.py`) : appariement |
| 21 | 21 | local FTS par adresse contre `data/vraiprix.db` (3,7 M unités d'évaluation). |
| 22 | 22 | Remplit lat/lng manquants, l'estimation Vrai-Prix (P10-P90 + lien) et les |
| 23 | 23 | champs du rôle (année de construction, superficies, évaluations). Impact : |
| 24 | − **year_built rempli à 67 %** des annonces visibles, dont | |
| 25 | − 71 % proviennent du rôle (`year_built_source: role`). | |
| 24 | + **year_built rempli à 68 %** des annonces visibles, dont | |
| 25 | + 31 % proviennent du rôle (`year_built_source: role`). | |
| 26 | 26 | - **Historique — vagues du 2026-08-18** : |
| 27 | 27 | - `7911d58` Vague 1 : clé Algolia auto-extraite (Barnes), taxes/éval RE/MAX |
| 28 | 28 | (cache détail v4), specs Via Capitale, Kijiji étendu. |
@@ -33,21 +33,21 @@ Base vivante `data/immoka.db` : 138 468 annonces, 122 797 actives, 77 668 visibl | ||
| 33 | 33 | |
| 34 | 34 | | Famille | Fiche | Membres | Visibles | |
| 35 | 35 | |---|---|---|---| |
| 36 | −| Famille RE/MAX sous-agences | [famille-remax-ag](famille-remax-ag.md) | 50 | 3 349 | | |
| 37 | −| Famille Via Capitale agences | [famille-via-ag](famille-via-ag.md) | 4 | 82 | | |
| 36 | +| Famille RE/MAX sous-agences | [famille-remax-ag](famille-remax-ag.md) | 50 | 3 150 | | |
| 37 | +| Famille Via Capitale agences | [famille-via-ag](famille-via-ag.md) | 4 | 50 | | |
| 38 | 38 | | Famille Century 21 | [famille-c21-ag](famille-c21-ag.md) | 2 | 1 576 | |
| 39 | −| Famille source.immo | [famille-source-immo](famille-source-immo.md) | 6 | 1 877 | | |
| 39 | +| Famille source.immo | [famille-source-immo](famille-source-immo.md) | 13 | 3 312 | | |
| 40 | 40 | |
| 41 | 41 | ## Connecteurs nommés |
| 42 | 42 | |
| 43 | 43 | | id | Nom | Type | Statut | Visibles | Année (dont rôle) | Dernier sync | OK | |
| 44 | 44 | |---|---|---|---|---|---|---|---| |
| 45 | −| [`remax_quebec`](remax_quebec.md) | RE/MAX Québec | franchise | actif | 25 348 | 77.0 % | 2026-08-18 01:45 | ✅ | | |
| 45 | +| [`remax_quebec`](remax_quebec.md) | RE/MAX Québec | franchise | actif | 25 348 | 82.8 % | 2026-08-18 05:11 | ✅ | | |
| 46 | 46 | | [`duproprio`](duproprio.md) | DuProprio (sans courtier) | fsbo | actif | 7 393 | 79.3 % | 2026-08-18 02:37 | ✅ | |
| 47 | 47 | | [`kijiji`](kijiji.md) | Kijiji Québec | — | actif | 7 104 | 4.2 % | 2026-08-18 02:59 | ✅ | |
| 48 | 48 | | [`via_capitale`](via_capitale.md) | Via Capitale | franchise | actif | 5 153 | 68.9 % | 2026-08-18 00:27 | ✅ | |
| 49 | 49 | | [`sutton`](sutton.md) | Groupe Sutton Québec | franchise | actif | 4 515 | 65.4 % | 2026-08-18 02:17 | ✅ | |
| 50 | −| [`lespac`](lespac.md) | LesPAC Québec | — | actif | 2 720 | 57.5 % | 2026-08-18 03:10 | ✅ | | |
| 50 | +| [`lespac`](lespac.md) | LesPAC Québec | — | actif | 2 756 | 57.9 % | 2026-08-18 03:10 | ✅ | | |
| 51 | 51 | | [`proprio_direct`](proprio_direct.md) | Proprio Direct | agence | actif | 2 464 | 67.5 % | 2026-08-18 03:14 | ✅ | |
| 52 | 52 | | [`c21_ag_quebec`](c21_ag_quebec.md) | Century 21 Québec (All Quebec) | — | actif | 1 576 | 75.6 % | 2026-08-18 02:35 | ✅ | |
| 53 | 53 | | [`domicilia`](domicilia.md) | Domicilia Agence Immobilière | agence | actif | 1 445 | 73.4 % | 2026-08-18 02:27 | ✅ | |
@@ -55,29 +55,38 @@ Base vivante `data/immoka.db` : 138 468 annonces, 122 797 actives, 77 668 visibl | ||
| 55 | 55 | | [`engel_volkers`](engel_volkers.md) | Engel & Völkers Montréal / Québec | luxe | actif | 1 228 | 69.9 % | 2026-08-18 02:37 | ✅ | |
| 56 | 56 | | [`ubee`](ubee.md) | Ubee | — | actif | 1 176 | 100.0 % | 2026-08-18 00:23 | ✅ | |
| 57 | 57 | | [`vendirect`](vendirect.md) | Vendirect | agence | actif | 1 170 | 79.4 % | 2026-08-18 00:23 | ✅ | |
| 58 | −| [`royal_lepage`](royal_lepage.md) | Royal LePage (Québec) | franchise | actif | 1 009 | 85.7 % | 2026-08-18 02:20 | ✅ | | |
| 58 | +| [`si_ag_ciemcq`](si_ag_ciemcq.md) | Chambre immobilière Estrie–Mauricie–Centre-du-Québec (Mon-Toit) | chambre | actif | 1 169 | 62.8 % | 2026-08-18 05:56 | ✅ | | |
| 59 | +| [`royal_lepage`](royal_lepage.md) | Royal LePage (Québec) | franchise | actif | 1 008 | 89.0 % | 2026-08-18 05:19 | ✅ | | |
| 59 | 60 | | [`exp_ag_qc`](exp_ag_qc.md) | eXp Agence immobilière (Québec) | agence | actif | 888 | 55.6 % | 2026-08-18 02:40 | ✅ | |
| 61 | +| [`sothebys_quebec`](sothebys_quebec.md) | Sotheby's International Realty Québec | luxe | actif | 869 | 3.5 % | 2026-08-18 06:05 | ✅ | | |
| 60 | 62 | | [`charisma_ag_qc`](charisma_ag_qc.md) | Les Immeubles Charisma | agence | actif | 696 | 81.2 % | 2026-08-18 02:37 | ✅ | |
| 61 | 63 | | [`kw_urbain`](kw_urbain.md) | Keller Williams Urbain | franchise | actif | 351 | 68.7 % | 2026-08-18 02:59 | ✅ | |
| 62 | 64 | | [`profusion`](profusion.md) | Profusion Immobilier (Christie's) | luxe | actif | 351 | 61.5 % | 2026-08-18 03:14 | ✅ | |
| 65 | +| [`realtor_ag_ca`](realtor_ag_ca.md) | Realtor.ca (MLS Québec) | agrégateur | actif | 343 | 0.0 % | 2026-08-18 06:06 | ✅ | | |
| 63 | 66 | | [`barnes_quebec`](barnes_quebec.md) | BARNES Québec | luxe | actif | 336 | 81.5 % | 2026-08-18 02:35 | ✅ | |
| 64 | 67 | | [`kw_prestige`](kw_prestige.md) | Keller Williams Prestige | franchise | actif | 277 | 0.0 % | 2026-08-18 02:59 | ✅ | |
| 65 | −| [`si_ag_theagency`](si_ag_theagency.md) | The Agency Montréal | agence | actif | 245 | 88.6 % | 2026-08-18 02:27 | ✅ | | |
| 68 | +| [`si_ag_theagency`](si_ag_theagency.md) | The Agency Montréal | agence | actif | 236 | 90.3 % | 2026-08-18 02:27 | ✅ | | |
| 66 | 69 | | [`glmc_ag_qc`](glmc_ag_qc.md) | Les Immeubles GLMC | agence | actif | 176 | 36.4 % | 2026-08-18 02:40 | ✅ | |
| 67 | 70 | | [`kw_distinction`](kw_distinction.md) | Keller Williams Distinction | franchise | actif | 167 | 0.0 % | 2026-08-18 02:59 | ✅ | |
| 68 | 71 | | [`imcha_ag_qc`](imcha_ag_qc.md) | Les Immeubles Charlevoix | agence | actif | 107 | 0.0 % | 2026-08-18 02:40 | ✅ | |
| 72 | +| [`guidehabitation`](guidehabitation.md) | Guide Habitation (projets neufs) | répertoire | actif | 94 | 0.0 % | 2026-08-18 05:56 | ✅ | | |
| 69 | 73 | | [`immodev`](immodev.md) | Immodev Agence Immobilière | agence | actif | 92 | 64.1 % | 2026-08-18 02:27 | ✅ | |
| 70 | 74 | | [`bhhs_ag_qc`](bhhs_ag_qc.md) | Berkshire Hathaway HomeServices Québec | franchise | actif | 91 | 86.8 % | 2026-08-18 02:35 | ✅ | |
| 71 | 75 | | [`realta`](realta.md) | Réalta Agence Immobilière | agence | actif | 82 | 80.5 % | 2026-08-18 02:27 | ✅ | |
| 76 | +| [`provad`](provad.md) | Proulx Vadnais & Associés | agence | actif | 80 | 41.2 % | 2026-08-18 05:56 | ✅ | | |
| 72 | 77 | | [`image_ag_qc`](image_ag_qc.md) | Image, l'agence immobilière | agence | actif | 77 | 0.0 % | 2026-08-18 02:27 | ✅ | |
| 73 | 78 | | [`m_immobilier`](m_immobilier.md) | M Immobilier | luxe | actif | 67 | 85.1 % | 2026-08-18 03:13 | ✅ | |
| 79 | +| [`si_ag_jga`](si_ag_jga.md) | JGA Équipe Commerciale (Royal LePage) | équipe | actif | 59 | 28.8 % | 2026-08-18 05:56 | ✅ | | |
| 80 | +| [`peladeau`](peladeau.md) | Péladeau Agence Immobilière | agence | actif | 47 | 83.0 % | 2026-08-18 05:56 | ✅ | | |
| 74 | 81 | | [`contact_ag_qc`](contact_ag_qc.md) | Les Immeubles Contact | agence | actif | 43 | 83.7 % | 2026-08-18 02:40 | ✅ | |
| 75 | −| [`sothebys_quebec`](sothebys_quebec.md) | Sotheby's International Realty Québec | luxe | actif | 42 | 71.4 % | 2026-08-18 00:21 | ✅ | | |
| 76 | −| [`via_ag_acces`](via_ag_acces.md) | Via Capitale Acces | franchise | actif | 31 | 96.8 % | 2026-08-18 00:27 | ✅ | | |
| 77 | −| [`via_ag_select`](via_ag_select.md) | Via Capitale Select | franchise | actif | 17 | 100.0 % | 2026-08-18 00:28 | ✅ | | |
| 82 | +| [`avenue`](avenue.md) | Avenue Immobilier | agence | actif | 42 | 95.2 % | 2026-08-18 05:56 | ✅ | | |
| 83 | +| [`si_ag_katiasamson`](si_ag_katiasamson.md) | Katia Samson (RE/MAX L'Espace) | équipe | actif | 25 | 100.0 % | 2026-08-18 05:56 | ✅ | | |
| 84 | +| [`ferri`](ferri.md) | Ferri Services Immobiliers | agence | actif | 22 | 95.5 % | 2026-08-18 05:56 | ✅ | | |
| 85 | +| [`via_ag_select`](via_ag_select.md) | Via Capitale Select | franchise | actif | 13 | 100.0 % | 2026-08-18 00:28 | ✅ | | |
| 78 | 86 | | [`gaillardetz`](gaillardetz.md) | Gaillardetz Agence Immobilière | agence | actif | 13 | 92.3 % | 2026-08-18 02:27 | ✅ | |
| 79 | −| [`via_ag_elite`](via_ag_elite.md) | Via Capitale Elite | franchise | actif | 11 | 81.8 % | 2026-08-18 00:28 | ✅ | | |
| 87 | +| [`via_ag_elite`](via_ag_elite.md) | Via Capitale Elite | franchise | actif | 10 | 80.0 % | 2026-08-18 00:28 | ✅ | | |
| 80 | 88 | | [`expert_immobilier_pm`](expert_immobilier_pm.md) | L'Expert Immobilier P.M. | agence | actif | 9 | 88.9 % | 2026-08-18 02:40 | ✅ | |
| 89 | +| [`via_ag_acces`](via_ag_acces.md) | Via Capitale Acces | franchise | actif | 7 | 100.0 % | 2026-08-18 00:27 | ✅ | | |
| 81 | 90 | | [`century21`](century21.md) | Century 21 (Québec) | franchise | actif | 0 | — | — | — | |
| 82 | 91 | | [`via_ag_dumontroyal`](via_ag_dumontroyal.md) | Via Capitale Dumontroyal | franchise | inactif | 0 | — | 2026-08-18 00:27 | ✅ | |
| 83 | 92 | | [`c21_ag_vision`](c21_ag_vision.md) | Century 21 Vision (Outaouais) | — | actif | 0 | — | 2026-08-18 02:35 | ✅ | |
added
docs/connecteurs/avenue.md
+59 −0
@@ -0,0 +1,59 @@ | ||
| 1 | +# Avenue Immobilier (`avenue`) | |
| 2 | + | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | + | |
| 5 | +## Registre (`data/sources.json`) | |
| 6 | + | |
| 7 | +- **Site** : https://avenueimmo.com | |
| 8 | +- **Recherche** : https://avenueimmo.com/proprietes/ | |
| 9 | +- **Couverture** : Agence indépendante (Brossard / Rive-Sud) | |
| 10 | +- **Type** : agence | |
| 11 | +- **Statut** : actif | |
| 12 | + | |
| 13 | +> Plateforme source.immo (API publique, config auto _configs.json). ~42 propriétés à vendre (2026-08-18). Généré par agences_source_immo.py. | |
| 14 | + | |
| 15 | +## Mécanique (introspection du code) | |
| 16 | + | |
| 17 | +- Module : `immoka/connectors/agences_source_immo.py` — classe `AgenceSIAvenue` | |
| 18 | +- Délai entre requêtes : 0.25 s ; cache détail BD : non | |
| 19 | + | |
| 20 | +**En-tête du module :** | |
| 21 | + | |
| 22 | +> Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 23 | +> Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 24 | +> connectors/agences_source_immo.py : agences INDÉPENDANTES sur la plateforme | |
| 25 | +> source.immo (plugin WordPress). Beaucoup de petites/moyennes agences QC | |
| 26 | +> l'utilisent (liste sur source.immo). Chacune expose sa config publique à | |
| 27 | +> /wp-content/uploads/_sourceimmo/_configs.json → on lit l'API publique | |
| 28 | +> api-v1.source.immo (voir SourceImmoConnector). Ce sont des agences | |
| 29 | +> autonomes : leurs inscriptions (leur propre n° Centris) sont ADDITIVES — | |
| 30 | +> pas de sous-agence d'une bannière déjà couverte → source_id normal (pas _ag_). | |
| 31 | +> EXCEPTION : les équipes/agences dont une partie des inscriptions est | |
| 32 | +> co-listée avec une bannière couverte (co-inscription Centris) portent un id | |
| 33 | +> « si_ag_<slug> » : la dédup Centris (db.refresh_dedup, sources %_ag_%) | |
| 34 | +> masque leurs doublons tout en gardant leurs fiches uniques visibles. | |
| 35 | +> Un connecteur par agence est généré depuis data/source_immo_agencies.json. | |
| 36 | + | |
| 37 | +## Volumétrie & complétude (BD live) | |
| 38 | + | |
| 39 | +| Indicateur | Valeur | | |
| 40 | +|---|---| | |
| 41 | +| Annonces en base (toutes) | 42 | | |
| 42 | +| Actives | 42 | | |
| 43 | +| Visibles (après dédup) | 42 | | |
| 44 | +| Masquées par la dédup | 0 | | |
| 45 | +| GPS (lat/lng) | 100.0 % | | |
| 46 | +| Photos | 100.0 % | | |
| 47 | +| Prix | 100.0 % | | |
| 48 | +| CAC (chambres) | 88.1 % | | |
| 49 | +| SDB (salles de bains) | 88.1 % | | |
| 50 | +| Année de construction | 95.2 % (dont rôle : 0.0 %) | | |
| 51 | +| Taxes / évaluation municipale | 90.5 % | | |
| 52 | +| Estimation Vrai-Prix (rôle) | 0.0 % | | |
| 53 | + | |
| 54 | +## Synchronisation | |
| 55 | + | |
| 56 | +- **Dernier sync** : 2026-08-18 05:56 — trouvé 42, +42 / ~0 / -0 — OK | |
| 57 | +- **Erreurs récentes** : 0 sur les 1 derniers syncs | |
| 58 | + | |
| 59 | +Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). | |
modified
docs/connecteurs/barnes_quebec.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # BARNES Québec (`barnes_quebec`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/bhhs_ag_qc.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Berkshire Hathaway HomeServices Québec (`bhhs_ag_qc`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/c21_ag_quebec.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Century 21 Québec (All Quebec) (`c21_ag_quebec`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/c21_ag_vision.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Century 21 Vision (Outaouais) (`c21_ag_vision`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/century21.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Century 21 (Québec) (`century21`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/charisma_ag_qc.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Les Immeubles Charisma (`charisma_ag_qc`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/cio_ag_outaouais.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Chambre immobilière de l'Outaouais (`cio_ag_outaouais`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/coldwell_banker.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Coldwell Banker Québec (`coldwell_banker`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/contact_ag_qc.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Les Immeubles Contact (`contact_ag_qc`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/domicilia.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Domicilia Agence Immobilière (`domicilia`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/duproprio.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # DuProprio (sans courtier) (`duproprio`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/engel_volkers.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Engel & Völkers Montréal / Québec (`engel_volkers`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/exp_ag_qc.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # eXp Agence immobilière (Québec) (`exp_ag_qc`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/expert_immobilier_pm.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # L'Expert Immobilier P.M. (`expert_immobilier_pm`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/famille-c21-ag.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Famille Century 21 (`c21_ag_*`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | Connecteurs par compte Century 21, générés depuis `data/century21_agencies.json` (plateforme source.immo). |
| 6 | 6 | |
modified
docs/connecteurs/famille-remax-ag.md
+55 −55
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Famille RE/MAX sous-agences (`remax_ag_*`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | Un connecteur par sous-agence RE/MAX (sites propres, indépendants du portail central), généré dynamiquement depuis `data/remax_agencies.json`. |
| 6 | 6 | |
@@ -36,56 +36,56 @@ Budgets env : `IMMOKA_AGENCE_DETAIL_LIMIT` (défaut 0) | ||
| 36 | 36 | |
| 37 | 37 | | source_id | Domaine | Plateforme | Visibles | Actives | Masquées dédup | Dernier sync | OK | |
| 38 | 38 | |---|---|---|---|---|---|---|---| |
| 39 | −| `remax_ag_1erchoix` | www.remax1erchoix.com | nos-proprietes | 211 | 1 064 | 853 | 2026-08-18 00:15 | ✅ | | |
| 40 | −| `remax_ag_2000` | www.remax-2000.com | centris-other | 72 | 735 | 663 | 2026-08-18 00:15 | ✅ | | |
| 41 | −| `remax_ag_2001` | www.remax2001.com | nos-proprietes | 37 | 366 | 329 | 2026-08-18 00:15 | ✅ | | |
| 42 | −| `remax_ag_3000` | remax3000.com | nos-proprietes | 52 | 782 | 730 | 2026-08-18 00:15 | ✅ | | |
| 43 | −| `remax_ag_acces` | www.remaxacces.com | nos-proprietes | 140 | 622 | 482 | 2026-08-18 00:15 | ✅ | | |
| 44 | −| `remax_ag_action` | remax-action.ca | nos-proprietes | 85 | 1 361 | 1 276 | 2026-08-18 00:15 | ✅ | | |
| 45 | −| `remax_ag_alliance` | www.remax-alliance.ca | nos-proprietes | 183 | 1 258 | 1 075 | 2026-08-18 00:15 | ✅ | | |
| 46 | −| `remax_ag_avantages` | www.remax-avantages.com | nos-proprietes | 177 | 772 | 595 | 2026-08-18 00:15 | ✅ | | |
| 47 | −| `remax_ag_avanttout` | www.remaxavanttout.com | nos-proprietes | 37 | 404 | 367 | 2026-08-18 00:15 | ✅ | | |
| 48 | −| `remax_ag_cite` | remax-cite.com | nos-proprietes | 12 | 116 | 104 | 2026-08-18 00:15 | ✅ | | |
| 49 | −| `remax_ag_crystal` | remaxcrystal.com | nos-proprietes | 168 | 1 305 | 1 137 | 2026-08-18 00:15 | ✅ | | |
| 50 | −| `remax_ag_d_ici` | remaxdici.com | nos-proprietes | 131 | 871 | 740 | 2026-08-18 00:15 | ✅ | | |
| 51 | −| `remax_ag_dabord` | www.remax-dabord.com | centris-other | 126 | 796 | 670 | 2026-08-18 00:15 | ✅ | | |
| 52 | −| `remax_ag_defi` | remax-defi1996.com | nos-proprietes | 27 | 348 | 321 | 2026-08-18 00:15 | ✅ | | |
| 53 | −| `remax_ag_defrancheville` | remaxdefrancheville.com | nos-proprietes | 168 | 1 461 | 1 293 | 2026-08-18 00:15 | ✅ | | |
| 54 | −| `remax_ag_direct` | remax-direct.com | nos-proprietes | 28 | 1 068 | 1 040 | 2026-08-18 00:15 | ✅ | | |
| 55 | −| `remax_ag_distinction` | remaxdistinction.com | nos-proprietes | 27 | 149 | 122 | 2026-08-18 00:15 | ✅ | | |
| 56 | −| `remax_ag_ducartier` | www.remaxducartier.com | centris-other | 237 | 1 860 | 1 623 | 2026-08-18 00:15 | ✅ | | |
| 57 | −| `remax_ag_ducartieractif` | www.remaxactif.com | centris-other | 25 | 119 | 94 | 2026-08-18 00:15 | ✅ | | |
| 58 | −| `remax_ag_ducartierbonjour` | remaxbonjour.com | centris-other | 120 | 1 548 | 1 428 | 2026-08-18 00:15 | ✅ | | |
| 59 | −| `remax_ag_dynamique` | remaxdynamique.com | nos-proprietes | 3 | 151 | 148 | 2026-08-18 00:15 | ✅ | | |
| 60 | −| `remax_ag_dynastie` | remax-dynastie.com | centris-other | 9 | 240 | 231 | 2026-08-18 00:15 | ✅ | | |
| 61 | −| `remax_ag_elegance` | remax-elegance.ca | nos-proprietes | 13 | 87 | 74 | 2026-08-18 00:15 | ✅ | | |
| 62 | −| `remax_ag_elite` | remax-elite.ca | nos-proprietes | 83 | 856 | 773 | 2026-08-18 00:15 | ✅ | | |
| 63 | −| `remax_ag_energie` | remax-energie.com | nos-proprietes | 8 | 173 | 165 | 2026-08-18 00:15 | ✅ | | |
| 64 | −| `remax_ag_evolution` | remax-evolution.com | centris-other | 39 | 494 | 455 | 2026-08-18 00:15 | ✅ | | |
| 65 | −| `remax_ag_excellence` | remax-excellence.ca | nos-proprietes | 6 | 286 | 280 | 2026-08-18 00:15 | ✅ | | |
| 66 | −| `remax_ag_extra` | remax-extra.ca | centris-other | 122 | 672 | 550 | 2026-08-18 00:15 | ✅ | | |
| 67 | −| `remax_ag_fortindelage` | remaxfortindelage.com | nos-proprietes | 67 | 408 | 341 | 2026-08-18 00:15 | ✅ | | |
| 68 | −| `remax_ag_futur` | remax-futur.ca | centris-other | 4 | 197 | 193 | 2026-08-18 00:15 | ✅ | | |
| 69 | −| `remax_ag_harmonie` | remaxharmonie.com | nos-proprietes | 58 | 376 | 318 | 2026-08-18 00:15 | ✅ | | |
| 70 | −| `remax_ag_harricana` | remax-harricana.com | nos-proprietes | 6 | 155 | 149 | 2026-08-18 00:16 | ✅ | | |
| 71 | −| `remax_ag_horizon` | remax-horizon.ca | nos-proprietes | 94 | 466 | 372 | 2026-08-18 00:16 | ✅ | | |
| 72 | −| `remax_ag_imagine` | remax-imagineprivilege.com | nos-proprietes | 64 | 457 | 393 | 2026-08-18 00:16 | ✅ | | |
| 73 | −| `remax_ag_immobilia` | remaximmobilia.ca | nos-proprietes | 0 | 7 | 7 | 2026-08-18 00:16 | ✅ | | |
| 74 | −| `remax_ag_immobilierplus` | remax-immobilierplus.com | nos-proprietes | 5 | 56 | 51 | 2026-08-18 00:16 | ✅ | | |
| 75 | −| `remax_ag_infinite` | remax-infinite.com | nos-proprietes | 2 | 61 | 59 | 2026-08-18 00:16 | ✅ | | |
| 76 | −| `remax_ag_invest` | remaxinvest.ca | nos-proprietes | 0 | 1 | 1 | 2026-08-18 00:16 | ✅ | | |
| 77 | −| `remax_ag_lespace` | www.remaxlespace.com | nos-proprietes | 41 | 472 | 431 | 2026-08-18 00:16 | ✅ | | |
| 78 | −| `remax_ag_lespace_commercial` | remaxlespace.com | nos-proprietes | 0 | 472 | 472 | 2026-08-18 00:16 | ✅ | | |
| 79 | −| `remax_ag_performance` | remaxperformance.net | nos-proprietes | 20 | 204 | 184 | 2026-08-18 00:16 | ✅ | | |
| 80 | −| `remax_ag_platine` | www.remax-platine.com | nos-proprietes | 107 | 1 313 | 1 206 | 2026-08-18 00:16 | ✅ | | |
| 81 | −| `remax_ag_plus` | remaxplus.ca | nos-proprietes | 71 | 349 | 278 | 2026-08-18 00:16 | ✅ | | |
| 82 | −| `remax_ag_prestige` | remaxprestige.ca | nos-proprietes | 94 | 482 | 388 | 2026-08-18 00:16 | ✅ | | |
| 83 | −| `remax_ag_privilege` | remax-imagineprivilege.com | nos-proprietes | 0 | 457 | 457 | 2026-08-18 00:16 | ✅ | | |
| 84 | −| `remax_ag_professionnel` | www.remax-professionnel.com | nos-proprietes | 81 | 729 | 648 | 2026-08-18 00:16 | ✅ | | |
| 85 | −| `remax_ag_renaissance` | remax-renaissance.ca | nos-proprietes | 36 | 302 | 266 | 2026-08-18 00:16 | ✅ | | |
| 86 | −| `remax_ag_royaljordan` | remax-royaljordan.com | nos-proprietes | 134 | 1 307 | 1 173 | 2026-08-18 00:16 | ✅ | | |
| 87 | −| `remax_ag_signature` | remaxsignature.ca | nos-proprietes | 88 | 569 | 481 | 2026-08-18 00:16 | ✅ | | |
| 88 | −| `remax_ag_vision` | remaxvision.ca | nos-proprietes | 31 | 1 074 | 1 043 | 2026-08-18 00:16 | ✅ | | |
| 39 | +| `remax_ag_1erchoix` | www.remax1erchoix.com | nos-proprietes | 203 | 1 056 | 853 | 2026-08-18 03:37 | ✅ | | |
| 40 | +| `remax_ag_2000` | www.remax-2000.com | centris-other | 65 | 728 | 663 | 2026-08-18 03:37 | ✅ | | |
| 41 | +| `remax_ag_2001` | www.remax2001.com | nos-proprietes | 37 | 366 | 329 | 2026-08-18 03:37 | ✅ | | |
| 42 | +| `remax_ag_3000` | remax3000.com | nos-proprietes | 46 | 775 | 729 | 2026-08-18 03:37 | ✅ | | |
| 43 | +| `remax_ag_acces` | www.remaxacces.com | nos-proprietes | 135 | 617 | 482 | 2026-08-18 03:37 | ✅ | | |
| 44 | +| `remax_ag_action` | remax-action.ca | nos-proprietes | 79 | 1 355 | 1 276 | 2026-08-18 03:37 | ✅ | | |
| 45 | +| `remax_ag_alliance` | www.remax-alliance.ca | nos-proprietes | 170 | 1 243 | 1 073 | 2026-08-18 03:37 | ✅ | | |
| 46 | +| `remax_ag_avantages` | www.remax-avantages.com | nos-proprietes | 169 | 765 | 596 | 2026-08-18 03:37 | ✅ | | |
| 47 | +| `remax_ag_avanttout` | www.remaxavanttout.com | nos-proprietes | 35 | 402 | 367 | 2026-08-18 03:37 | ✅ | | |
| 48 | +| `remax_ag_cite` | remax-cite.com | nos-proprietes | 12 | 116 | 104 | 2026-08-18 03:37 | ✅ | | |
| 49 | +| `remax_ag_crystal` | remaxcrystal.com | nos-proprietes | 157 | 1 294 | 1 137 | 2026-08-18 03:37 | ✅ | | |
| 50 | +| `remax_ag_d_ici` | remaxdici.com | nos-proprietes | 126 | 866 | 740 | 2026-08-18 03:37 | ✅ | | |
| 51 | +| `remax_ag_dabord` | www.remax-dabord.com | centris-other | 116 | 786 | 670 | 2026-08-18 03:37 | ✅ | | |
| 52 | +| `remax_ag_defi` | remax-defi1996.com | nos-proprietes | 26 | 347 | 321 | 2026-08-18 03:37 | ✅ | | |
| 53 | +| `remax_ag_defrancheville` | remaxdefrancheville.com | nos-proprietes | 162 | 1 457 | 1 295 | 2026-08-18 03:37 | ✅ | | |
| 54 | +| `remax_ag_direct` | remax-direct.com | nos-proprietes | 26 | 1 057 | 1 031 | 2026-08-18 03:37 | ✅ | | |
| 55 | +| `remax_ag_distinction` | remaxdistinction.com | nos-proprietes | 26 | 148 | 122 | 2026-08-18 03:37 | ✅ | | |
| 56 | +| `remax_ag_ducartier` | www.remaxducartier.com | centris-other | 215 | 1 838 | 1 623 | 2026-08-18 03:37 | ✅ | | |
| 57 | +| `remax_ag_ducartieractif` | www.remaxactif.com | centris-other | 25 | 119 | 94 | 2026-08-18 03:37 | ✅ | | |
| 58 | +| `remax_ag_ducartierbonjour` | remaxbonjour.com | centris-other | 110 | 1 538 | 1 428 | 2026-08-18 03:37 | ✅ | | |
| 59 | +| `remax_ag_dynamique` | remaxdynamique.com | nos-proprietes | 2 | 150 | 148 | 2026-08-18 03:37 | ✅ | | |
| 60 | +| `remax_ag_dynastie` | remax-dynastie.com | centris-other | 5 | 236 | 231 | 2026-08-18 03:37 | ✅ | | |
| 61 | +| `remax_ag_elegance` | remax-elegance.ca | nos-proprietes | 12 | 86 | 74 | 2026-08-18 03:37 | ✅ | | |
| 62 | +| `remax_ag_elite` | remax-elite.ca | nos-proprietes | 78 | 851 | 773 | 2026-08-18 03:37 | ✅ | | |
| 63 | +| `remax_ag_energie` | remax-energie.com | nos-proprietes | 8 | 173 | 165 | 2026-08-18 03:37 | ✅ | | |
| 64 | +| `remax_ag_evolution` | remax-evolution.com | centris-other | 39 | 494 | 455 | 2026-08-18 03:37 | ✅ | | |
| 65 | +| `remax_ag_excellence` | remax-excellence.ca | nos-proprietes | 1 | 281 | 280 | 2026-08-18 03:37 | ✅ | | |
| 66 | +| `remax_ag_extra` | remax-extra.ca | centris-other | 122 | 672 | 550 | 2026-08-18 03:37 | ✅ | | |
| 67 | +| `remax_ag_fortindelage` | remaxfortindelage.com | nos-proprietes | 65 | 406 | 341 | 2026-08-18 03:37 | ✅ | | |
| 68 | +| `remax_ag_futur` | remax-futur.ca | centris-other | 3 | 195 | 192 | 2026-08-18 03:37 | ✅ | | |
| 69 | +| `remax_ag_harmonie` | remaxharmonie.com | nos-proprietes | 55 | 373 | 318 | 2026-08-18 03:37 | ✅ | | |
| 70 | +| `remax_ag_harricana` | remax-harricana.com | nos-proprietes | 6 | 155 | 149 | 2026-08-18 03:37 | ✅ | | |
| 71 | +| `remax_ag_horizon` | remax-horizon.ca | nos-proprietes | 93 | 463 | 370 | 2026-08-18 03:37 | ✅ | | |
| 72 | +| `remax_ag_imagine` | remax-imagineprivilege.com | nos-proprietes | 59 | 452 | 393 | 2026-08-18 03:37 | ✅ | | |
| 73 | +| `remax_ag_immobilia` | remaximmobilia.ca | nos-proprietes | 0 | 7 | 7 | 2026-08-18 03:38 | ✅ | | |
| 74 | +| `remax_ag_immobilierplus` | remax-immobilierplus.com | nos-proprietes | 5 | 56 | 51 | 2026-08-18 03:38 | ✅ | | |
| 75 | +| `remax_ag_infinite` | remax-infinite.com | nos-proprietes | 0 | 59 | 59 | 2026-08-18 03:38 | ✅ | | |
| 76 | +| `remax_ag_invest` | remaxinvest.ca | nos-proprietes | 0 | 1 | 1 | 2026-08-18 03:38 | ✅ | | |
| 77 | +| `remax_ag_lespace` | www.remaxlespace.com | nos-proprietes | 38 | 469 | 431 | 2026-08-18 03:38 | ✅ | | |
| 78 | +| `remax_ag_lespace_commercial` | remaxlespace.com | nos-proprietes | 0 | 469 | 469 | 2026-08-18 03:38 | ✅ | | |
| 79 | +| `remax_ag_performance` | remaxperformance.net | nos-proprietes | 19 | 203 | 184 | 2026-08-18 03:38 | ✅ | | |
| 80 | +| `remax_ag_platine` | www.remax-platine.com | nos-proprietes | 95 | 1 303 | 1 208 | 2026-08-18 03:38 | ✅ | | |
| 81 | +| `remax_ag_plus` | remaxplus.ca | nos-proprietes | 70 | 348 | 278 | 2026-08-18 03:38 | ✅ | | |
| 82 | +| `remax_ag_prestige` | remaxprestige.ca | nos-proprietes | 88 | 476 | 388 | 2026-08-18 03:38 | ✅ | | |
| 83 | +| `remax_ag_privilege` | remax-imagineprivilege.com | nos-proprietes | 0 | 452 | 452 | 2026-08-18 03:38 | ✅ | | |
| 84 | +| `remax_ag_professionnel` | www.remax-professionnel.com | nos-proprietes | 74 | 722 | 648 | 2026-08-18 03:38 | ✅ | | |
| 85 | +| `remax_ag_renaissance` | remax-renaissance.ca | nos-proprietes | 34 | 300 | 266 | 2026-08-18 03:38 | ✅ | | |
| 86 | +| `remax_ag_royaljordan` | remax-royaljordan.com | nos-proprietes | 130 | 1 303 | 1 173 | 2026-08-18 03:38 | ✅ | | |
| 87 | +| `remax_ag_signature` | remaxsignature.ca | nos-proprietes | 80 | 561 | 481 | 2026-08-18 03:38 | ✅ | | |
| 88 | +| `remax_ag_vision` | remaxvision.ca | nos-proprietes | 29 | 1 067 | 1 038 | 2026-08-18 03:38 | ✅ | | |
| 89 | 89 | |
| 90 | 90 | Entrées du registre sans connecteur instancié (2) : `remax-pro-commercial.ca`, `nancyforlini.com` |
| 91 | 91 | |
@@ -94,10 +94,10 @@ Entrées du registre sans connecteur instancié (2) : `remax-pro-commercial.ca`, | ||
| 94 | 94 | | Indicateur | Valeur | |
| 95 | 95 | |---|---| |
| 96 | 96 | | Annonces en base (toutes) | 31 174 | |
| 97 | −| Actives | 29 878 | | |
| 98 | −| Visibles (après dédup) | 3 349 | | |
| 99 | −| Masquées par la dédup | 26 529 | | |
| 100 | −| GPS (lat/lng) | 96.8 % | | |
| 97 | +| Actives | 29 656 | | |
| 98 | +| Visibles (après dédup) | 3 150 | | |
| 99 | +| Masquées par la dédup | 26 506 | | |
| 100 | +| GPS (lat/lng) | 97.1 % | | |
| 101 | 101 | | Photos | 0.0 % | |
| 102 | 102 | | Prix | 0.0 % | |
| 103 | 103 | | CAC (chambres) | 7.9 % | |
modified
docs/connecteurs/famille-source-immo.md
+21 −14
@@ -1,11 +1,11 @@ | ||
| 1 | 1 | # Famille source.immo (agences indépendantes) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | Agences indépendantes servies par la plateforme source.immo (comptes/API dans `data/source_immo_agencies.json`). |
| 6 | 6 | |
| 7 | −- Registre : `data/source_immo_agencies.json` — **6 entrées** | |
| 8 | −- Connecteurs instanciés : **6** | |
| 7 | +- Registre : `data/source_immo_agencies.json` — **13 entrées** | |
| 8 | +- Connecteurs instanciés : **13** | |
| 9 | 9 | - Module : `immoka/connectors/agences_source_immo.py` |
| 10 | 10 | |
| 11 | 11 | **En-tête du module :** |
@@ -29,29 +29,36 @@ Agences indépendantes servies par la plateforme source.immo (comptes/API dans ` | ||
| 29 | 29 | |
| 30 | 30 | | source_id | Domaine | Plateforme | Visibles | Actives | Masquées dédup | Dernier sync | OK | |
| 31 | 31 | |---|---|---|---|---|---|---|---| |
| 32 | +| [`avenue`](avenue.md) | — | source.immo | 42 | 42 | 0 | 2026-08-18 05:56 | ✅ | | |
| 32 | 33 | | [`domicilia`](domicilia.md) | — | source.immo | 1 445 | 1 445 | 0 | 2026-08-18 02:27 | ✅ | |
| 34 | +| [`ferri`](ferri.md) | — | source.immo | 22 | 22 | 0 | 2026-08-18 05:56 | ✅ | | |
| 33 | 35 | | [`gaillardetz`](gaillardetz.md) | — | source.immo | 13 | 13 | 0 | 2026-08-18 02:27 | ✅ | |
| 34 | 36 | | [`immodev`](immodev.md) | — | source.immo | 92 | 92 | 0 | 2026-08-18 02:27 | ✅ | |
| 35 | 37 | | [`niddamour`](niddamour.md) | — | source.immo | 0 | 0 | 0 | 2026-08-18 02:27 | ✅ | |
| 38 | +| [`peladeau`](peladeau.md) | — | source.immo | 47 | 47 | 0 | 2026-08-18 05:56 | ✅ | | |
| 39 | +| [`provad`](provad.md) | — | source.immo | 80 | 80 | 0 | 2026-08-18 05:56 | ✅ | | |
| 36 | 40 | | [`realta`](realta.md) | — | source.immo | 82 | 82 | 0 | 2026-08-18 02:27 | ✅ | |
| 37 | −| [`si_ag_theagency`](si_ag_theagency.md) | — | source.immo | 245 | 304 | 59 | 2026-08-18 02:27 | ✅ | | |
| 41 | +| [`si_ag_ciemcq`](si_ag_ciemcq.md) | — | source.immo | 1 169 | 3 920 | 2 751 | 2026-08-18 05:56 | ✅ | | |
| 42 | +| [`si_ag_jga`](si_ag_jga.md) | — | source.immo | 59 | 64 | 5 | 2026-08-18 05:56 | ✅ | | |
| 43 | +| [`si_ag_katiasamson`](si_ag_katiasamson.md) | — | source.immo | 25 | 30 | 5 | 2026-08-18 05:56 | ✅ | | |
| 44 | +| [`si_ag_theagency`](si_ag_theagency.md) | — | source.immo | 236 | 304 | 68 | 2026-08-18 02:27 | ✅ | | |
| 38 | 45 | |
| 39 | −Entrées du registre sans connecteur instancié (6) : `www.realta.ca`, `www.immodev.ca`, `www.gaillardetz.ca`, `www.domicilia.com`, `www.niddamour.ca`, `theagencymontreal.com` | |
| 46 | +Entrées du registre sans connecteur instancié (13) : `www.realta.ca`, `www.immodev.ca`, `www.gaillardetz.ca`, `www.domicilia.com`, `www.niddamour.ca`, `theagencymontreal.com`, `www.mon-toit.net`, `avenueimmo.com`, `provad.ca`, `www.epeladeau.com`, `www.ferri.ca`, `jgacommercial.com`, `www.katiasamson.com` | |
| 40 | 47 | |
| 41 | 48 | ## Volumétrie & complétude agrégées (famille, BD live) |
| 42 | 49 | |
| 43 | 50 | | Indicateur | Valeur | |
| 44 | 51 | |---|---| |
| 45 | −| Annonces en base (toutes) | 1 984 | | |
| 46 | −| Actives | 1 936 | | |
| 47 | −| Visibles (après dédup) | 1 877 | | |
| 48 | −| Masquées par la dédup | 59 | | |
| 52 | +| Annonces en base (toutes) | 6 189 | | |
| 53 | +| Actives | 6 141 | | |
| 54 | +| Visibles (après dédup) | 3 312 | | |
| 55 | +| Masquées par la dédup | 2 829 | | |
| 49 | 56 | | GPS (lat/lng) | 99.9 % | |
| 50 | 57 | | Photos | 100.0 % | |
| 51 | 58 | | Prix | 100.0 % | |
| 52 | −| CAC (chambres) | 66.3 % | | |
| 53 | −| SDB (salles de bains) | 64.6 % | | |
| 54 | −| Année de construction | 75.4 % (dont rôle : 6.6 %) | | |
| 55 | −| Taxes / évaluation municipale | 89.3 % | | |
| 56 | −| Estimation Vrai-Prix (rôle) | 100.0 % | | |
| 59 | +| CAC (chambres) | 65.0 % | | |
| 60 | +| SDB (salles de bains) | 61.6 % | | |
| 61 | +| Année de construction | 70.0 % (dont rôle : 4.0 %) | | |
| 62 | +| Taxes / évaluation municipale | 86.1 % | | |
| 63 | +| Estimation Vrai-Prix (rôle) | 56.4 % | | |
| 57 | 64 | |
modified
docs/connecteurs/famille-via-ag.md
+11 −11
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Famille Via Capitale agences (`via_ag_*`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | Connecteurs par bannière Via Capitale, générés depuis `data/via_capitale_agencies.json` (comptes API source.immo par agence). |
| 6 | 6 | |
@@ -28,10 +28,10 @@ Connecteurs par bannière Via Capitale, générés depuis `data/via_capitale_age | ||
| 28 | 28 | |
| 29 | 29 | | source_id | Domaine | Plateforme | Visibles | Actives | Masquées dédup | Dernier sync | OK | |
| 30 | 30 | |---|---|---|---|---|---|---|---| |
| 31 | −| [`via_ag_acces`](via_ag_acces.md) | — | source.immo | 31 | 181 | 150 | 2026-08-18 00:27 | ✅ | | |
| 32 | −| [`via_ag_elite`](via_ag_elite.md) | — | source.immo | 11 | 319 | 308 | 2026-08-18 00:28 | ✅ | | |
| 33 | −| `via_ag_partenaires` | — | source.immo | 23 | 444 | 421 | 2026-08-18 00:28 | ✅ | | |
| 34 | −| [`via_ag_select`](via_ag_select.md) | — | source.immo | 17 | 580 | 563 | 2026-08-18 00:28 | ✅ | | |
| 31 | +| [`via_ag_acces`](via_ag_acces.md) | — | source.immo | 7 | 181 | 174 | 2026-08-18 00:27 | ✅ | | |
| 32 | +| [`via_ag_elite`](via_ag_elite.md) | — | source.immo | 10 | 319 | 309 | 2026-08-18 00:28 | ✅ | | |
| 33 | +| `via_ag_partenaires` | — | source.immo | 20 | 444 | 424 | 2026-08-18 00:28 | ✅ | | |
| 34 | +| [`via_ag_select`](via_ag_select.md) | — | source.immo | 13 | 580 | 567 | 2026-08-18 00:28 | ✅ | | |
| 35 | 35 | |
| 36 | 36 | Entrées du registre sans connecteur instancié (5) : `viacapitaleacces.com`, `viacapitaledumontroyal.com`, `viacapitaleelite.immo`, `viacapitalepartenaires.com`, `viacapitaleselect.com` |
| 37 | 37 | |
@@ -41,14 +41,14 @@ Entrées du registre sans connecteur instancié (5) : `viacapitaleacces.com`, `v | ||
| 41 | 41 | |---|---| |
| 42 | 42 | | Annonces en base (toutes) | 1 580 | |
| 43 | 43 | | Actives | 1 524 | |
| 44 | −| Visibles (après dédup) | 82 | | |
| 45 | −| Masquées par la dédup | 1 442 | | |
| 44 | +| Visibles (après dédup) | 50 | | |
| 45 | +| Masquées par la dédup | 1 474 | | |
| 46 | 46 | | GPS (lat/lng) | 100.0 % | |
| 47 | 47 | | Photos | 100.0 % | |
| 48 | 48 | | Prix | 100.0 % | |
| 49 | −| CAC (chambres) | 67.1 % | | |
| 50 | −| SDB (salles de bains) | 62.2 % | | |
| 51 | −| Année de construction | 93.9 % (dont rôle : 10.4 %) | | |
| 52 | −| Taxes / évaluation municipale | 89.0 % | | |
| 49 | +| CAC (chambres) | 54.0 % | | |
| 50 | +| SDB (salles de bains) | 50.0 % | | |
| 51 | +| Année de construction | 92.0 % (dont rôle : 8.7 %) | | |
| 52 | +| Taxes / évaluation municipale | 90.0 % | | |
| 53 | 53 | | Estimation Vrai-Prix (rôle) | 100.0 % | |
| 54 | 54 | |
added
docs/connecteurs/ferri.md
+59 −0
@@ -0,0 +1,59 @@ | ||
| 1 | +# Ferri Services Immobiliers (`ferri`) | |
| 2 | + | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | + | |
| 5 | +## Registre (`data/sources.json`) | |
| 6 | + | |
| 7 | +- **Site** : https://www.ferri.ca | |
| 8 | +- **Recherche** : https://www.ferri.ca/proprietes/ | |
| 9 | +- **Couverture** : Agence indépendante (Laval / Montréal) | |
| 10 | +- **Type** : agence | |
| 11 | +- **Statut** : actif | |
| 12 | + | |
| 13 | +> Plateforme source.immo (API publique, config auto _configs.json). ~22 propriétés à vendre (2026-08-18). Généré par agences_source_immo.py. | |
| 14 | + | |
| 15 | +## Mécanique (introspection du code) | |
| 16 | + | |
| 17 | +- Module : `immoka/connectors/agences_source_immo.py` — classe `AgenceSIFerri` | |
| 18 | +- Délai entre requêtes : 0.25 s ; cache détail BD : non | |
| 19 | + | |
| 20 | +**En-tête du module :** | |
| 21 | + | |
| 22 | +> Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 23 | +> Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 24 | +> connectors/agences_source_immo.py : agences INDÉPENDANTES sur la plateforme | |
| 25 | +> source.immo (plugin WordPress). Beaucoup de petites/moyennes agences QC | |
| 26 | +> l'utilisent (liste sur source.immo). Chacune expose sa config publique à | |
| 27 | +> /wp-content/uploads/_sourceimmo/_configs.json → on lit l'API publique | |
| 28 | +> api-v1.source.immo (voir SourceImmoConnector). Ce sont des agences | |
| 29 | +> autonomes : leurs inscriptions (leur propre n° Centris) sont ADDITIVES — | |
| 30 | +> pas de sous-agence d'une bannière déjà couverte → source_id normal (pas _ag_). | |
| 31 | +> EXCEPTION : les équipes/agences dont une partie des inscriptions est | |
| 32 | +> co-listée avec une bannière couverte (co-inscription Centris) portent un id | |
| 33 | +> « si_ag_<slug> » : la dédup Centris (db.refresh_dedup, sources %_ag_%) | |
| 34 | +> masque leurs doublons tout en gardant leurs fiches uniques visibles. | |
| 35 | +> Un connecteur par agence est généré depuis data/source_immo_agencies.json. | |
| 36 | + | |
| 37 | +## Volumétrie & complétude (BD live) | |
| 38 | + | |
| 39 | +| Indicateur | Valeur | | |
| 40 | +|---|---| | |
| 41 | +| Annonces en base (toutes) | 22 | | |
| 42 | +| Actives | 22 | | |
| 43 | +| Visibles (après dédup) | 22 | | |
| 44 | +| Masquées par la dédup | 0 | | |
| 45 | +| GPS (lat/lng) | 100.0 % | | |
| 46 | +| Photos | 100.0 % | | |
| 47 | +| Prix | 100.0 % | | |
| 48 | +| CAC (chambres) | 95.5 % | | |
| 49 | +| SDB (salles de bains) | 95.5 % | | |
| 50 | +| Année de construction | 95.5 % (dont rôle : 0.0 %) | | |
| 51 | +| Taxes / évaluation municipale | 100.0 % | | |
| 52 | +| Estimation Vrai-Prix (rôle) | 0.0 % | | |
| 53 | + | |
| 54 | +## Synchronisation | |
| 55 | + | |
| 56 | +- **Dernier sync** : 2026-08-18 05:56 — trouvé 22, +22 / ~0 / -0 — OK | |
| 57 | +- **Erreurs récentes** : 0 sur les 1 derniers syncs | |
| 58 | + | |
| 59 | +Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). | |
modified
docs/connecteurs/gaillardetz.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Gaillardetz Agence Immobilière (`gaillardetz`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/glmc_ag_qc.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Les Immeubles GLMC (`glmc_ag_qc`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
added
docs/connecteurs/guidehabitation.md
+56 −0
@@ -0,0 +1,56 @@ | ||
| 1 | +# Guide Habitation (projets neufs) (`guidehabitation`) | |
| 2 | + | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | + | |
| 5 | +## Registre (`data/sources.json`) | |
| 6 | + | |
| 7 | +- **Site** : https://www.guidehabitation.ca | |
| 8 | +- **Recherche** : https://www.guidehabitation.ca/fr/projets-immobiliers/montreal/ | |
| 9 | +- **Couverture** : Québec habité (9 régions) — projets neufs des promoteurs (condos et maisons neuves à vendre) | |
| 10 | +- **Type** : répertoire | |
| 11 | +- **Statut** : actif | |
| 12 | + | |
| 13 | +> Répertoire de référence des projets neufs. Pages région /fr/projets-immobiliers/{region}/ rendues serveur avec microdonnées schema.org par carte : adresse, ville, GPS, prix « À partir de » (itemprop=price), type, description, chambres, photo. Aucune clé, aucun JS. Projets LOCATIFS écartés (prix mensuel < 50 000 $ ou « locatif » dans le texte). 1 fiche = 1 projet (prix plancher, details.price_from). | |
| 14 | + | |
| 15 | +## Mécanique (introspection du code) | |
| 16 | + | |
| 17 | +- Module : `immoka/connectors/guidehabitation.py` — classe `GuideHabitationConnector` | |
| 18 | +- Délai entre requêtes : 1.0 s ; cache détail BD : oui | |
| 19 | + | |
| 20 | +**En-tête du module :** | |
| 21 | + | |
| 22 | +> Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 23 | +> Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 24 | +> connectors/guidehabitation.py : Guide Habitation (guidehabitation.ca) | |
| 25 | +> Répertoire de référence des PROJETS NEUFS au Québec (condos et maisons | |
| 26 | +> neuves des promoteurs). Pages région /fr/projets-immobiliers/{region}/ | |
| 27 | +> rendues serveur avec microdonnées schema.org complètes par carte projet : | |
| 28 | +> adresse (streetAddress), ville, GPS, prix « À partir de » (itemprop=price), | |
| 29 | +> type (SingleFamilyResidence → maison, ApartmentComplex → condo), | |
| 30 | +> description, chambres offertes, photo. Aucune clé, aucun rendu JS. | |
| 31 | +> On écarte les projets LOCATIFS (prix mensuel / « locatif » dans le texte) : | |
| 32 | +> Immo-Ka couvre le neuf À VENDRE. external_id = data-id du projet. | |
| 33 | + | |
| 34 | +## Volumétrie & complétude (BD live) | |
| 35 | + | |
| 36 | +| Indicateur | Valeur | | |
| 37 | +|---|---| | |
| 38 | +| Annonces en base (toutes) | 95 | | |
| 39 | +| Actives | 95 | | |
| 40 | +| Visibles (après dédup) | 94 | | |
| 41 | +| Masquées par la dédup | 1 | | |
| 42 | +| GPS (lat/lng) | 100.0 % | | |
| 43 | +| Photos | 100.0 % | | |
| 44 | +| Prix | 100.0 % | | |
| 45 | +| CAC (chambres) | 100.0 % | | |
| 46 | +| SDB (salles de bains) | 0.0 % | | |
| 47 | +| Année de construction | 0.0 % | | |
| 48 | +| Taxes / évaluation municipale | 0.0 % | | |
| 49 | +| Estimation Vrai-Prix (rôle) | 0.0 % | | |
| 50 | + | |
| 51 | +## Synchronisation | |
| 52 | + | |
| 53 | +- **Dernier sync** : 2026-08-18 05:56 — trouvé 95, +95 / ~0 / -0 — OK | |
| 54 | +- **Erreurs récentes** : 0 sur les 1 derniers syncs | |
| 55 | + | |
| 56 | +Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). | |
modified
docs/connecteurs/image_ag_qc.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Image, l'agence immobilière (`image_ag_qc`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/imcha_ag_qc.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Les Immeubles Charlevoix (`imcha_ag_qc`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/immodev.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Immodev Agence Immobilière (`immodev`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/kijiji.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Kijiji Québec (`kijiji`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/kw_distinction.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Keller Williams Distinction (`kw_distinction`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/kw_prestige.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Keller Williams Prestige (`kw_prestige`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/kw_urbain.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Keller Williams Urbain (`kw_urbain`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/lespac.md
+10 −10
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # LesPAC Québec (`lespac`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
@@ -32,16 +32,16 @@ | ||
| 32 | 32 | |---|---| |
| 33 | 33 | | Annonces en base (toutes) | 4 343 | |
| 34 | 34 | | Actives | 4 132 | |
| 35 | −| Visibles (après dédup) | 2 720 | | |
| 36 | −| Masquées par la dédup | 1 412 | | |
| 37 | −| GPS (lat/lng) | 46.3 % | | |
| 35 | +| Visibles (après dédup) | 2 756 | | |
| 36 | +| Masquées par la dédup | 1 376 | | |
| 37 | +| GPS (lat/lng) | 46.8 % | | |
| 38 | 38 | | Photos | 99.6 % | |
| 39 | −| Prix | 97.8 % | | |
| 40 | −| CAC (chambres) | 54.3 % | | |
| 41 | −| SDB (salles de bains) | 15.6 % | | |
| 42 | −| Année de construction | 57.5 % (dont rôle : 0.0 %) | | |
| 43 | −| Taxes / évaluation municipale | 8.3 % | | |
| 44 | −| Estimation Vrai-Prix (rôle) | 69.7 % | | |
| 39 | +| Prix | 97.9 % | | |
| 40 | +| CAC (chambres) | 54.6 % | | |
| 41 | +| SDB (salles de bains) | 15.7 % | | |
| 42 | +| Année de construction | 57.9 % (dont rôle : 0.0 %) | | |
| 43 | +| Taxes / évaluation municipale | 8.1 % | | |
| 44 | +| Estimation Vrai-Prix (rôle) | 70.2 % | | |
| 45 | 45 | |
| 46 | 46 | ## Synchronisation |
| 47 | 47 | |
modified
docs/connecteurs/m_immobilier.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # M Immobilier (`m_immobilier`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/niddamour.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Nid d'Amour Agence Immobilière (`niddamour`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
added
docs/connecteurs/peladeau.md
+59 −0
@@ -0,0 +1,59 @@ | ||
| 1 | +# Péladeau Agence Immobilière (`peladeau`) | |
| 2 | + | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | + | |
| 5 | +## Registre (`data/sources.json`) | |
| 6 | + | |
| 7 | +- **Site** : https://www.epeladeau.com | |
| 8 | +- **Recherche** : https://www.epeladeau.com/proprietes/ | |
| 9 | +- **Couverture** : Agence indépendante | |
| 10 | +- **Type** : agence | |
| 11 | +- **Statut** : actif | |
| 12 | + | |
| 13 | +> Plateforme source.immo (API publique, config auto _configs.json). ~47 propriétés à vendre (2026-08-18). Généré par agences_source_immo.py. | |
| 14 | + | |
| 15 | +## Mécanique (introspection du code) | |
| 16 | + | |
| 17 | +- Module : `immoka/connectors/agences_source_immo.py` — classe `AgenceSIPeladeau` | |
| 18 | +- Délai entre requêtes : 0.25 s ; cache détail BD : non | |
| 19 | + | |
| 20 | +**En-tête du module :** | |
| 21 | + | |
| 22 | +> Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 23 | +> Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 24 | +> connectors/agences_source_immo.py : agences INDÉPENDANTES sur la plateforme | |
| 25 | +> source.immo (plugin WordPress). Beaucoup de petites/moyennes agences QC | |
| 26 | +> l'utilisent (liste sur source.immo). Chacune expose sa config publique à | |
| 27 | +> /wp-content/uploads/_sourceimmo/_configs.json → on lit l'API publique | |
| 28 | +> api-v1.source.immo (voir SourceImmoConnector). Ce sont des agences | |
| 29 | +> autonomes : leurs inscriptions (leur propre n° Centris) sont ADDITIVES — | |
| 30 | +> pas de sous-agence d'une bannière déjà couverte → source_id normal (pas _ag_). | |
| 31 | +> EXCEPTION : les équipes/agences dont une partie des inscriptions est | |
| 32 | +> co-listée avec une bannière couverte (co-inscription Centris) portent un id | |
| 33 | +> « si_ag_<slug> » : la dédup Centris (db.refresh_dedup, sources %_ag_%) | |
| 34 | +> masque leurs doublons tout en gardant leurs fiches uniques visibles. | |
| 35 | +> Un connecteur par agence est généré depuis data/source_immo_agencies.json. | |
| 36 | + | |
| 37 | +## Volumétrie & complétude (BD live) | |
| 38 | + | |
| 39 | +| Indicateur | Valeur | | |
| 40 | +|---|---| | |
| 41 | +| Annonces en base (toutes) | 47 | | |
| 42 | +| Actives | 47 | | |
| 43 | +| Visibles (après dédup) | 47 | | |
| 44 | +| Masquées par la dédup | 0 | | |
| 45 | +| GPS (lat/lng) | 100.0 % | | |
| 46 | +| Photos | 100.0 % | | |
| 47 | +| Prix | 100.0 % | | |
| 48 | +| CAC (chambres) | 93.6 % | | |
| 49 | +| SDB (salles de bains) | 95.7 % | | |
| 50 | +| Année de construction | 83.0 % (dont rôle : 0.0 %) | | |
| 51 | +| Taxes / évaluation municipale | 78.7 % | | |
| 52 | +| Estimation Vrai-Prix (rôle) | 0.0 % | | |
| 53 | + | |
| 54 | +## Synchronisation | |
| 55 | + | |
| 56 | +- **Dernier sync** : 2026-08-18 05:56 — trouvé 47, +47 / ~0 / -0 — OK | |
| 57 | +- **Erreurs récentes** : 0 sur les 1 derniers syncs | |
| 58 | + | |
| 59 | +Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). | |
modified
docs/connecteurs/profusion.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Profusion Immobilier (Christie's) (`profusion`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/proprio_direct.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Proprio Direct (`proprio_direct`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
added
docs/connecteurs/provad.md
+59 −0
@@ -0,0 +1,59 @@ | ||
| 1 | +# Proulx Vadnais & Associés (`provad`) | |
| 2 | + | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | + | |
| 5 | +## Registre (`data/sources.json`) | |
| 6 | + | |
| 7 | +- **Site** : https://provad.ca | |
| 8 | +- **Recherche** : https://provad.ca/nos-proprietes/ | |
| 9 | +- **Couverture** : Agence indépendante commerciale/industrielle (Laval, Rive-Nord) | |
| 10 | +- **Type** : agence | |
| 11 | +- **Statut** : actif | |
| 12 | + | |
| 13 | +> Plateforme source.immo (API publique, config auto _configs.json). ~80 propriétés à vendre (2026-08-18). Généré par agences_source_immo.py. | |
| 14 | + | |
| 15 | +## Mécanique (introspection du code) | |
| 16 | + | |
| 17 | +- Module : `immoka/connectors/agences_source_immo.py` — classe `AgenceSIProvad` | |
| 18 | +- Délai entre requêtes : 0.25 s ; cache détail BD : non | |
| 19 | + | |
| 20 | +**En-tête du module :** | |
| 21 | + | |
| 22 | +> Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 23 | +> Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 24 | +> connectors/agences_source_immo.py : agences INDÉPENDANTES sur la plateforme | |
| 25 | +> source.immo (plugin WordPress). Beaucoup de petites/moyennes agences QC | |
| 26 | +> l'utilisent (liste sur source.immo). Chacune expose sa config publique à | |
| 27 | +> /wp-content/uploads/_sourceimmo/_configs.json → on lit l'API publique | |
| 28 | +> api-v1.source.immo (voir SourceImmoConnector). Ce sont des agences | |
| 29 | +> autonomes : leurs inscriptions (leur propre n° Centris) sont ADDITIVES — | |
| 30 | +> pas de sous-agence d'une bannière déjà couverte → source_id normal (pas _ag_). | |
| 31 | +> EXCEPTION : les équipes/agences dont une partie des inscriptions est | |
| 32 | +> co-listée avec une bannière couverte (co-inscription Centris) portent un id | |
| 33 | +> « si_ag_<slug> » : la dédup Centris (db.refresh_dedup, sources %_ag_%) | |
| 34 | +> masque leurs doublons tout en gardant leurs fiches uniques visibles. | |
| 35 | +> Un connecteur par agence est généré depuis data/source_immo_agencies.json. | |
| 36 | + | |
| 37 | +## Volumétrie & complétude (BD live) | |
| 38 | + | |
| 39 | +| Indicateur | Valeur | | |
| 40 | +|---|---| | |
| 41 | +| Annonces en base (toutes) | 80 | | |
| 42 | +| Actives | 80 | | |
| 43 | +| Visibles (après dédup) | 80 | | |
| 44 | +| Masquées par la dédup | 0 | | |
| 45 | +| GPS (lat/lng) | 100.0 % | | |
| 46 | +| Photos | 100.0 % | | |
| 47 | +| Prix | 100.0 % | | |
| 48 | +| CAC (chambres) | 1.2 % | | |
| 49 | +| SDB (salles de bains) | 0.0 % | | |
| 50 | +| Année de construction | 41.2 % (dont rôle : 0.0 %) | | |
| 51 | +| Taxes / évaluation municipale | 42.5 % | | |
| 52 | +| Estimation Vrai-Prix (rôle) | 0.0 % | | |
| 53 | + | |
| 54 | +## Synchronisation | |
| 55 | + | |
| 56 | +- **Dernier sync** : 2026-08-18 05:56 — trouvé 80, +80 / ~0 / -0 — OK | |
| 57 | +- **Erreurs récentes** : 0 sur les 1 derniers syncs | |
| 58 | + | |
| 59 | +Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). | |
modified
docs/connecteurs/realta.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Réalta Agence Immobilière (`realta`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
added
docs/connecteurs/realtor_ag_ca.md
+66 −0
@@ -0,0 +1,66 @@ | ||
| 1 | +# Realtor.ca (MLS Québec) (`realtor_ag_ca`) | |
| 2 | + | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | + | |
| 5 | +## Registre (`data/sources.json`) | |
| 6 | + | |
| 7 | +- **Site** : https://www.realtor.ca | |
| 8 | +- **Recherche** : https://www.realtor.ca/map#view=list&Province=QC | |
| 9 | +- **Couverture** : Toute la province — agrégateur MLS pan-bannières (SCI/CREA) | |
| 10 | +- **Type** : agrégateur | |
| 11 | +- **Statut** : actif | |
| 12 | + | |
| 13 | +> API interne api2.realtor.ca/Listing.svc/PropertySearch_Post (POST form). Protégée DataDome/Incapsula : accès direct = 403, mais REJOUABLE via Scrapfly ASP SANS render_js (vérifié 2026-08-18) → JSON riche : MLS, GPS, prix, CAC/SDB, superficie, photos, courtier+agence. 200 fiches/page, plafond serveur 600/recherche → sharding par 14 boîtes lat/lng QC, tri plus récentes d'abord (Sort=6-D). Budget borné IMMOKA_REALTOR_MAX (défaut 2 000 fiches/sync ≈ 10 appels Scrapfly — les ~10 shards les plus denses ; augmenter pour couvrir les régions éloignées ; 0 = désactivé). external_id = n° MLS Centris + infixe _ag_ → la dédup masque tout recoupement avec les connecteurs directs ; seules les fiches des bannières non couvertes restent visibles. Fenêtre glissante : les fiches anciennes sortent du budget au fil des syncs (miss_count → inactif). | |
| 14 | + | |
| 15 | +## Mécanique (introspection du code) | |
| 16 | + | |
| 17 | +- Module : `immoka/connectors/realtor_ca.py` — classe `RealtorCaConnector` | |
| 18 | +- Délai entre requêtes : 0.2 s ; cache détail BD : non | |
| 19 | +- Budgets env (enrichissement détail plafonné/exécution) : `IMMOKA_REALTOR_MAX` (défaut 2000) | |
| 20 | + | |
| 21 | +**En-tête du module :** | |
| 22 | + | |
| 23 | +> Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 24 | +> Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 25 | +> connectors/realtor_ca.py : Realtor.ca (couverture MLS pan-bannières, QC) | |
| 26 | +> API interne https://api2.realtor.ca/Listing.svc/PropertySearch_Post (POST | |
| 27 | +> form). Protégée (DataDome/Incapsula) : l'accès direct renvoie 403, mais | |
| 28 | +> l'API se REJOUE via Scrapfly ASP SANS render_js (1 crédit-appel ASP, pas de | |
| 29 | +> navigateur) → JSON complet : n° MLS, GPS, prix, CAC/SDB, superficie, photos, | |
| 30 | +> courtier + agence. Vérifié 2026-08-18 : 200 fiches/page, plafond serveur | |
| 31 | +> 600 fiches (MaxRecords) par recherche → SHARDING par boîtes lat/lng | |
| 32 | +> couvrant le Québec, tri « plus récentes d'abord » (Sort=6-D). | |
| 33 | +> BUDGET BORNÉ : IMMOKA_REALTOR_MAX fiches max par sync (défaut 2 000, soit | |
| 34 | +> ~10 appels Scrapfly), réparties en balayant la page 1 de chaque shard puis | |
| 35 | +> les pages 2-3 si le budget le permet. Les fiches plus anciennes sortent de | |
| 36 | +> la fenêtre au fil des syncs (miss_count → active=0) : le connecteur vaut | |
| 37 | +> surtout pour les inscriptions récentes des bannières non couvertes. | |
| 38 | +> Mettre IMMOKA_REALTOR_MAX=0 pour désactiver le connecteur. | |
| 39 | +> source_id « realtor_ag_ca » : l'infixe _ag_ + external_id = n° MLS Centris | |
| 40 | +> activent la dédup existante — toute fiche déjà couverte par un connecteur | |
| 41 | +> direct (RE/MAX, Royal LePage, Sutton…) est masquée, seules les fiches | |
| 42 | +> UNIQUES (petites bannières sans connecteur) restent visibles. | |
| 43 | + | |
| 44 | +## Volumétrie & complétude (BD live) | |
| 45 | + | |
| 46 | +| Indicateur | Valeur | | |
| 47 | +|---|---| | |
| 48 | +| Annonces en base (toutes) | 2 145 | | |
| 49 | +| Actives | 2 145 | | |
| 50 | +| Visibles (après dédup) | 343 | | |
| 51 | +| Masquées par la dédup | 1 802 | | |
| 52 | +| GPS (lat/lng) | 100.0 % | | |
| 53 | +| Photos | 100.0 % | | |
| 54 | +| Prix | 100.0 % | | |
| 55 | +| CAC (chambres) | 85.7 % | | |
| 56 | +| SDB (salles de bains) | 86.0 % | | |
| 57 | +| Année de construction | 0.0 % | | |
| 58 | +| Taxes / évaluation municipale | 0.0 % | | |
| 59 | +| Estimation Vrai-Prix (rôle) | 0.0 % | | |
| 60 | + | |
| 61 | +## Synchronisation | |
| 62 | + | |
| 63 | +- **Dernier sync** : 2026-08-18 06:06 — trouvé 2 145, +2145 / ~0 / -0 — OK | |
| 64 | +- **Erreurs récentes** : 0 sur les 1 derniers syncs | |
| 65 | + | |
| 66 | +Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). | |
modified
docs/connecteurs/remax_quebec.md
+5 −5
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # RE/MAX Québec (`remax_quebec`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
@@ -41,17 +41,17 @@ | ||
| 41 | 41 | | Visibles (après dédup) | 25 348 | |
| 42 | 42 | | Masquées par la dédup | 138 | |
| 43 | 43 | | GPS (lat/lng) | 100.0 % | |
| 44 | −| Photos | 99.7 % | | |
| 44 | +| Photos | 100.0 % | | |
| 45 | 45 | | Prix | 83.9 % | |
| 46 | 46 | | CAC (chambres) | 79.1 % | |
| 47 | 47 | | SDB (salles de bains) | 59.9 % | |
| 48 | −| Année de construction | 77.0 % (dont rôle : 99.9 %) | | |
| 49 | −| Taxes / évaluation municipale | 0.4 % | | |
| 48 | +| Année de construction | 82.8 % (dont rôle : 0.0 %) | | |
| 49 | +| Taxes / évaluation municipale | 77.2 % | | |
| 50 | 50 | | Estimation Vrai-Prix (rôle) | 100.0 % | |
| 51 | 51 | |
| 52 | 52 | ## Synchronisation |
| 53 | 53 | |
| 54 | −- **Dernier sync** : 2026-08-18 01:45 — trouvé 25 486, +0 / ~60 / -177 — OK | |
| 54 | +- **Dernier sync** : 2026-08-18 05:11 — trouvé 25 486, +0 / ~25426 / -0 — OK | |
| 55 | 55 | - **Erreurs récentes** : 0 sur les 10 derniers syncs |
| 56 | 56 | |
| 57 | 57 | Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). |
modified
docs/connecteurs/royal_lepage.md
+10 −10
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Royal LePage (Québec) (`royal_lepage`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
@@ -37,21 +37,21 @@ | ||
| 37 | 37 | | Indicateur | Valeur | |
| 38 | 38 | |---|---| |
| 39 | 39 | | Annonces en base (toutes) | 1 461 | |
| 40 | −| Actives | 1 012 | | |
| 41 | −| Visibles (après dédup) | 1 009 | | |
| 40 | +| Actives | 1 011 | | |
| 41 | +| Visibles (après dédup) | 1 008 | | |
| 42 | 42 | | Masquées par la dédup | 3 | |
| 43 | 43 | | GPS (lat/lng) | 100.0 % | |
| 44 | −| Photos | 99.9 % | | |
| 45 | −| Prix | 80.4 % | | |
| 46 | −| CAC (chambres) | 81.8 % | | |
| 47 | −| SDB (salles de bains) | 81.4 % | | |
| 48 | −| Année de construction | 85.7 % (dont rôle : 99.4 %) | | |
| 49 | −| Taxes / évaluation municipale | 0.4 % | | |
| 44 | +| Photos | 100.0 % | | |
| 45 | +| Prix | 80.5 % | | |
| 46 | +| CAC (chambres) | 85.6 % | | |
| 47 | +| SDB (salles de bains) | 84.5 % | | |
| 48 | +| Année de construction | 89.0 % (dont rôle : 47.6 %) | | |
| 49 | +| Taxes / évaluation municipale | 38.0 % | | |
| 50 | 50 | | Estimation Vrai-Prix (rôle) | 100.0 % | |
| 51 | 51 | |
| 52 | 52 | ## Synchronisation |
| 53 | 53 | |
| 54 | −- **Dernier sync** : 2026-08-18 02:20 — trouvé 1 010, +0 / ~7 / -18 — OK | |
| 54 | +- **Dernier sync** : 2026-08-18 05:19 — trouvé 1 010, +0 / ~498 / -1 — OK | |
| 55 | 55 | - **Erreurs récentes** : 0 sur les 10 derniers syncs |
| 56 | 56 | |
| 57 | 57 | Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). |
added
docs/connecteurs/si_ag_ciemcq.md
+59 −0
@@ -0,0 +1,59 @@ | ||
| 1 | +# Chambre immobilière Estrie–Mauricie–Centre-du-Québec (Mon-Toit) (`si_ag_ciemcq`) | |
| 2 | + | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | + | |
| 5 | +## Registre (`data/sources.json`) | |
| 6 | + | |
| 7 | +- **Site** : https://www.mon-toit.net | |
| 8 | +- **Recherche** : https://www.mon-toit.net/proprietes/ | |
| 9 | +- **Couverture** : Estrie, Mauricie, Centre-du-Québec — ~600 courtiers (chambre régionale) | |
| 10 | +- **Type** : chambre | |
| 11 | +- **Statut** : actif | |
| 12 | + | |
| 13 | +> Plateforme source.immo (config publique _configs.json sur mon-toit.net et ciemcq.com). ~3 900 fiches à vendre (2026-08-18). Flux co-listé avec les bannières → si_ag_ (dédup Centris). Généré par agences_source_immo.py. | |
| 14 | + | |
| 15 | +## Mécanique (introspection du code) | |
| 16 | + | |
| 17 | +- Module : `immoka/connectors/agences_source_immo.py` — classe `AgenceSISiAgCiemcq` | |
| 18 | +- Délai entre requêtes : 0.25 s ; cache détail BD : non | |
| 19 | + | |
| 20 | +**En-tête du module :** | |
| 21 | + | |
| 22 | +> Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 23 | +> Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 24 | +> connectors/agences_source_immo.py : agences INDÉPENDANTES sur la plateforme | |
| 25 | +> source.immo (plugin WordPress). Beaucoup de petites/moyennes agences QC | |
| 26 | +> l'utilisent (liste sur source.immo). Chacune expose sa config publique à | |
| 27 | +> /wp-content/uploads/_sourceimmo/_configs.json → on lit l'API publique | |
| 28 | +> api-v1.source.immo (voir SourceImmoConnector). Ce sont des agences | |
| 29 | +> autonomes : leurs inscriptions (leur propre n° Centris) sont ADDITIVES — | |
| 30 | +> pas de sous-agence d'une bannière déjà couverte → source_id normal (pas _ag_). | |
| 31 | +> EXCEPTION : les équipes/agences dont une partie des inscriptions est | |
| 32 | +> co-listée avec une bannière couverte (co-inscription Centris) portent un id | |
| 33 | +> « si_ag_<slug> » : la dédup Centris (db.refresh_dedup, sources %_ag_%) | |
| 34 | +> masque leurs doublons tout en gardant leurs fiches uniques visibles. | |
| 35 | +> Un connecteur par agence est généré depuis data/source_immo_agencies.json. | |
| 36 | + | |
| 37 | +## Volumétrie & complétude (BD live) | |
| 38 | + | |
| 39 | +| Indicateur | Valeur | | |
| 40 | +|---|---| | |
| 41 | +| Annonces en base (toutes) | 3 920 | | |
| 42 | +| Actives | 3 920 | | |
| 43 | +| Visibles (après dédup) | 1 169 | | |
| 44 | +| Masquées par la dédup | 2 751 | | |
| 45 | +| GPS (lat/lng) | 100.0 % | | |
| 46 | +| Photos | 100.0 % | | |
| 47 | +| Prix | 100.0 % | | |
| 48 | +| CAC (chambres) | 66.7 % | | |
| 49 | +| SDB (salles de bains) | 60.1 % | | |
| 50 | +| Année de construction | 62.8 % (dont rôle : 0.0 %) | | |
| 51 | +| Taxes / évaluation municipale | 83.7 % | | |
| 52 | +| Estimation Vrai-Prix (rôle) | 0.0 % | | |
| 53 | + | |
| 54 | +## Synchronisation | |
| 55 | + | |
| 56 | +- **Dernier sync** : 2026-08-18 05:56 — trouvé 3 920, +3920 / ~0 / -0 — OK | |
| 57 | +- **Erreurs récentes** : 0 sur les 1 derniers syncs | |
| 58 | + | |
| 59 | +Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). | |
added
docs/connecteurs/si_ag_jga.md
+59 −0
@@ -0,0 +1,59 @@ | ||
| 1 | +# JGA Équipe Commerciale (Royal LePage) (`si_ag_jga`) | |
| 2 | + | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | + | |
| 5 | +## Registre (`data/sources.json`) | |
| 6 | + | |
| 7 | +- **Site** : https://jgacommercial.com | |
| 8 | +- **Recherche** : https://jgacommercial.com/proprietes/ | |
| 9 | +- **Couverture** : Équipe commerciale/industrielle Royal LePage | |
| 10 | +- **Type** : équipe | |
| 11 | +- **Statut** : actif | |
| 12 | + | |
| 13 | +> Plateforme source.immo. ~64 fiches à vendre (2026-08-18). Équipe co-listée → si_ag_ (dédup Centris). Généré par agences_source_immo.py. | |
| 14 | + | |
| 15 | +## Mécanique (introspection du code) | |
| 16 | + | |
| 17 | +- Module : `immoka/connectors/agences_source_immo.py` — classe `AgenceSISiAgJga` | |
| 18 | +- Délai entre requêtes : 0.25 s ; cache détail BD : non | |
| 19 | + | |
| 20 | +**En-tête du module :** | |
| 21 | + | |
| 22 | +> Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 23 | +> Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 24 | +> connectors/agences_source_immo.py : agences INDÉPENDANTES sur la plateforme | |
| 25 | +> source.immo (plugin WordPress). Beaucoup de petites/moyennes agences QC | |
| 26 | +> l'utilisent (liste sur source.immo). Chacune expose sa config publique à | |
| 27 | +> /wp-content/uploads/_sourceimmo/_configs.json → on lit l'API publique | |
| 28 | +> api-v1.source.immo (voir SourceImmoConnector). Ce sont des agences | |
| 29 | +> autonomes : leurs inscriptions (leur propre n° Centris) sont ADDITIVES — | |
| 30 | +> pas de sous-agence d'une bannière déjà couverte → source_id normal (pas _ag_). | |
| 31 | +> EXCEPTION : les équipes/agences dont une partie des inscriptions est | |
| 32 | +> co-listée avec une bannière couverte (co-inscription Centris) portent un id | |
| 33 | +> « si_ag_<slug> » : la dédup Centris (db.refresh_dedup, sources %_ag_%) | |
| 34 | +> masque leurs doublons tout en gardant leurs fiches uniques visibles. | |
| 35 | +> Un connecteur par agence est généré depuis data/source_immo_agencies.json. | |
| 36 | + | |
| 37 | +## Volumétrie & complétude (BD live) | |
| 38 | + | |
| 39 | +| Indicateur | Valeur | | |
| 40 | +|---|---| | |
| 41 | +| Annonces en base (toutes) | 64 | | |
| 42 | +| Actives | 64 | | |
| 43 | +| Visibles (après dédup) | 59 | | |
| 44 | +| Masquées par la dédup | 5 | | |
| 45 | +| GPS (lat/lng) | 100.0 % | | |
| 46 | +| Photos | 100.0 % | | |
| 47 | +| Prix | 100.0 % | | |
| 48 | +| CAC (chambres) | 8.5 % | | |
| 49 | +| SDB (salles de bains) | 5.1 % | | |
| 50 | +| Année de construction | 28.8 % (dont rôle : 0.0 %) | | |
| 51 | +| Taxes / évaluation municipale | 91.5 % | | |
| 52 | +| Estimation Vrai-Prix (rôle) | 0.0 % | | |
| 53 | + | |
| 54 | +## Synchronisation | |
| 55 | + | |
| 56 | +- **Dernier sync** : 2026-08-18 05:56 — trouvé 64, +64 / ~0 / -0 — OK | |
| 57 | +- **Erreurs récentes** : 0 sur les 1 derniers syncs | |
| 58 | + | |
| 59 | +Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). | |
added
docs/connecteurs/si_ag_katiasamson.md
+59 −0
@@ -0,0 +1,59 @@ | ||
| 1 | +# Katia Samson (RE/MAX L'Espace) (`si_ag_katiasamson`) | |
| 2 | + | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | + | |
| 5 | +## Registre (`data/sources.json`) | |
| 6 | + | |
| 7 | +- **Site** : https://www.katiasamson.com | |
| 8 | +- **Recherche** : https://www.katiasamson.com/proprietes/ | |
| 9 | +- **Couverture** : Équipe RE/MAX L'Espace (Montréal) | |
| 10 | +- **Type** : équipe | |
| 11 | +- **Statut** : actif | |
| 12 | + | |
| 13 | +> Plateforme source.immo. ~30 fiches à vendre (2026-08-18). Équipe co-listée (remax_ag_lespace couvert) → si_ag_ (dédup Centris). Généré par agences_source_immo.py. | |
| 14 | + | |
| 15 | +## Mécanique (introspection du code) | |
| 16 | + | |
| 17 | +- Module : `immoka/connectors/agences_source_immo.py` — classe `AgenceSISiAgKatiasamson` | |
| 18 | +- Délai entre requêtes : 0.25 s ; cache détail BD : non | |
| 19 | + | |
| 20 | +**En-tête du module :** | |
| 21 | + | |
| 22 | +> Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 23 | +> Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 24 | +> connectors/agences_source_immo.py : agences INDÉPENDANTES sur la plateforme | |
| 25 | +> source.immo (plugin WordPress). Beaucoup de petites/moyennes agences QC | |
| 26 | +> l'utilisent (liste sur source.immo). Chacune expose sa config publique à | |
| 27 | +> /wp-content/uploads/_sourceimmo/_configs.json → on lit l'API publique | |
| 28 | +> api-v1.source.immo (voir SourceImmoConnector). Ce sont des agences | |
| 29 | +> autonomes : leurs inscriptions (leur propre n° Centris) sont ADDITIVES — | |
| 30 | +> pas de sous-agence d'une bannière déjà couverte → source_id normal (pas _ag_). | |
| 31 | +> EXCEPTION : les équipes/agences dont une partie des inscriptions est | |
| 32 | +> co-listée avec une bannière couverte (co-inscription Centris) portent un id | |
| 33 | +> « si_ag_<slug> » : la dédup Centris (db.refresh_dedup, sources %_ag_%) | |
| 34 | +> masque leurs doublons tout en gardant leurs fiches uniques visibles. | |
| 35 | +> Un connecteur par agence est généré depuis data/source_immo_agencies.json. | |
| 36 | + | |
| 37 | +## Volumétrie & complétude (BD live) | |
| 38 | + | |
| 39 | +| Indicateur | Valeur | | |
| 40 | +|---|---| | |
| 41 | +| Annonces en base (toutes) | 30 | | |
| 42 | +| Actives | 30 | | |
| 43 | +| Visibles (après dédup) | 25 | | |
| 44 | +| Masquées par la dédup | 5 | | |
| 45 | +| GPS (lat/lng) | 100.0 % | | |
| 46 | +| Photos | 100.0 % | | |
| 47 | +| Prix | 100.0 % | | |
| 48 | +| CAC (chambres) | 96.0 % | | |
| 49 | +| SDB (salles de bains) | 96.0 % | | |
| 50 | +| Année de construction | 100.0 % (dont rôle : 0.0 %) | | |
| 51 | +| Taxes / évaluation municipale | 64.0 % | | |
| 52 | +| Estimation Vrai-Prix (rôle) | 0.0 % | | |
| 53 | + | |
| 54 | +## Synchronisation | |
| 55 | + | |
| 56 | +- **Dernier sync** : 2026-08-18 05:56 — trouvé 30, +30 / ~0 / -0 — OK | |
| 57 | +- **Erreurs récentes** : 0 sur les 1 derniers syncs | |
| 58 | + | |
| 59 | +Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). | |
modified
docs/connecteurs/si_ag_theagency.md
+7 −7
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # The Agency Montréal (`si_ag_theagency`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
@@ -40,15 +40,15 @@ | ||
| 40 | 40 | |---|---| |
| 41 | 41 | | Annonces en base (toutes) | 308 | |
| 42 | 42 | | Actives | 304 | |
| 43 | −| Visibles (après dédup) | 245 | | |
| 44 | −| Masquées par la dédup | 59 | | |
| 43 | +| Visibles (après dédup) | 236 | | |
| 44 | +| Masquées par la dédup | 68 | | |
| 45 | 45 | | GPS (lat/lng) | 100.0 % | |
| 46 | 46 | | Photos | 100.0 % | |
| 47 | 47 | | Prix | 100.0 % | |
| 48 | −| CAC (chambres) | 77.6 % | | |
| 49 | −| SDB (salles de bains) | 75.5 % | | |
| 50 | −| Année de construction | 88.6 % (dont rôle : 6.5 %) | | |
| 51 | −| Taxes / évaluation municipale | 83.7 % | | |
| 48 | +| CAC (chambres) | 78.8 % | | |
| 49 | +| SDB (salles de bains) | 76.7 % | | |
| 50 | +| Année de construction | 90.3 % (dont rôle : 6.6 %) | | |
| 51 | +| Taxes / évaluation municipale | 84.7 % | | |
| 52 | 52 | | Estimation Vrai-Prix (rôle) | 100.0 % | |
| 53 | 53 | |
| 54 | 54 | ## Synchronisation |
modified
docs/connecteurs/sothebys_quebec.md
+25 −17
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Sotheby's International Realty Québec (`sothebys_quebec`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
@@ -10,45 +10,53 @@ | ||
| 10 | 10 | - **Type** : luxe |
| 11 | 11 | - **Statut** : actif |
| 12 | 12 | |
| 13 | −> Recherche rendue côté client. Fiches enumérées via pages de résultats (grid public plafonné ~40 fiches province-wide ; pagination AJAX non exposée en URL). Chaque fiche enrichie via son JSON-LD Product : prix, galerie S3 complète (35-75 photos), description, MLS (sku), type. Limite : couverture = set public courant (~40) ; coverage complète nécessiterait l'endpoint AJAX de pagination. | |
| 13 | +> Inventaire COMPLET via l'API AJAX interne /include/ajax_results.php (dowhat=getgridresults, jeton ajaxtoken de la page province, p_territories[]=4 = Québec, 64 fiches/page). Particularité : les valeurs du filtre statut de l'UI (1=For Sale, 3=For Rent) sont remappées côté serveur — on passe p_status[]=2 (neutre → aucun filtre → tout l'inventaire actif) et on écarte les locations («…/mo») au parsing. ~1 100 fiches QC dont ~965 à vendre (2026-08-18) contre ~40-60 avant (grid public plafonné). Enrichissement JSON-LD Product par fiche : prix, galerie S3 complète, description, MLS (sku). Repli : ancien parcours des pages région. | |
| 14 | 14 | |
| 15 | 15 | ## Mécanique (introspection du code) |
| 16 | 16 | |
| 17 | 17 | - Module : `immoka/connectors/sothebys_quebec.py` — classe `SothebysQuebecConnector` |
| 18 | 18 | - Délai entre requêtes : 1.0 s ; cache détail BD : oui |
| 19 | −- Budgets env (enrichissement détail plafonné/exécution) : `IMMOKA_SOTHEBYS_DETAIL_LIMIT` (défaut 400) | |
| 19 | +- Budgets env (enrichissement détail plafonné/exécution) : `IMMOKA_SOTHEBYS_DETAIL_LIMIT` (défaut 400), `IMMOKA_SOTHEBYS_MAX_PAGES` (défaut 30) | |
| 20 | 20 | |
| 21 | 21 | **En-tête du module :** |
| 22 | 22 | |
| 23 | 23 | > Immo-Ka — Agrégateur de maisons à vendre (province de Québec) |
| 24 | 24 | > Auteur : Simon-Pierre Boucher — contact@spboucher.ai |
| 25 | 25 | > connectors/sothebys_quebec.py : Sotheby's International Realty Québec |
| 26 | −> Recherche rendue côté client : le grid public est plafonné (~40/page) et la | |
| 27 | −> pagination passe par du JS (pas d'URL). On SHARD donc par région | |
| 28 | −> administrative du Québec (chaque page « region-{slug}-real-estate » renvoie | |
| 29 | −> son lot), on dédoublonne par id, puis on enrichit chaque fiche via son | |
| 30 | −> JSON-LD `Product` (prix, galerie S3 complète, description, n° MLS = sku). | |
| 26 | +> Inventaire COMPLET via l'API AJAX interne du site : | |
| 27 | +> GET /include/ajax_results.php?dowhat=getgridresults&token=…&p_territories[]=4 | |
| 28 | +> (territoire 4 = province de Québec ; jeton `ajaxtoken` exposé dans la page | |
| 29 | +> /en/search-results/province-quebec-real-estate/). Pagination 64 fiches/page. | |
| 30 | +> Particularité serveur : les valeurs du filtre statut de l'interface | |
| 31 | +> (1 = For Sale, 3 = For Rent) sont REMAPPÉES côté serveur — `p_status[]=1` | |
| 32 | +> renvoie 0 résultat et `p_status[]=3` seulement les locations. On passe donc | |
| 33 | +> une valeur neutre (2) qui désactive le filtre et renvoie TOUT l'inventaire | |
| 34 | +> actif (vente + location), puis on écarte les locations (« …/mo ») au parsing. | |
| 35 | +> Chaque carte porte data-lat/lng/img/price + adresse/ville + CAC/SDB. | |
| 36 | +> Enrichissement fiche détail (JSON-LD Product) : prix, galerie S3 complète, | |
| 37 | +> description, n° MLS = sku. Repli : ancien parcours des pages région si | |
| 38 | +> l'AJAX venait à changer. | |
| 31 | 39 | |
| 32 | 40 | ## Volumétrie & complétude (BD live) |
| 33 | 41 | |
| 34 | 42 | | Indicateur | Valeur | |
| 35 | 43 | |---|---| |
| 36 | −| Annonces en base (toutes) | 58 | | |
| 37 | −| Actives | 42 | | |
| 38 | −| Visibles (après dédup) | 42 | | |
| 44 | +| Annonces en base (toutes) | 869 | | |
| 45 | +| Actives | 869 | | |
| 46 | +| Visibles (après dédup) | 869 | | |
| 39 | 47 | | Masquées par la dédup | 0 | |
| 40 | −| GPS (lat/lng) | 88.1 % | | |
| 48 | +| GPS (lat/lng) | 99.8 % | | |
| 41 | 49 | | Photos | 100.0 % | |
| 42 | 50 | | Prix | 100.0 % | |
| 43 | −| CAC (chambres) | 45.2 % | | |
| 44 | −| SDB (salles de bains) | 14.3 % | | |
| 45 | −| Année de construction | 71.4 % (dont rôle : 100.0 %) | | |
| 51 | +| CAC (chambres) | 76.9 % | | |
| 52 | +| SDB (salles de bains) | 74.5 % | | |
| 53 | +| Année de construction | 3.5 % (dont rôle : 0.0 %) | | |
| 46 | 54 | | Taxes / évaluation municipale | 0.0 % | |
| 47 | −| Estimation Vrai-Prix (rôle) | 100.0 % | | |
| 55 | +| Estimation Vrai-Prix (rôle) | 6.7 % | | |
| 48 | 56 | |
| 49 | 57 | ## Synchronisation |
| 50 | 58 | |
| 51 | −- **Dernier sync** : 2026-08-18 00:21 — trouvé 40, +2 / ~0 / -0 — OK | |
| 59 | +- **Dernier sync** : 2026-08-18 06:05 — trouvé 869, +809 / ~60 / -0 — OK | |
| 52 | 60 | - **Erreurs récentes** : 0 sur les 10 derniers syncs |
| 53 | 61 | |
| 54 | 62 | Voir aussi les [mécanismes transverses](INDEX.md#mécanismes-transverses-tous-connecteurs) (budgets détail, dédup Centris+adresse, jointure rôle vraiprix.db). |
modified
docs/connecteurs/sutton.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Groupe Sutton Québec (`sutton`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/ubee.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Ubee (`ubee`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/vendirect.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Vendirect (`vendirect`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/via_ag_acces.md
+7 −7
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Via Capitale Acces (`via_ag_acces`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
@@ -38,15 +38,15 @@ | ||
| 38 | 38 | |---|---| |
| 39 | 39 | | Annonces en base (toutes) | 186 | |
| 40 | 40 | | Actives | 181 | |
| 41 | −| Visibles (après dédup) | 31 | | |
| 42 | −| Masquées par la dédup | 150 | | |
| 41 | +| Visibles (après dédup) | 7 | | |
| 42 | +| Masquées par la dédup | 174 | | |
| 43 | 43 | | GPS (lat/lng) | 100.0 % | |
| 44 | 44 | | Photos | 100.0 % | |
| 45 | 45 | | Prix | 100.0 % | |
| 46 | −| CAC (chambres) | 77.4 % | | |
| 47 | −| SDB (salles de bains) | 74.2 % | | |
| 48 | −| Année de construction | 96.8 % (dont rôle : 10.0 %) | | |
| 49 | −| Taxes / évaluation municipale | 93.5 % | | |
| 46 | +| CAC (chambres) | 57.1 % | | |
| 47 | +| SDB (salles de bains) | 57.1 % | | |
| 48 | +| Année de construction | 100.0 % (dont rôle : 0.0 %) | | |
| 49 | +| Taxes / évaluation municipale | 100.0 % | | |
| 50 | 50 | | Estimation Vrai-Prix (rôle) | 100.0 % | |
| 51 | 51 | |
| 52 | 52 | ## Synchronisation |
modified
docs/connecteurs/via_ag_dumontroyal.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Via Capitale Dumontroyal (`via_ag_dumontroyal`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
modified
docs/connecteurs/via_ag_elite.md
+7 −7
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Via Capitale Elite (`via_ag_elite`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
@@ -38,15 +38,15 @@ | ||
| 38 | 38 | |---|---| |
| 39 | 39 | | Annonces en base (toutes) | 327 | |
| 40 | 40 | | Actives | 319 | |
| 41 | −| Visibles (après dédup) | 11 | | |
| 42 | −| Masquées par la dédup | 308 | | |
| 41 | +| Visibles (après dédup) | 10 | | |
| 42 | +| Masquées par la dédup | 309 | | |
| 43 | 43 | | GPS (lat/lng) | 100.0 % | |
| 44 | 44 | | Photos | 100.0 % | |
| 45 | 45 | | Prix | 100.0 % | |
| 46 | −| CAC (chambres) | 63.6 % | | |
| 47 | −| SDB (salles de bains) | 54.5 % | | |
| 48 | −| Année de construction | 81.8 % (dont rôle : 22.2 %) | | |
| 49 | −| Taxes / évaluation municipale | 81.8 % | | |
| 46 | +| CAC (chambres) | 60.0 % | | |
| 47 | +| SDB (salles de bains) | 60.0 % | | |
| 48 | +| Année de construction | 80.0 % (dont rôle : 12.5 %) | | |
| 49 | +| Taxes / évaluation municipale | 90.0 % | | |
| 50 | 50 | | Estimation Vrai-Prix (rôle) | 100.0 % | |
| 51 | 51 | |
| 52 | 52 | ## Synchronisation |
modified
docs/connecteurs/via_ag_select.md
+6 −6
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Via Capitale Select (`via_ag_select`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
@@ -38,15 +38,15 @@ | ||
| 38 | 38 | |---|---| |
| 39 | 39 | | Annonces en base (toutes) | 611 | |
| 40 | 40 | | Actives | 580 | |
| 41 | −| Visibles (après dédup) | 17 | | |
| 42 | −| Masquées par la dédup | 563 | | |
| 41 | +| Visibles (après dédup) | 13 | | |
| 42 | +| Masquées par la dédup | 567 | | |
| 43 | 43 | | GPS (lat/lng) | 100.0 % | |
| 44 | 44 | | Photos | 100.0 % | |
| 45 | 45 | | Prix | 100.0 % | |
| 46 | −| CAC (chambres) | 70.6 % | | |
| 47 | −| SDB (salles de bains) | 70.6 % | | |
| 46 | +| CAC (chambres) | 61.5 % | | |
| 47 | +| SDB (salles de bains) | 61.5 % | | |
| 48 | 48 | | Année de construction | 100.0 % (dont rôle : 0.0 %) | |
| 49 | −| Taxes / évaluation municipale | 94.1 % | | |
| 49 | +| Taxes / évaluation municipale | 92.3 % | | |
| 50 | 50 | | Estimation Vrai-Prix (rôle) | 100.0 % | |
| 51 | 51 | |
| 52 | 52 | ## Synchronisation |
modified
docs/connecteurs/via_capitale.md
+1 −1
@@ -1,6 +1,6 @@ | ||
| 1 | 1 | # Via Capitale (`via_capitale`) |
| 2 | 2 | |
| 3 | −*Généré le 2026-08-18 03:27 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 3 | +*Généré le 2026-08-18 06:06 par `scripts/gen_connector_docs.py` — fichier produit automatiquement, ne pas éditer à la main.* | |
| 4 | 4 | |
| 5 | 5 | ## Registre (`data/sources.json`) |
| 6 | 6 | |
added
immoka/connectors/guidehabitation.py
+150 −0
@@ -0,0 +1,150 @@ | ||
| 1 | +# ----------------------------------------------------------------------------- | |
| 2 | +# Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 3 | +# Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 4 | +# connectors/guidehabitation.py : Guide Habitation (guidehabitation.ca) | |
| 5 | +# Répertoire de référence des PROJETS NEUFS au Québec (condos et maisons | |
| 6 | +# neuves des promoteurs). Pages région /fr/projets-immobiliers/{region}/ | |
| 7 | +# rendues serveur avec microdonnées schema.org complètes par carte projet : | |
| 8 | +# adresse (streetAddress), ville, GPS, prix « À partir de » (itemprop=price), | |
| 9 | +# type (SingleFamilyResidence → maison, ApartmentComplex → condo), | |
| 10 | +# description, chambres offertes, photo. Aucune clé, aucun rendu JS. | |
| 11 | +# On écarte les projets LOCATIFS (prix mensuel / « locatif » dans le texte) : | |
| 12 | +# Immo-Ka couvre le neuf À VENDRE. external_id = data-id du projet. | |
| 13 | +# ----------------------------------------------------------------------------- | |
| 14 | +from __future__ import annotations | |
| 15 | + | |
| 16 | +import html as _html | |
| 17 | +import re | |
| 18 | + | |
| 19 | +from .base import BaseConnector | |
| 20 | +from ..schema import PropertyListing | |
| 21 | + | |
| 22 | +SITE = "https://www.guidehabitation.ca" | |
| 23 | + | |
| 24 | +# Régions du répertoire (repli si le sitemap est indisponible). | |
| 25 | +REGIONS = ["montreal", "monteregie", "laval", "laurentides", "lanaudiere", | |
| 26 | + "quebec", "estrie", "outaouais", "mauricie"] | |
| 27 | + | |
| 28 | +_SITEMAP_REGION_RE = re.compile(r'/fr/projets-immobiliers/([a-z-]+)/') | |
| 29 | +_CARD_SPLIT_RE = re.compile(r'(?=<article class="project-card )') | |
| 30 | +_ID_RE = re.compile(r'data-id="(\d+)"') | |
| 31 | +_URL_RE = re.compile(r'href="(https://www\.guidehabitation\.ca/fr/\d+/[^"]+)"') | |
| 32 | +_IMG_RE = re.compile(r'<img[^>]+src="([^"]+)"') | |
| 33 | +_META_RE = re.compile(r'itemprop="(name|streetAddress|addressLocality|latitude|' | |
| 34 | + r'longitude|price)"[^>]*content="([^"]*)"') | |
| 35 | +_LOCALITY_RE = re.compile(r'itemprop="addressLocality">([^<]*)<') | |
| 36 | +_NAME_H3_RE = re.compile(r'<h3 itemprop="name">([^<]*)</h3>') | |
| 37 | +_DESC_RE = re.compile(r'itemprop="description">([^<]*)<') | |
| 38 | +_TYPE_RE = re.compile(r'itemtype="https://schema\.org/(SingleFamilyResidence|' | |
| 39 | + r'ApartmentComplex|Residence)"') | |
| 40 | +_BEDROOMS_RE = re.compile(r'class="card-bedrooms">([^<]*)<') | |
| 41 | +_PRICE_TXT_RE = re.compile(r'À partir de\s*([\d\s ,.]+)\s*\$') | |
| 42 | +_RENTAL_RE = re.compile(r'locati|à louer|for rent', re.I) | |
| 43 | + | |
| 44 | +# En deçà de ce prix « à partir de », c'est un loyer mensuel (projet locatif). | |
| 45 | +MIN_SALE_PRICE = 50_000 | |
| 46 | + | |
| 47 | + | |
| 48 | +class GuideHabitationConnector(BaseConnector): | |
| 49 | + source_id = "guidehabitation" | |
| 50 | + request_delay = 1.0 | |
| 51 | + | |
| 52 | + def _regions(self) -> list[str]: | |
| 53 | + try: | |
| 54 | + xml = self.get(f"{SITE}/sitemap.xml").text | |
| 55 | + found = sorted({m.group(1) for m in _SITEMAP_REGION_RE.finditer(xml)}) | |
| 56 | + if found: | |
| 57 | + return found | |
| 58 | + except Exception: | |
| 59 | + pass | |
| 60 | + return REGIONS | |
| 61 | + | |
| 62 | + def fetch(self) -> list[PropertyListing]: | |
| 63 | + by_id: dict[str, PropertyListing] = {} | |
| 64 | + for region in self._regions(): | |
| 65 | + try: | |
| 66 | + html = self.get(f"{SITE}/fr/projets-immobiliers/{region}/").text | |
| 67 | + except Exception: | |
| 68 | + continue | |
| 69 | + for card in _CARD_SPLIT_RE.split(html): | |
| 70 | + if 'data-id="' not in card: | |
| 71 | + continue | |
| 72 | + lst = self._to_listing(card, region) | |
| 73 | + if lst and lst.external_id not in by_id: | |
| 74 | + by_id[lst.external_id] = lst | |
| 75 | + return list(by_id.values()) | |
| 76 | + | |
| 77 | + def _to_listing(self, card: str, region: str) -> PropertyListing | None: | |
| 78 | + mid = _ID_RE.search(card) | |
| 79 | + murl = _URL_RE.search(card) | |
| 80 | + if not mid or not murl: | |
| 81 | + return None | |
| 82 | + meta = {k: _html.unescape(v).strip() for k, v in _META_RE.findall(card)} | |
| 83 | + name = meta.get("name") or "" | |
| 84 | + mh3 = _NAME_H3_RE.search(card) | |
| 85 | + if mh3: | |
| 86 | + name = _html.unescape(mh3.group(1)).strip() or name | |
| 87 | + desc = "" | |
| 88 | + mdesc = _DESC_RE.search(card) | |
| 89 | + if mdesc: | |
| 90 | + desc = _html.unescape(mdesc.group(1)).strip() | |
| 91 | + # prix « À partir de » — absent ou mensuel (locatif) → hors périmètre | |
| 92 | + price = None | |
| 93 | + try: | |
| 94 | + price = float(meta.get("price")) | |
| 95 | + except (TypeError, ValueError): | |
| 96 | + mtxt = _PRICE_TXT_RE.search(card) | |
| 97 | + if mtxt: | |
| 98 | + try: | |
| 99 | + price = float(re.sub(r"[\s ,]", "", mtxt.group(1))) | |
| 100 | + except ValueError: | |
| 101 | + price = None | |
| 102 | + if price is None or price < MIN_SALE_PRICE: | |
| 103 | + return None | |
| 104 | + if _RENTAL_RE.search(name) or _RENTAL_RE.search(desc): | |
| 105 | + return None | |
| 106 | + mtype = _TYPE_RE.search(card) | |
| 107 | + ptype = {"SingleFamilyResidence": "Maison", | |
| 108 | + "ApartmentComplex": "Condo"}.get( | |
| 109 | + mtype.group(1) if mtype else "", "") | |
| 110 | + city = meta.get("addressLocality") or "" | |
| 111 | + if not city: | |
| 112 | + mloc = _LOCALITY_RE.search(card) | |
| 113 | + if mloc: | |
| 114 | + city = _html.unescape(mloc.group(1)).strip() | |
| 115 | + address = meta.get("streetAddress") or "" | |
| 116 | + # « Chemin du Golf, Sainte-Julie, QC, Canada » → rue seulement | |
| 117 | + address = re.sub(r",\s*(QC|Québec|Quebec)\b.*$", "", address).strip() | |
| 118 | + if city and address.lower().endswith(", " + city.lower()): | |
| 119 | + address = address[: -(len(city) + 2)].strip().rstrip(",") | |
| 120 | + lst = PropertyListing( | |
| 121 | + source=self.source_id, | |
| 122 | + external_id=mid.group(1), | |
| 123 | + url=murl.group(1), | |
| 124 | + title=name, | |
| 125 | + address=address or name, | |
| 126 | + city=city, | |
| 127 | + property_type=ptype, | |
| 128 | + price=price, | |
| 129 | + price_label=f"À partir de {price:,.0f} $".replace(",", " "), | |
| 130 | + description=desc, | |
| 131 | + broker_name="Guide Habitation — projet neuf", | |
| 132 | + agency="Guide Habitation (projets neufs)", | |
| 133 | + ) | |
| 134 | + mimg = _IMG_RE.search(card) | |
| 135 | + if mimg: | |
| 136 | + lst.images = [mimg.group(1)] | |
| 137 | + try: | |
| 138 | + lst.lat = float(meta.get("latitude")) | |
| 139 | + lst.lng = float(meta.get("longitude")) | |
| 140 | + except (TypeError, ValueError): | |
| 141 | + pass | |
| 142 | + mbeds = _BEDROOMS_RE.search(card) | |
| 143 | + if mbeds: | |
| 144 | + beds = re.findall(r"(\d+)\s*ch", mbeds.group(1)) | |
| 145 | + if beds: | |
| 146 | + lst.bedrooms = int(beds[0]) # minimum offert | |
| 147 | + lst.details["Chambres offertes"] = _html.unescape( | |
| 148 | + mbeds.group(1)).strip() | |
| 149 | + lst.details["Projet neuf"] = True | |
| 150 | + return lst | |
added
immoka/connectors/realtor_ca.py
+191 −0
@@ -0,0 +1,191 @@ | ||
| 1 | +# ----------------------------------------------------------------------------- | |
| 2 | +# Immo-Ka — Agrégateur de maisons à vendre (province de Québec) | |
| 3 | +# Auteur : Simon-Pierre Boucher — contact@spboucher.ai | |
| 4 | +# connectors/realtor_ca.py : Realtor.ca (couverture MLS pan-bannières, QC) | |
| 5 | +# API interne https://api2.realtor.ca/Listing.svc/PropertySearch_Post (POST | |
| 6 | +# form). Protégée (DataDome/Incapsula) : l'accès direct renvoie 403, mais | |
| 7 | +# l'API se REJOUE via Scrapfly ASP SANS render_js (1 crédit-appel ASP, pas de | |
| 8 | +# navigateur) → JSON complet : n° MLS, GPS, prix, CAC/SDB, superficie, photos, | |
| 9 | +# courtier + agence. Vérifié 2026-08-18 : 200 fiches/page, plafond serveur | |
| 10 | +# 600 fiches (MaxRecords) par recherche → SHARDING par boîtes lat/lng | |
| 11 | +# couvrant le Québec, tri « plus récentes d'abord » (Sort=6-D). | |
| 12 | +# | |
| 13 | +# BUDGET BORNÉ : IMMOKA_REALTOR_MAX fiches max par sync (défaut 2 000, soit | |
| 14 | +# ~10 appels Scrapfly), réparties en balayant la page 1 de chaque shard puis | |
| 15 | +# les pages 2-3 si le budget le permet. Les fiches plus anciennes sortent de | |
| 16 | +# la fenêtre au fil des syncs (miss_count → active=0) : le connecteur vaut | |
| 17 | +# surtout pour les inscriptions récentes des bannières non couvertes. | |
| 18 | +# Mettre IMMOKA_REALTOR_MAX=0 pour désactiver le connecteur. | |
| 19 | +# | |
| 20 | +# source_id « realtor_ag_ca » : l'infixe _ag_ + external_id = n° MLS Centris | |
| 21 | +# activent la dédup existante — toute fiche déjà couverte par un connecteur | |
| 22 | +# direct (RE/MAX, Royal LePage, Sutton…) est masquée, seules les fiches | |
| 23 | +# UNIQUES (petites bannières sans connecteur) restent visibles. | |
| 24 | +# ----------------------------------------------------------------------------- | |
| 25 | +from __future__ import annotations | |
| 26 | + | |
| 27 | +import json | |
| 28 | +import os | |
| 29 | + | |
| 30 | +from .base import BaseConnector | |
| 31 | +from ..schema import PropertyListing | |
| 32 | + | |
| 33 | +SEARCH_URL = "https://api2.realtor.ca/Listing.svc/PropertySearch_Post" | |
| 34 | +SITE = "https://www.realtor.ca" | |
| 35 | + | |
| 36 | +MAX_RECORDS = int(os.environ.get("IMMOKA_REALTOR_MAX", "2000")) | |
| 37 | +PER_PAGE = 200 # maximum accepté par l'API | |
| 38 | +MAX_PAGES_PER_SHARD = 3 # plafond serveur : MaxRecords=600 par recherche | |
| 39 | + | |
| 40 | +# Boîtes (sud, ouest, nord, est) couvrant le Québec habité, par densité | |
| 41 | +# décroissante — le budget est d'abord dépensé sur les marchés actifs. | |
| 42 | +SHARDS: list[tuple[str, float, float, float, float]] = [ | |
| 43 | + ("montreal-laval", 45.35, -74.05, 45.75, -73.30), | |
| 44 | + ("monteregie", 45.00, -74.40, 45.35, -72.80), | |
| 45 | + ("rive-sud-est", 45.35, -73.30, 45.75, -72.80), | |
| 46 | + ("laurentides-lanaudiere", 45.75, -74.80, 46.40, -73.20), | |
| 47 | + ("quebec-metro", 46.55, -71.65, 47.10, -70.90), | |
| 48 | + ("chaudiere-appalaches", 46.00, -71.80, 46.85, -70.00), | |
| 49 | + ("estrie", 45.00, -72.80, 45.90, -71.50), | |
| 50 | + ("mauricie-cdq", 45.90, -73.20, 46.90, -71.80), | |
| 51 | + ("outaouais", 45.30, -77.60, 46.50, -74.80), | |
| 52 | + ("saguenay-lac-st-jean", 48.00, -72.60, 48.80, -70.70), | |
| 53 | + ("bas-st-laurent-gaspesie", 47.20, -70.60, 49.40, -64.00), | |
| 54 | + ("charlevoix-cote-nord", 47.00, -71.00, 50.40, -65.90), | |
| 55 | + ("abitibi-temiscamingue", 47.20, -79.60, 48.90, -77.40), | |
| 56 | + ("hautes-laurentides", 46.40, -76.00, 47.20, -74.20), | |
| 57 | +] | |
| 58 | + | |
| 59 | + | |
| 60 | +class RealtorCaConnector(BaseConnector): | |
| 61 | + source_id = "realtor_ag_ca" | |
| 62 | + request_delay = 0.2 # Scrapfly gère la politesse côté cible | |
| 63 | + use_detail_cache = False # tout est déjà dans la réponse liste | |
| 64 | + | |
| 65 | + def _search(self, shard: tuple, page: int) -> dict: | |
| 66 | + _, south, west, north, east = shard | |
| 67 | + body = "&".join(f"{k}={v}" for k, v in { | |
| 68 | + "ZoomLevel": 10, | |
| 69 | + "LatitudeMax": north, "LongitudeMax": east, | |
| 70 | + "LatitudeMin": south, "LongitudeMin": west, | |
| 71 | + "Sort": "6-D", # inscription la plus récente d'abord | |
| 72 | + "PropertyTypeGroupID": 1, # résidentiel | |
| 73 | + "TransactionTypeId": 2, # à vendre | |
| 74 | + "PropertySearchTypeId": 0, | |
| 75 | + "Currency": "CAD", | |
| 76 | + "RecordsPerPage": PER_PAGE, | |
| 77 | + "CurrentPage": page, | |
| 78 | + "CultureId": 1, | |
| 79 | + "ApplicationId": 1, | |
| 80 | + "PropertyStatusId": 1, | |
| 81 | + "Version": "7.0", | |
| 82 | + }.items()) | |
| 83 | + result = self.scrapfly( | |
| 84 | + SEARCH_URL, render_js=False, asp=True, method="POST", body=body, | |
| 85 | + headers={ | |
| 86 | + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", | |
| 87 | + "Referer": "https://www.realtor.ca/", | |
| 88 | + "Origin": "https://www.realtor.ca", | |
| 89 | + }) | |
| 90 | + try: | |
| 91 | + return json.loads(result.get("content") or "") | |
| 92 | + except ValueError: | |
| 93 | + return {} | |
| 94 | + | |
| 95 | + def fetch(self) -> list[PropertyListing]: | |
| 96 | + if MAX_RECORDS <= 0: | |
| 97 | + return [] | |
| 98 | + by_id: dict[str, PropertyListing] = {} | |
| 99 | + exhausted: set[str] = set() | |
| 100 | + for page in range(1, MAX_PAGES_PER_SHARD + 1): | |
| 101 | + for shard in SHARDS: | |
| 102 | + name = shard[0] | |
| 103 | + if name in exhausted or len(by_id) >= MAX_RECORDS: | |
| 104 | + continue | |
| 105 | + data = self._search(shard, page) | |
| 106 | + results = data.get("Results") or [] | |
| 107 | + if len(results) < PER_PAGE: | |
| 108 | + exhausted.add(name) | |
| 109 | + if not results: | |
| 110 | + continue | |
| 111 | + for item in results: | |
| 112 | + lst = self._to_listing(item) | |
| 113 | + if lst and lst.external_id not in by_id: | |
| 114 | + by_id[lst.external_id] = lst | |
| 115 | + if len(by_id) >= MAX_RECORDS: | |
| 116 | + break | |
| 117 | + return list(by_id.values()) | |
| 118 | + | |
| 119 | + def _to_listing(self, item: dict) -> PropertyListing | None: | |
| 120 | + prop = item.get("Property") or {} | |
| 121 | + addr = prop.get("Address") or {} | |
| 122 | + text = addr.get("AddressText") or "" | |
| 123 | + # « 680 Rue De Courcelle|#613|Montréal (Le Sud-Ouest), Quebec H4C0B8 » | |
| 124 | + if ", Quebec" not in text and ", Québec" not in text: | |
| 125 | + return None # les shards frontaliers débordent (Ottawa, N.-B.) | |
| 126 | + parts = [p.strip() for p in text.split("|")] | |
| 127 | + locality = parts[-1] if parts else "" | |
| 128 | + street = ", ".join(parts[:-1]) if len(parts) > 1 else "" | |
| 129 | + city = sector = "" | |
| 130 | + loc = locality.split(", Quebec")[0].split(", Québec")[0] | |
| 131 | + if "(" in loc: | |
| 132 | + city, _, rest = loc.partition("(") | |
| 133 | + city, sector = city.strip(), rest.rstrip(")").strip() | |
| 134 | + else: | |
| 135 | + city = loc.strip() | |
| 136 | + mls = str(item.get("MlsNumber") or "").strip() | |
| 137 | + rid = str(item.get("Id") or "").strip() | |
| 138 | + if not (mls or rid) or not street: | |
| 139 | + return None | |
| 140 | + try: | |
| 141 | + price = float(prop.get("PriceUnformattedValue")) | |
| 142 | + except (TypeError, ValueError): | |
| 143 | + price = None | |
| 144 | + building = item.get("Building") or {} | |
| 145 | + lst = PropertyListing( | |
| 146 | + source=self.source_id, | |
| 147 | + external_id=mls or rid, | |
| 148 | + url=f"{SITE}{item.get('RelativeDetailsURL') or ''}", | |
| 149 | + title=f"{building.get('Type') or prop.get('Type') or ''} — {city}".strip(" —"), | |
| 150 | + address=street, | |
| 151 | + sector=sector, | |
| 152 | + city=city, | |
| 153 | + property_type=building.get("Type") or prop.get("Type") or "", | |
| 154 | + price=price, | |
| 155 | + price_label=prop.get("Price") or "", | |
| 156 | + mls=mls, | |
| 157 | + description=(item.get("PublicRemarks") or "").strip(), | |
| 158 | + ) | |
| 159 | + try: | |
| 160 | + lst.lat = float(addr.get("Latitude")) | |
| 161 | + lst.lng = float(addr.get("Longitude")) | |
| 162 | + except (TypeError, ValueError): | |
| 163 | + pass | |
| 164 | + beds = str(building.get("Bedrooms") or "") | |
| 165 | + if beds: | |
| 166 | + try: # « 3 + 1 » → 4 | |
| 167 | + lst.bedrooms = sum(int(x) for x in beds.replace(" ", "").split("+") if x) | |
| 168 | + except ValueError: | |
| 169 | + pass | |
| 170 | + try: | |
| 171 | + lst.bathrooms = int(building.get("BathroomTotal")) | |
| 172 | + except (TypeError, ValueError): | |
| 173 | + pass | |
| 174 | + size = building.get("SizeInterior") or "" | |
| 175 | + if size: | |
| 176 | + lst.details["Superficie habitable"] = size | |
| 177 | + land = (item.get("Land") or {}).get("SizeTotal") or "" | |
| 178 | + if land: | |
| 179 | + lst.details["Superficie du terrain"] = land | |
| 180 | + lst.images = [p.get("HighResPath") or p.get("MedResPath") | |
| 181 | + for p in (prop.get("Photo") or []) if isinstance(p, dict)] | |
| 182 | + lst.images = [u for u in lst.images if u] | |
| 183 | + ind = (item.get("Individual") or [{}])[0] | |
| 184 | + lst.broker_name = ind.get("Name") or "" | |
| 185 | + org = ind.get("Organization") or {} | |
| 186 | + lst.agency = org.get("Name") or "" | |
| 187 | + phones = ind.get("Phones") or [] | |
| 188 | + if phones: | |
| 189 | + p0 = phones[0] | |
| 190 | + lst.broker_phone = f"{p0.get('AreaCode', '')} {p0.get('PhoneNumber', '')}".strip() | |
| 191 | + return lst | |
modified
immoka/connectors/sothebys_quebec.py
+148 −19
@@ -2,11 +2,19 @@ | ||
| 2 | 2 | # Immo-Ka — Agrégateur de maisons à vendre (province de Québec) |
| 3 | 3 | # Auteur : Simon-Pierre Boucher — contact@spboucher.ai |
| 4 | 4 | # connectors/sothebys_quebec.py : Sotheby's International Realty Québec |
| 5 | −# Recherche rendue côté client : le grid public est plafonné (~40/page) et la | |
| 6 | −# pagination passe par du JS (pas d'URL). On SHARD donc par région | |
| 7 | −# administrative du Québec (chaque page « region-{slug}-real-estate » renvoie | |
| 8 | −# son lot), on dédoublonne par id, puis on enrichit chaque fiche via son | |
| 9 | −# JSON-LD `Product` (prix, galerie S3 complète, description, n° MLS = sku). | |
| 5 | +# Inventaire COMPLET via l'API AJAX interne du site : | |
| 6 | +# GET /include/ajax_results.php?dowhat=getgridresults&token=…&p_territories[]=4 | |
| 7 | +# (territoire 4 = province de Québec ; jeton `ajaxtoken` exposé dans la page | |
| 8 | +# /en/search-results/province-quebec-real-estate/). Pagination 64 fiches/page. | |
| 9 | +# Particularité serveur : les valeurs du filtre statut de l'interface | |
| 10 | +# (1 = For Sale, 3 = For Rent) sont REMAPPÉES côté serveur — `p_status[]=1` | |
| 11 | +# renvoie 0 résultat et `p_status[]=3` seulement les locations. On passe donc | |
| 12 | +# une valeur neutre (2) qui désactive le filtre et renvoie TOUT l'inventaire | |
| 13 | +# actif (vente + location), puis on écarte les locations (« …/mo ») au parsing. | |
| 14 | +# Chaque carte porte data-lat/lng/img/price + adresse/ville + CAC/SDB. | |
| 15 | +# Enrichissement fiche détail (JSON-LD Product) : prix, galerie S3 complète, | |
| 16 | +# description, n° MLS = sku. Repli : ancien parcours des pages région si | |
| 17 | +# l'AJAX venait à changer. | |
| 10 | 18 | # ----------------------------------------------------------------------------- |
| 11 | 19 | from __future__ import annotations |
| 12 | 20 | |
@@ -21,20 +29,29 @@ from ..schema import PropertyListing | ||
| 21 | 29 | |
| 22 | 30 | SITE = "https://sothebysrealty.ca" |
| 23 | 31 | DETAIL_LIMIT = int(os.environ.get("IMMOKA_SOTHEBYS_DETAIL_LIMIT", "400")) |
| 32 | +# ~18 pages × 64 = tout l'inventaire QC (~1 100 fiches) ; borne de sécurité. | |
| 33 | +MAX_PAGES = int(os.environ.get("IMMOKA_SOTHEBYS_MAX_PAGES", "30")) | |
| 34 | +QC_TERRITORY = 4 # p_territories[] = province de Québec | |
| 24 | 35 | |
| 25 | −# Régions administratives du Québec (slugs de recherche Sotheby's). | |
| 36 | +# Régions administratives du Québec (repli si l'AJAX casse). | |
| 26 | 37 | QC_REGIONS = [ |
| 27 | 38 | "region-montreal", "region-laval", "region-monteregie", "region-laurentides", |
| 28 | 39 | "region-lanaudiere", "region-eastern-townships", "region-outaouais", |
| 29 | 40 | "region-capitale-nationale", "region-mauricie", "region-centre-du-quebec", |
| 30 | 41 | "region-chaudiere-appalaches", "region-bas-saint-laurent", |
| 31 | 42 | "region-saguenay-lac-saint-jean", "region-cote-nord", "region-charlevoix", |
| 32 | − "region-gaspesie", "region-abitibi-temiscamingue", | |
| 43 | + "region-gaspesie-iles-de-la-madeleine", "region-abitibi-temiscamingue", | |
| 33 | 44 | ] |
| 34 | 45 | |
| 35 | 46 | _PROP_RE = re.compile( |
| 36 | 47 | r'/(?:fr|en)/property/quebec/region-([a-z-]+)/([a-z0-9-]+?)-real-estate/(\d{5,})/([a-z0-9-]+)/', |
| 37 | 48 | re.I) |
| 49 | +_TOKEN_RE = re.compile(r"var ajaxtoken = '([a-f0-9]+)'") | |
| 50 | +_CARD_SPLIT_RE = re.compile(r'(?=<div class="mprop )') | |
| 51 | +_ATTR_RE = re.compile(r'data-(lat|lng|img|price|id)="([^"]*)"') | |
| 52 | +_LOC_RE = re.compile(r'<p class="location">([^<]*)</p>') | |
| 53 | +_BED_RE = re.compile(r'(\d{1,2})\s*BEDS?', re.I) | |
| 54 | +_BATH_RE = re.compile(r'(\d{1,2})\s*BATHS?', re.I) | |
| 38 | 55 | |
| 39 | 56 | |
| 40 | 57 | class SothebysQuebecConnector(BaseConnector): |
@@ -42,8 +59,8 @@ class SothebysQuebecConnector(BaseConnector): | ||
| 42 | 59 | request_delay = 1.0 |
| 43 | 60 | |
| 44 | 61 | def _get_tolerant(self, url: str) -> str: |
| 45 | − """GET qui ignore le statut HTTP : les pages de résultats Sotheby's | |
| 46 | − renvoient un 404 tout en servant le contenu complet.""" | |
| 62 | + """GET qui ignore le statut HTTP : certaines pages Sotheby's renvoient | |
| 63 | + un 404 tout en servant le contenu complet.""" | |
| 47 | 64 | import time |
| 48 | 65 | wait = self.request_delay - (time.time() - self._last_request) |
| 49 | 66 | if wait > 0: |
@@ -52,23 +69,135 @@ class SothebysQuebecConnector(BaseConnector): | ||
| 52 | 69 | self._last_request = time.time() |
| 53 | 70 | return resp.text |
| 54 | 71 | |
| 72 | + # -- API AJAX interne ------------------------------------------------------- | |
| 73 | + def _ajax_token(self) -> str: | |
| 74 | + html = self._get_tolerant( | |
| 75 | + f"{SITE}/en/search-results/province-quebec-real-estate/") | |
| 76 | + m = _TOKEN_RE.search(html) | |
| 77 | + return m.group(1) if m else "" | |
| 78 | + | |
| 79 | + def _ajax_page(self, token: str, page: int) -> dict: | |
| 80 | + params = { | |
| 81 | + "dowhat": "getgridresults", "token": token, "agent_slug": "", | |
| 82 | + "aid": 0, "team_id": 0, "view": "grid", "sort": 1, | |
| 83 | + "p_bed": 0, "p_bath": 0, "p_mls": 1, "p_minprice": 0, | |
| 84 | + "p_maxprice": 0, "p_status[]": 2, "p_territories[]": QC_TERRITORY, | |
| 85 | + "search_type_init": 2, "per_page": 64, "per_page_init": 64, | |
| 86 | + "page": page, "map_data": 0, "device": "desktop", | |
| 87 | + "device_width": 1440, "start": "", "crawler": 0, "office": 0, | |
| 88 | + "development": 0, "igallery": 0, "boundary_trap": 0, | |
| 89 | + "pagetype": "", "do_int": 0, "extrasearch": "", "results_qty": 0, | |
| 90 | + } | |
| 91 | + resp = self.get(f"{SITE}/include/ajax_results.php", params=params, | |
| 92 | + headers={"X-Requested-With": "XMLHttpRequest", | |
| 93 | + "Referer": f"{SITE}/en/search-results/"}) | |
| 94 | + try: | |
| 95 | + return resp.json() | |
| 96 | + except ValueError: | |
| 97 | + return {} | |
| 98 | + | |
| 55 | 99 | def fetch(self) -> list[PropertyListing]: |
| 56 | 100 | by_id: dict[str, PropertyListing] = {} |
| 57 | − for region in QC_REGIONS: | |
| 58 | − url = f"{SITE}/en/search-results/{region}-real-estate/" | |
| 59 | − try: | |
| 60 | − html = self._get_tolerant(url) | |
| 61 | − except Exception: | |
| 62 | − continue | |
| 63 | − for m in _PROP_RE.finditer(html): | |
| 64 | − lst = self._to_listing(m) | |
| 65 | − if lst and lst.external_id not in by_id: | |
| 66 | − by_id[lst.external_id] = lst | |
| 101 | + try: | |
| 102 | + token = self._ajax_token() | |
| 103 | + if token: | |
| 104 | + total = None | |
| 105 | + for page in range(1, MAX_PAGES + 1): | |
| 106 | + data = self._ajax_page(token, page) | |
| 107 | + cards_html = (data or {}).get("properties") or "" | |
| 108 | + if total is None: | |
| 109 | + try: | |
| 110 | + total = int(data.get("results") or 0) | |
| 111 | + except (TypeError, ValueError): | |
| 112 | + total = 0 | |
| 113 | + found = False | |
| 114 | + for card in _CARD_SPLIT_RE.split(cards_html): | |
| 115 | + if 'data-id="' not in card: | |
| 116 | + continue | |
| 117 | + found = True | |
| 118 | + lst = self._card_to_listing(card) | |
| 119 | + if lst and lst.external_id not in by_id: | |
| 120 | + by_id[lst.external_id] = lst | |
| 121 | + if not found or (total and len(by_id) >= total): | |
| 122 | + break | |
| 123 | + except Exception: | |
| 124 | + pass | |
| 125 | + if not by_id: # repli : parcours des pages région (ancienne méthode) | |
| 126 | + for region in QC_REGIONS: | |
| 127 | + url = f"{SITE}/en/search-results/{region}-province-quebec-real-estate/" | |
| 128 | + try: | |
| 129 | + html = self._get_tolerant(url) | |
| 130 | + except Exception: | |
| 131 | + continue | |
| 132 | + for m in _PROP_RE.finditer(html): | |
| 133 | + lst = self._to_listing(m) | |
| 134 | + if lst and lst.external_id not in by_id: | |
| 135 | + by_id[lst.external_id] = lst | |
| 67 | 136 | listings = list(by_id.values()) |
| 68 | 137 | # fiche détail : JSON-LD Product (prix, galerie complète, description, MLS) |
| 69 | 138 | du.enrich(self, listings, DETAIL_LIMIT, parse_sothebys_detail, key="v1") |
| 70 | 139 | return listings |
| 71 | 140 | |
| 141 | + def _card_to_listing(self, card: str) -> PropertyListing | None: | |
| 142 | + attrs = dict(_ATTR_RE.findall(card)) | |
| 143 | + pid = attrs.get("id") | |
| 144 | + if not pid: | |
| 145 | + return None | |
| 146 | + price_label = _html.unescape(attrs.get("price") or "").strip() | |
| 147 | + # hors périmètre « à vendre » : locations («…/mo») et fiches sans prix | |
| 148 | + # affiché (« Sold », « Price upon request »…) — p_status neutre renvoie | |
| 149 | + # tout l'inventaire, on filtre ici. | |
| 150 | + if "/mo" in price_label or not re.search(r"\d", price_label): | |
| 151 | + return None | |
| 152 | + m = _PROP_RE.search(card) | |
| 153 | + if m: | |
| 154 | + region_slug, city_slug, _, addr_slug = m.groups() | |
| 155 | + url = (f"{SITE}/fr/property/quebec/region-{region_slug}/" | |
| 156 | + f"{city_slug}-real-estate/{pid}/{addr_slug}/") | |
| 157 | + region = _deslug(region_slug) | |
| 158 | + else: | |
| 159 | + url = f"{SITE}/en/property/{pid}/" | |
| 160 | + region = "" | |
| 161 | + loc = _LOC_RE.search(card) | |
| 162 | + address = city = "" | |
| 163 | + title = "" | |
| 164 | + if loc: | |
| 165 | + title = _html.unescape(loc.group(1)).strip() | |
| 166 | + parts = [p.strip() for p in title.split(",")] | |
| 167 | + address = parts[0] if parts else "" | |
| 168 | + # "28 Av. de la Gare, Saint-Sauveur, Quebec" → ville = avant-dernier | |
| 169 | + if len(parts) >= 2: | |
| 170 | + city = parts[-2] if parts[-1].lower() in ("quebec", "québec") \ | |
| 171 | + else parts[-1] | |
| 172 | + if not title and m: | |
| 173 | + title = _deslug(m.group(4)) | |
| 174 | + lst = PropertyListing( | |
| 175 | + source=self.source_id, | |
| 176 | + external_id=str(pid), | |
| 177 | + url=url, | |
| 178 | + title=title, | |
| 179 | + address=address, | |
| 180 | + city=city, | |
| 181 | + region=region, | |
| 182 | + price_label=price_label, | |
| 183 | + broker_name="Sotheby's International Realty Québec", | |
| 184 | + ) | |
| 185 | + mb = _BED_RE.search(card) | |
| 186 | + if mb and int(mb.group(1)) <= 20: | |
| 187 | + lst.bedrooms = int(mb.group(1)) | |
| 188 | + ms = _BATH_RE.search(card) | |
| 189 | + if ms and int(ms.group(1)) <= 20: | |
| 190 | + lst.bathrooms = int(ms.group(1)) | |
| 191 | + try: | |
| 192 | + lst.lat = float(attrs.get("lat") or "") | |
| 193 | + lst.lng = float(attrs.get("lng") or "") | |
| 194 | + except ValueError: | |
| 195 | + lst.lat = lst.lng = None | |
| 196 | + img = attrs.get("img") or "" | |
| 197 | + if img: | |
| 198 | + lst.images = [re.sub(r'(?:nr|m)?\.jpg$', 'r.jpg', img)] | |
| 199 | + return lst | |
| 200 | + | |
| 72 | 201 | def _to_listing(self, m: re.Match) -> PropertyListing | None: |
| 73 | 202 | region_slug, city_slug, pid, addr_slug = m.group(1), m.group(2), m.group(3), m.group(4) |
| 74 | 203 | url = f"{SITE}/fr/property/quebec/region-{region_slug}/{city_slug}-real-estate/{pid}/{addr_slug}/" |
| 75 | 204 | |