find-listing▌
french-property.com/find-listing-sujpf1 · updated May 21, 2026
MDX-style export adds YAML metadata + attribution linking explainx.ai and this canonical listing URL.
Search french-property.com for-sale listings by region, price, bedrooms, property type, habitable / land size, and keywords; return matching listings with title, reference, price, location, room counts, sizes, image, and URL.
| name | find-listing |
| title | French-Property.com Find Listings |
| description | >- Search french-property.com for-sale listings by region, price, bedrooms, property type, habitable / land size, and keywords; return matching listings with title, reference, price, location, room counts, sizes, image, and URL. |
| website | french-property.com |
| category | real-estate |
| tags | - real-estate - france - listings - search - url-param - read-only |
| source | 'browserbase: agent-runtime 2026-05-19' |
| updated | '2026-05-19' |
| recommended_method | url-param |
| alternative_methods | - method: browser rationale: >- Only needed for visual verification. The /properties-for-sale page is fully server-rendered, so URL-param fetch through a residential proxy returns the same HTML with all Schema.org microdata inline — driving a Browserbase session costs ~30x more without adding any signal. - method: api rationale: >- No public JSON API. The search form posts only to the same /properties-for-sale GET endpoint that the URL-param path already targets. |
| verified | true |
| proxies | true |
French-Property.com Find Listings
Purpose
Given a set of buyer characteristics (region, price range, bedroom count, property type, habitable / land size, free-text keywords, sort order), return the matching for-sale property listings on french-property.com — each with title, reference, price (EUR), region/department/commune, bedrooms/bathrooms, habitable + land sizes, listing URL, image URL, and description snippet. Read-only; never enquires, saves, or contacts vendors.
When to Use
- Buyer agent searching for French real estate within a budget, region, and structural criteria.
- Monitoring new listings matching a saved profile (re-fetch + diff on
reference). - Bulk enumeration across regions, departments, or feature flags (e.g. swimming pool, outbuildings) — sale side of the site.
- Anywhere you'd otherwise scrape french-property.com search HTML — the URL-param surface is faster than UI-driving, and the rendered HTML already carries Schema.org microdata.
Workflow
The french-property.com search page at /properties-for-sale is a fully server-rendered Laravel app behind Cloudflare that accepts every filter as a URL query parameter. No login, no JS execution, no anti-bot challenge with a residential proxy — browse cloud fetch <url> --proxies returns the same HTML the browser renders, with all listing data inlined as Schema.org microdata. There is no public JSON API. Lead with URL-param + HTML extraction; the browser path is only useful for visual verification.
-
Construct the search URL by appending filters to
https://www.french-property.com/properties-for-sale:Param Type Notes regionsEnglish-kebab slug, single value Valid: alsace, aquitaine, auvergne, brittany, centre-val-de-loire, champagne-ardenne, corsica, franche-comte, languedoc-roussillon, limousin, lorraine, midi-pyrenees, nord-pas-de-calais, normandy, occitanie, paris-ile-de-france, pays-de-la-loire, picardy, poitou-charentes, provence-alpes-cote-d-azur, rhone-alpes. ⚠ See gotchas — French slugs silently no-op.minimum_price,maximum_priceint (EUR) e.g. 200000minimum_bedrooms,maximum_bedroomsint minimum_floor_size,maximum_floor_sizeint (m²) Habitable size, not land minimum_land_size,maximum_land_sizeint Pair with land_size_unit=m(m²) orland_size_unit=ha(hectares)property_types_allsingle value house | apartment | business | land. Despite the trailing_all, this is NOT an array; the form only emits one value.keywords_allURL-encoded text Listings must contain ALL keywords. Spaces as +or%20.keywords_anyURL-encoded text Listings matching ANY keyword. referencestring Direct lookup by reference code (e.g. IFPC46841); returnsResults 1 - 1 of 1.exclude_agencies1Private-vendor listings only (typically ~2% of inventory). sort_byenum date(default, most recent),price,land_size.sort_directionenum asc,desc.start_pageint ≥ 1 Pagination cursor. 25 results per page. Page 1 omits the param or uses start_page=1.currencyenum EUR(default),GBP,USD,CAD,AUD. Affects on-page display only —<meta itemprop="price">is always in the underlying currency (typically EUR).Example for "Houses in Brittany, €200K–€400K, 3+ bedrooms, sorted by most recent":
https://www.french-property.com/properties-for-sale?regions=brittany&minimum_price=200000&maximum_price=400000&minimum_bedrooms=3&property_types_all=house&sort_by=date&sort_direction=desc -
Fetch the page through a residential proxy (the site is Cloudflare-fronted; bare requests sometimes get challenged but proxy fetches consistently return 200):
browse cloud fetch "$url" --proxiesResponse envelope contains the rendered HTML under
.content. No--verified/ advanced-stealth needed — the search route does not run an Akamai/Datadome-class challenge in 2026-05 testing. -
Read the total count from the rendered text — single regex hit:
/Results (\d+) - (\d+) of (\d+)/The third capture group is the total match count across all pages. Total pages =
ceil(total / 25). -
Detect the no-results case before trying to parse listings: the page renders the literal string
No properties found - try expanding your search:followed by a property-alert sign-up form. Emittotal_matches: 0, listings: []in that branch — don't error. -
Extract each listing. Split the HTML on
<li class="property_listing standard ">(note the double-space — that's the production class string, see gotchas). Within each block, the data is all in inline Schema.org microdata, no JS required:Field Selector / regex url(relative)<meta itemprop="url" content="(/sale-property/\d+-[A-Z0-9]+)"/>→ prefix withhttps://www.french-property.comreference<span itemprop="productID">Ref: ([A-Z0-9]+)</span>titlefirst <h3 itemprop="name">…<a [^>]*>([^<]+)</a></h3>(often truncated with…; for the full title, GET the detail page)price_eur<meta itemprop="price" content="(\d+)"/>(string of digits, parse to int;0or missing = "Price on request")currency<meta itemprop="priceCurrency" content="([A-Z]{3})"/>(almost alwaysEUR)region<span class="region">Region: <strong>([^<]+)</strong>department<span class="department">Department: <strong>([^<]+)</strong>— e.g.Ille-et-Vilaine (35)commune<span class="commune">\s*Location:\s*<strong>([^<]+)</strong>— e.g.Rennes, 35000bedroomsclass="info-beds">.*?<strong>\s*(\d+)bathroomsclass="info-bath">.*?<strong>(\d+)(may be absent for studios / land)habitable_size_m2class="info-habitable">.*?<strong>.*?(\d+(?:\.\d+)?)\s*m²(may be absent for land)land_sizeclass="info-land">.*?<strong>.*?(\d+(?:\.\d+)?)\s*(ha|m²)— value + unitimage_urlfirst <meta itemprop="contentUrl" content="([^"]+\?height=500&width=750)"/>within the listing block (full-resolution)description<div class="description" itemprop="description">\s*<p>([\s\S]*?)</p>— strip whitespace, decode HTML entities -
Paginate if more pages exist (total > 25): re-issue the same URL with
&start_page=2,&start_page=3, … up toceil(total/25). The page title gets a- page Nsuffix you can use as a sanity check. Sustained throughput at 1 req/s through one proxy IP has been smooth in testing. -
Sanity-check region scope before emitting. After parsing, every listing's
regionfield should equal the requested region's display name (e.g.regions=brittany→Brittany;regions=provence-alpes-cote-d-azur→Provence-Alpes-Côte d'Azur). If you see mixed regions, the slug was wrong and the site fell back to all-France — see gotchas.
Browser fallback
Only needed if the URL-param + HTML extraction path is somehow blocked (not observed in testing). Drive a session in the standard way:
sid=$(browse cloud sessions create --keep-alive --proxies | node -pe \
"let s='';process.stdin.on('data',c=>s+=c).on('end',()=>process.stdout.write(JSON.parse(s).id))")
browse open "$url" --remote --session "$sid"
browse get html body --remote --session "$sid" > page.html # same HTML the fetch path returns
browse screenshot --remote --session "$sid" --path screenshot.png
browse cloud sessions update "$sid" --status REQUEST_RELEASE
browse snapshot is not useful here — the listings render server-side, but the accessibility-tree refs add no information beyond the microdata you already have in HTML. Skip the snapshot step.
Site-Specific Gotchas
regions=requires the ENGLISH kebab-case slug, NOT the French slug used in/regions/<slug>/URLs. Verified failures (silent no-op, falls back to all-France with title "Property for sale in France"):bretagne, bourgogne, provence_alpes_cote_dazur, haute_normandie, basse_normandie, paris, ile-de-france, loire-valley. Verified successes: the 21 English slugs listed in the workflow table. The trap is silent: the URL still loads200 OKwith no error indicator — only the<title>and per-listingregionstrings reveal that no region filter was applied. Always verify by checking the response<title>contains the expected English region name before trusting the result set.provence-alpes-cote-d-azurusesd-azurwith a hyphen, notdazurord%27azur. Both alternatives fall back to all-France. Confirmed working slug:provence-alpes-cote-d-azur.departments=NNdoes NOT filter via URL params in 2026-05 testing. Addingdepartments=35(Ille-et-Vilaine, Brittany) to aregions=brittanyquery returns the identical 333 results asregions=brittanyalone. Bracket-syntaxdepartments[]=35returns a 500 "Sorry, we are having temporary issues with our system" error page. The departments multi-select on the search form is driven by client-side JS that mutates a hidden field and submits a different payload shape — the URL-param surface only honorsregions=, notdepartments=. To scope below region, post-filter the extracteddepartmentfield client-side (it's always present as<span class="department">…<strong>NAME (NN)</strong>).property_types_allis single-value despite the_allsuffix. The form's<select>emits onehouse|apartment|business|land. Passing multiple values (property_types_all=house,apartmentorproperty_types_all[]=house&property_types_all[]=apartment) is silently dropped — the response shows all types. To search across types, fetch each type separately and union client-side.- The CSS class string is
property_listing standardwith a double space and trailing space. That's the production literal in the rendered HTML. If you use a CSS selector framework, match by class containment (property_listing standard), not exact string equality. The four observed listing variants areproperty_listing featured,property_listing standard,property_listing advertise,property_listing standard text-center. The first two are real listings;advertiseis a sponsored card with NO microdata (nometa itemprop="price", no reference) — skip it.standard text-centeris an empty-state placeholder shown when a page has fewer than 25 results — also skip it. - Titles in the listing card are truncated with
…(e.g.Just a Few Minutes from Rennes, in a Preserved and Perfectly Peaceful Setting, this Elegant Character Property Exudes Ch…). For the full title, fetch the detail page at themeta itemprop="url"link. The truncation length appears to be ~155 characters. bathrooms,habitable_size_m2,land_sizeare optional fields — apartments often lackland_size; studios may lackbathrooms; land plots lack bothbedroomsandhabitable_size_m2. Always guard the regex with a presence check; don't emitnullas0.info-landcarries the unit inline (2.6 ha,1200 m²). Don't assume hectares. Parse both number and unit; convert client-side if you need a normalized field. The land filter'sland_size_unitURL param acceptsmorha; mismatched units (e.g.minimum_land_size=1withland_size_unit=m) return effectively-all results, so always pair them.page_sizeURL param is silently ignored. The form hasname="page_size"and 25 is fixed. Don't try to fetch 100 per page.<meta itemprop="price">is the source of truth, not the<h4>€780,000</h4>rendered text. The displayed h4 changes withcurrency=GBP|USD|...; the meta always emits the underlying EUR integer. Some listings haveprice=0or omit the meta entirely — those render as "Price on request" / blank — emitprice_eur: nullfor these, not0.- Featured listings appear on EVERY page of paginated results (paid placement). They have the same
reference/url, so deduplicate byreferencewhen collecting across pages, or you'll over-count. Results A - B of Cregex match can find multiple hits if the page has alternate-language<link hreflang>versions in the head with translated text. Use the FIRST match or scope the regex to the<div id="results">container.- Cloudflare Cache-Status is
DYNAMIC, neverHIT. Search responses are not cached at the edge — count on ~1–3s per page-fetch through proxy. There is no rate-limit response observed at 1 req/s sustained, but adding any explicit rate-limit avoids social risk. exclude_agencies=1only narrows by ~2% (333 → 326 in Brittany 2026-05 sample) — most listings are agency-listed. Use it only when private-vendor-only is a hard requirement.- The
sortURL param does NOT work; you need the splitsort_by+sort_directionpair. The form's<select name="sort">emits the full/properties-for-sale?sort_by=…&sort_direction=…URL as its value, which is what gets navigated to. Passingsort=datealone is silently ignored. - Rentals are a different surface.
/properties-for-saleis sale-only. For rentals, the endpoint is/properties-to-rentwith a POST-only form (/properties-to-rent/submit-search) and a completely different param namespace (price_min/price_max/bedrooms_min/bedrooms_max/locations[]/attributes[]). This skill targets sale listings; rentals require a separate skill. burgundy(English-kebab) appears to NOT be a validregions=slug — testing returned an empty title repeatedly. The corresponding metropolitan region (Bourgogne) was merged into Bourgogne-Franche-Comté in 2016, but neitherburgundynorbourgogne-franche-comteworks. If a user requests Burgundy, either search the underlying Côte-d'Or / Saône-et-Loire / Nièvre / Yonne departments byregions=francewith client-side department filtering, OR fall back to the directory at/regions/bourgogne/(which links to listings via per-department deep URLs).
Expected Output
{
"success": true,
"search_params": {
"regions": "brittany",
"minimum_price": 200000,
"maximum_price": 400000,
"minimum_bedrooms": 3,
"property_types_all": "house",
"sort_by": "date",
"sort_direction": "desc"
},
"url": "https://www.french-property.com/properties-for-sale?regions=brittany&minimum_price=200000&maximum_price=400000&minimum_bedrooms=3&property_types_all=house&sort_by=date&sort_direction=desc",
"total_matches": 61,
"page": 1,
"page_size": 25,
"total_pages": 3,
"listings": [
{
"reference": "IFPC46841",
"url": "https://www.french-property.com/sale-property/1-IFPC46841",
"title": "Just a Few Minutes from Rennes, in a Preserved and Perfectly Peaceful Setting, this Elegant Character Property Exudes Ch…",
"price_eur": 780000,
"currency": "EUR",
"region": "Brittany",
"department": "Ille-et-Vilaine (35)",
"commune": "Rennes, 35000",
"bedrooms": 5,
"bathrooms": 3,
"habitable_size_m2": 260,
"land_size_value": 2.6,
"land_size_unit": "ha",
"image_url": "https://cdn4.french-property.com/private-vendors/IFPC46841/21285379-6923-4488-8aa3-b07b385bd621.jpg?height=500&width=750",
"description": "5 bed country estate for sale in Rennes. Renovated property with swimming pool – 260 m² – 2.5 hectares – 10 min from Rennes on the Rennes/St Malo road…"
}
]
}
No-results shape
{
"success": true,
"search_params": { "regions": "brittany", "minimum_price": 50000000 },
"url": "https://www.french-property.com/properties-for-sale?regions=brittany&minimum_price=50000000",
"total_matches": 0,
"page": 1,
"total_pages": 0,
"listings": [],
"no_results_message": "No properties found - try expanding your search:"
}
Single-reference lookup shape
{
"success": true,
"search_params": { "reference": "IFPC46841" },
"url": "https://www.french-property.com/properties-for-sale?reference=IFPC46841",
"total_matches": 1,
"page": 1,
"total_pages": 1,
"listings": [ { "reference": "IFPC46841", "...": "..." } ]
}
Invalid-region fallback (defensive)
If the response <title> contains "Property for sale in France" but the request specified regions=<X>, the slug was invalid and the site silently fell back to all-France. Emit:
{
"success": false,
"reason": "invalid_region_slug",
"requested_region": "bretagne",
"hint": "Use the English kebab-case slug. Valid: alsace, aquitaine, ... See SKILL.md workflow table.",
"search_params": { "regions": "bretagne" }
}
How to use find-listing on Cursor
AI-first code editor with Composer
Prerequisites
Before installing skills in Cursor, ensure your development environment meets these requirements:
- ›Cursor installed and configured on your development machine
- ›Node.js version 16.0+ with npm package manager (verify with
node --version) - ›Active project directory or workspace where you want to add find-listing
Execute installation command
Execute the skills CLI command in your project's root directory to begin installation:
The skills CLI fetches find-listing from GitHub repository french-property.com/find-listing-sujpf1 and configures it for Cursor.
Select Cursor when prompted
The CLI will show a list of available agents. Use arrow keys to navigate and space to select Cursor:
Verify installation
Confirm successful installation by checking the skill directory location:
Reload or restart Cursor to activate find-listing. Access the skill through slash commands (e.g., /find-listing) or your agent's skill management interface.
Security & Verification Notice
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your development environment. Always verify the publisher's identity, review recent commits, and test in isolated environments before production deployment.
List & Monetize Your Skill
Submit your Claude Code skill and start earning
Use Cases▌
Task Automation & Efficiency
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Knowledge Enhancement
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Quality Improvement
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
Implementation Guide▌
Prerequisites
- ›Claude Desktop or compatible AI client with skill support
- ›Clear understanding of task or problem to solve
- ›Willingness to iterate and refine outputs
Time Estimate
15-45 minutes depending on use case complexity
Installation Steps
- 1.Install skill using provided installation command
- 2.Test with simple use case relevant to your work
- 3.Evaluate output quality and relevance
- 4.Iterate on prompts to improve results
- 5.Integrate into regular workflow if valuable
Common Pitfalls
- ⚠Expecting perfect results without iteration
- ⚠Not providing enough context in prompts
- ⚠Using skill for tasks outside its intended scope
- ⚠Accepting outputs without review and validation
Best Practices▌
✓ Do
- +Start with clear, specific prompts
- +Provide relevant context and constraints
- +Review and refine all outputs before using
- +Iterate to improve output quality
- +Document successful prompt patterns
✗ Don't
- −Don't use without understanding skill limitations
- −Don't skip validation of outputs
- −Don't share sensitive information in prompts
- −Don't expect skill to replace human judgment
💡 Pro Tips
- ★Be specific about desired format and style
- ★Ask for multiple options to choose from
- ★Request explanations to understand reasoning
- ★Combine AI efficiency with human expertise
When to Use This▌
✓ Use When
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid When
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
Learning Path▌
- 1Familiarize yourself with skill capabilities and limitations
- 2Start with low-risk, non-critical tasks
- 3Progress to more complex and valuable use cases
- 4Build expertise through regular use and experimentation
Discussion
Product Hunt–style comments (not star reviews)- No comments yet — start the thread.
Ratings
4.5★★★★★58 reviews- ★★★★★Ganesh Mohane· Dec 24, 2024
Keeps context tight: find-listing is the kind of skill you can hand to a new teammate without a long onboarding doc.
- ★★★★★William Torres· Dec 20, 2024
Registry listing for find-listing matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Alexander Martinez· Dec 12, 2024
find-listing is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
- ★★★★★Dev Garcia· Dec 12, 2024
Solid pick for teams standardizing on skills: find-listing is focused, and the summary matches what you get after install.
- ★★★★★Lucas Li· Dec 8, 2024
find-listing fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
- ★★★★★Dev Martinez· Nov 27, 2024
find-listing has been reliable in day-to-day use. Documentation quality is above average for community skills.
- ★★★★★Rahul Santra· Nov 15, 2024
Registry listing for find-listing matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Ren Singh· Nov 11, 2024
I recommend find-listing for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Ava Jain· Nov 11, 2024
Keeps context tight: find-listing is the kind of skill you can hand to a new teammate without a long onboarding doc.
- ★★★★★Chen Thompson· Nov 3, 2024
find-listing reduced setup friction for our internal harness; good balance of opinion and flexibility.
showing 1-10 of 58