PagesJaunes Scraper — French Business Directory, per result avatar

PagesJaunes Scraper — French Business Directory, per result

Pricing

from $1.40 / 1,000 business with details

Go to Apify Store
PagesJaunes Scraper — French Business Directory, per result

PagesJaunes Scraper — French Business Directory, per result

Business listings from pagesjaunes.fr: name, address, activities, rating, plus phone, SIRET, NAF code, GPS and opening hours from the professional's own page. Drop-in compatible with memo23/pagesjaunes-scraper-cheerio.

Pricing

from $1.40 / 1,000 business with details

Rating

0.0

(0)

Developer

DIOPSIDE AI

DIOPSIDE AI

Maintained by Community

Actor stats

0

Bookmarked

4

Total users

2

Monthly active users

25 days ago

Last modified

Security

Limited permissions

Share

Drop-in compatible with memo23/pagesjaunes-scraper-cheerio and saswave/pagesjaunes-scraper — same input fields, same output column names, cheaper per result, and pagination that actually paginates.

Search pagesjaunes.fr by activity and town and get every business as a row: name, address, activity, services, ratings — plus phone, website, GPS coordinates, SIRET, SIREN, NAF code, legal form, incorporation date, opening hours and payment methods taken from each professional's own page.

No login, no API key, no cookies to supply. You pay per business, not per page or per hour.

Why this one

1. It does not silently re-scrape page 1. PagesJaunes has two search surfaces. The query route (/annuaire/chercherlespros?quoiqui=…&ou=…) honours ?page=N; the SEO route (/annuaire/paris-75/restaurant) does not — asking it for ?page=3 returns page 1 again, with 16 of the 20 results identical and the footer still reading "Page 1 / 500". A scraper that builds its own page URLs therefore bills you repeatedly for the same twenty businesses and calls the run a success. This actor follows PagesJaunes' own "Suivant" link instead (which carries a per-search contexte token that cannot be constructed), and refuses to push a page whose footer did not advance — it stops the target and says so in the run status message.

2. Official registry data, not just contact details. Every enriched record carries the SIRET, SIREN, NAF code, legal form, establishment type (head office or branch) and incorporation date that PagesJaunes sources from INSEE's Sirene base — so a lead list is also a company list you can join to French open data.

3. A Google rating never lands in the PagesJaunes rating column. PagesJaunes shows a third-party score next to its own for about half of listings. Blending the two quietly changes what your pipeline is averaging, so they stay in separate columns (basicInfo_place_rating / partnerRating).

4. Failures are reported, never hidden. A blocked page is retried on a fresh exit IP; a target that still fails is named in the status message while the businesses already collected are kept. A run only fails when it produced nothing.

Input

FieldTypeDefaultDescription
startUrlsarray—pagesjaunes.fr URLs. A search listing (/annuaire/paris-75/restaurant or /annuaire/chercherlespros?quoiqui=plombier&ou=Paris) or one professional's page (/pros/64217247).
searchTermstring—Activity or trade (plombier, restaurant). Used when no startUrls are given.
locationstring—Town, department or postcode (Paris, Lyon, 69003).
maxItemsinteger100Stop after this many businesses. 0 scrapes every page.
extractDetailsbooleantrueOpen each business's /pros/ page for phone, website, GPS, SIRET, NAF, opening hours and payment methods.
proxyConfigurationobjectRESIDENTIAL / FRSee Proxy below.
maxConcurrencyinteger4Pages fetched at the same time.
maxRequestsPerMinuteinteger90Request rate ceiling.
maxRequestRetriesinteger4Retries on a fresh exit IP before a target is given up on.

url, pros_urls (saswave) and proxy (memo23) are accepted as aliases, so an input written for either incumbent runs here unchanged.

Output

One record per business. Column names in the first group match memo23/pagesjaunes-scraper-cheerio exactly; the rest are additions.

{
"code_etablissement": "64217247",
"denomination": "SOS Plomberie 92",
"telephone": "+33 7 52 63 50 52",
"email": null,
"site_web": "https://sosplomberie92.fr/",
"adresse_full_long": "10 Marceau 92130 Issy les Moulineaux",
"street": "10 Marceau",
"postalCode": "92130",
"city": "Issy les Moulineaux",
"country": "FR",
"latitude": 48.82664,
"longitude": 2.27191,
"siret": "48390376100060",
"siren": "483903761",
"codeNaf": "4322A",
"formeJuridique": "Entrepreneur individuel",
"typologieEtablissement": "Siège",
"creationEntreprise": "10 octobre 2005",
"activite_libelle": "dépannage plomberie",
"prestations": ["dépannage de chauffe-eau", "détection de fuite d'eau"],
"description": "15 ans d'expérience dans le métier. Devis gratuit, transparent.",
"basicInfo_place_rating": 5,
"basicInfo_place_nb_review": 6,
"partnerRating": 5,
"partnerReviewCount": 26,
"partnerSource": "Google",
"openingHours": [{ "day": "Monday", "opens": "08:00", "closes": "20:00" }],
"paymentAccepted": ["CB", "Espèces", "Chèque"],
"images": ["https://www.pagesjaunes.fr/media/newdam/…/photo.jpg"],
"url": "https://www.pagesjaunes.fr/pros/64217247",
"searchUrl": "https://www.pagesjaunes.fr/annuaire/chercherlespros?quoiqui=plombier&ou=Paris",
"searchPage": 1,
"position": 1,
"hasDetails": true,
"scrapedAt": "2026-09-20T08:26:03+00:00"
}

Every record carries every column, so a CSV export never shifts. hasDetails tells you whether a null phone means "the business publishes none" or "not looked up".

email is always null. PagesJaunes does not publish contact emails, and this actor does not go hunting for them on the businesses' own websites. The column exists so a dataset from another PagesJaunes actor keeps the same shape.

Sizes and speed

A search returns 20 businesses per page. plombier in Paris is 24 pages (~480 businesses); restaurant in Paris is capped at 500 pages (~10,000). With extractDetails on, expect roughly 25 businesses per 25 seconds at the default concurrency; with it off, 20 per request.

Proxy

French residential IPs are required. PagesJaunes sits behind a Cloudflare managed challenge that scores the exit IP, not just the TLS fingerprint. Measured on the Apify platform on 2026-09-20, three attempts against each of three routes per tier:

TierResult
No proxy (raw Apify egress)0/9 — 403 + Cloudflare interstitial on every request
Apify datacenter, country FR0/9 — no French datacenter IPs available
Apify RESIDENTIAL, country FR6/9, and all three misses were the proxy failing to allocate an exit IP, not Cloudflare

The default proxyConfiguration is RESIDENTIAL/FR and you should leave it there. Running with the proxy off is not a cheaper mode — it is a failed run, and the actor says so before it starts.

Pricing

EventPriceWhat you get
Actor start$0.00005Once per run, per GB of memory.
Business$0.0009One search-result business: name, address, activity, services, description, both ratings, URL.
Business with details$0.0014The above plus phone, website, GPS, SIRET, SIREN, NAF code, legal form, incorporation date, opening hours, payment methods, photos.

Two prices because the two records cost very different amounts to produce: a listing record is one twentieth of a search page, an enriched one adds a whole extra page of residential traffic. Set extractDetails: false for a fast name-and-address sweep at the lower price.

Use cases

  • Local lead lists — every plumber, restaurant or bakery in a town with phone, website and opening hours, ready for a CRM import.
  • Company data enrichment — join your French customer list to SIRET/SIREN/NAF straight from the directory, without a separate registry lookup.
  • Local SEO and competitive audits — track who ranks where for an activity in a town over time; searchPage and position are on every record.
  • Store locators and maps — GPS coordinates and structured addresses for every business in a category.

Switching from another PagesJaunes actor

Change the actor id. Your input keeps working: startUrls (memo23), url and pros_urls (saswave) and proxy (memo23) are all accepted, and maxItems, maxConcurrency, minConcurrency and maxRequestRetries mean what they did before.

Two differences to know about:

  • email is always null here (see above). If you depended on the incumbent's email enrichment, this actor does not replace it.
  • Set proxyConfiguration to RESIDENTIAL/FR — or just delete your proxy setting and take the default. An input that said {"useApifyProxy": false} will not get through Cloudflare.

Notes

Only public directory pages are read, over the routes robots.txt allows: search listings and each professional's own /pros/ page. The phone number comes from the schema.org block PagesJaunes publishes on that page for search engines — not from the /annuaire/ajax/ endpoint its "Afficher le N°" button calls, which robots.txt disallows. Nothing from PagesBlanches (the residential directory) is scraped.