+
    j!"                       R t ^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 ^ RI
t
^ RIHt ]! ]4      P                  4       P                  P                  t]! ]4      ]P$                  9  d#   ]P$                  P'                  ^ ]! ]4      4       ^ RIHtHtHt / RR*bRR+bR	R,bR
R-bRR.bRR/bRR0bRR1bRR2bRR3bRR4bRR5bRR6bRR7bRR8bRR9bRR:bRR;RR<RR=RR>RR?/CtRt]R,           tRt]P8                  ! R 4      t]P8                  ! R!4      t]P8                  ! R"4      t]P8                  ! R#4      t ]P8                  ! R$4      t!]P8                  ! R%4      t"R& R' lt# ! R( R)]4      t$R# )@ut  Immonot.com — Notaires de France property listings.

Picked over pap.fr (Cloudflare-blocked 2026-05-25) because immonot serves
HTML cleanly to standard requests and represents a distinct market slice:
notary-listed properties, often estate sales / family transfers / divorce
splits — direct seller-to-buyer with the notary as intermediary. No agent
commission. Frequently the cheapest comparable properties in a département.

URL pattern (verified 2026-05-25):
  https://www.immonot.com/recherche-annonces-par-departement/VENT/MAIS/{dept_code}/Achat-Maison-{dept_slug}.html
  VENT = vente (sale, vs LOC = location/rent)
  MAIS = maison (vs APPT = appartement, TERR = terrain)

Card structure: div.il-card-content per listing, with:
  - a.reset-link[href^="/annonce-..."] (detail URL)
  - h2.il-card-title > strong.il-card-locale (city + postcode)
  - div.il-card-price > strong (price text)
  - Card text contains: "Intérieur X m 2", "Extérieur Y m", "Pièces N", "Chb. M"

Pagination not yet handled — first page returns ~12 results per département,
which is enough for the weekly cadence and small enough to not annoy the site.
)annotationsN)Path)Iterator)BeautifulSoup)PropertyHitSearchCriteriaSourcedromeardecheheraultgardcotes-d-armormorbihan	finisteredordognelotcreusecorrezecharentecharente-maritimecantalaveyronlozeretarntarn-et-garonnepyrenees-atlantiqueshautes-pyreneesaudepyrenees-orientaleszhttps://www.immonot.comzM/recherche-annonces-par-departement/VENT/MAIS/{code}/Achat-Maison-{slug}.htmlzuMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15u&   Int[ée]rieur\s+([\d ,.]+)\s*m\s*[²2]u   Ext[ée]rieur\s+([\d ,.]+)\s*mu   Pi[èe]ces\s+(\d+)zChb\.\s*(\d+)u   (\d[\d\s]*)\s*€z^(.+?)\s*-\s*(\d{5})\s*$c                    V ^8  d   QhRRRR/# )   textstrreturnz
int | None )formats   "W/Users/jonathan/Documents/Zakelijk/ClaudeOS/03_Lab/farmmatch/scraper/sources/immonot.py__annotate__r'   S   s     + +# +* +    c                p    V '       g   R# \         P                  ! RRV 4      pV'       d   \        V4      # R# )z-Strip spaces/commas/dots, return int or None.Nz[^\d] )resubint)r!   digitss   & r&   _to_intr/   S   s+    VVHb$'F 3v;*d*r(   c                  F    ] tR t^[tRtR.tRtR tR R ltRR R	 llt	R
t
R# )ImmonotSourceimmonotFRFc                	    \         P                  ! 4       V n        V P                  P                  P	                  R \
        RRRR/4       R# )z
User-AgentAcceptztext/html,application/xhtml+xmlzAccept-Languagezfr-FR,fr;q=0.9N)requestsSession_sessionheadersupdateUA)selfs   &r&   __init__ImmonotSource.__init__`   s@     ((*$$"7/&
 	r(   c                   V ^8  d   QhRR/# )r    r#   ztuple[bool, str]r$   )r%   s   "r&   r'   ImmonotSource.__annotate__h   s     0 0( 0r(   c                    V P                   P                  \        R,           ^RR7      pVP                  R8  d   RRVP                   23# R#   \        P
                   d#   pR\        T4      P                   3u Rp?# Rp?ii ; i)	zDGET probe against the search base URL (HEAD returns 405 on immonot)./T)timeoutallow_redirectsi  FzHTTP N)T	reachable)r8   getBASEstatus_coder6   RequestExceptiontype__name__)r<   res   &  r&   healthImmonotSource.healthh   s|    	0!!$*a!NA}}#amm_555$$(( 	0T!W--.//	0s$   A
A A B$B;BBNc               $    V ^8  d   QhRRRRRR/# )r    criteriar   
known_urlszset[str] | Noner#   zIterator[PropertyHit]r$   )r%   s   "r&   r'   r@   r   s(     u u~ u*u6Kur(   c              #  	
  "   VP                   R 8w  d   R# VP                  '       d   VP                  \        9  d   R# T;'       g    \        4       p\        VP                  ,          w  rE\        P                  WER7      p V P                  P                  V^R7      pTP                  ^8w  d(   \        RTP                   RTP                   24       R# \        TP                  R4      p	T	P!                  R4      p
^ pT
 EF  pTP"                  '       d   YP"                  8  d    EMTP%                  R	4      pT'       g   KD  TP                  R
R4      pTP'                  R4      '       d   \(        T,           MTpY9   d   K  RpR pTP%                  R4      pT'       dO   TP+                  RR7      p\,        P/                  T4      pT'       d    TP1                  ^4      P3                  4       pRpTP%                  R4      pT'       dK   TP+                  RRR7      p\4        P7                  T4      pT'       d   \9        TP1                  ^4      4      pTeM   TP:                  '       d   TTP:                  8  d   EK~  TP<                  '       d   TTP<                  8  d   EK  TP+                  RRR7      pRpRpRpRp\>        P7                  T4      pT'       dG   TP1                  ^4      PA                  RR4      PA                  RR4      p \C        \E        T4      4      p\H        P7                  T4      pT'       dG   TP1                  ^4      PA                  RR4      PA                  RR4      p \C        \E        T4      4      p\J        P7                  T4      pT'       d   \C        TP1                  ^4      4      p\L        P7                  T4      pT'       d   \C        TP1                  ^4      4      pTPN                  '       d   T;'       g    ^ TPN                  8  d   EK#  TPP                  '       d   T;'       g    ^ TPP                  8  d   EKS  TPR                  '       d   T;'       g    ^ TPR                  8  d   EK  \U        TRT;'       g    TP                  PW                  4        R2TTTTTTTTP                  R7      x  T^,          pEK  	  \X        PZ                  ! ^4       R#   \        P                   d:   p\        R\        T4      P                   RTP                   24        Rp?R# Rp?ii ; i  \F         d     EL-i ; i  \F         d     ELi ; i5i)r3   N)codeslug)rC   z    immonot: z on z    immonot: HTTP zhtml.parserzdiv.il-card-contentza.reset-link[href^="/annonce-"]hrefr*   rB   zstrong.il-card-localeT)stripzdiv.il-card-price ,.r2   z
 - immonot)urlsourcetitlepricecitycountrybuilding_size	land_sizeroomsbedroomssearch_region).r`   region
REGION_MAPsetSEARCH_URL_TEMPLATEr%   r8   rF   r6   rI   printrJ   rK   rH   r   r!   selectlimit
select_one
startswithrG   get_textRE_CITY_POSTCODEmatchgrouprW   RE_PRICE_DIGITSsearchr/   	min_price	max_price
RE_SURFACEreplacer-   float
ValueErrorRE_LANDRE_ROOMSRE_BEDSmin_building_m2min_land_m2min_bedroomsr   r]   timesleep)r<   rQ   rR   knownrT   rU   r[   rL   rM   soupcardsyieldedcardlinkrV   prop_urlr_   country_code	locale_ellocale_textmr^   price_el
price_text	card_textra   rb   rc   rd   vals   &&&                           r&   rt   ImmonotSource.searchr   sd    t#(//"C##ce0
!((d(>	!!#r!2A ==C&q}}oT(//9JKLQVV]312D~~~'^^";??#DED88FB'D&*ooc&:&:td{H  DL(?@I'00t0<$**;7771:++-D E':;H%..s$.?
#**:6#AGGAJ/E  %%%%(2D2D*D%%%%(2D2D*D c6I MIEH!!),Aggaj((c2::3C$'c
OM y)Aggaj((c2::3C #E#JI 	*AAGGAJy)Aqwwqz? ''']-?-?a8C[C[,[###a8;O;O(O$$$(--a8;P;P)P 88!6!6!89D$+#!&oo  qLGy | 	

1S (( 	M$q'"2"2!347HIJ	~ "  " s   %U(U(:U(S3  B$U(*U(03U($.U(9U(/U(=/U(-%U(AU(1U(U%U(1U(4UU(%6U(+U(U(&U(8U(&U((U(1$U(AU(3U.T<6U(<UU(UU(UU(U%!U($U%%U()r8   )N)rK   
__module____qualname____firstlineno__name	countriesrequires_authr=   rN   rt   __static_attributes__r$   r(   r&   r1   r1   [   s)    DIM0u ur(   r1   )26r	   )07r
   )34r   )30r   )22r   )56r   )29r   )24r   )46r   )23r   )19r   )16r   )17r   )15r   )12r   )48r   )81r   )82r   )64r   )65r   )11r   )66r   )%__doc__
__future__r   r+   sysr   pathlibr   typingr   r6   bs4r   __file__resolveparent
SCRIPT_DIRr"   pathinsertsources._baser   r   r   rg   rG   ri   r;   compilerw   r{   r|   r}   rs   rp   r/   r1   r$   r(   r&   <module>r      s  , # 	 
     (^##%,,33
z?#(("HHOOAs:' = =( ( ~	
 . ) * ) 
} ' ( ) 4 '  (!" '#$ ~%& 0:0
~8/
4 !ll %
 ZZAB

**6
7::+,
**%
&**12::9: +LF Lr(   