FR
Copied
Modules

Find the website

Find the website

Finds a company's official website from its name and city, then proves the match by reading the site itself. No AI: every decision comes from an observable fact, and an unproven candidate is never written.

Purpose

emails, socials, legal_mentions, techstack and pricing all require a site_web. A list that has names but no websites cannot reach any of them. This module is the bridge.

It runs in two stages:

  1. Search. A web search on the company name plus its city. Directories, social networks, marketplaces, registry pages and job boards are discarded: the target is the company's own site, not its listing on someone else's. If the legal name returns nothing usable, a second search runs on the most distinctive word of the name plus the city, which is how companies are usually referenced online (SAS LABLAUDE Diégo is not a phrase anyone writes; Lablaude plus the town is). The establishment qualifier registries append to the legal name is stripped before searching: NALDEO - SITE DE TARNOS becomes NALDEO, otherwise the query targets a label nobody ever writes.
  2. Proof. The surviving candidates are opened and read. The site is accepted only when its pages contain the company's postcode or town, or, for an exact name match, the company name. Without proof the cell stays empty.

Between two domains that both prove the same company, the apex domain wins over a subdomain, and a deployment host address (.vercel.app and the like) is only ever a last resort.

All traffic goes through the VPN proxy pool, one exit per worker.

Inputs

Field Required Notes
nom yes Company name. Aliases accepted (name, raison sociale, entreprise…).
ville / commune no Strongly recommended: it is both a search term and the main proof.
code_postal no Used as proof when reading the candidate site.
adresse no Fallback: the postcode and town are read from it when the dedicated columns are missing.

Like opendata, this module accepts rows with no contact detail at all: creating one is its job. Rows with no usable name are kept in the output file untouched.

Outputs

Column Type Description
site_web url The website found. An existing value is never overwritten.
site_finder_match text Why the decision was made: nom + adresse vérifiés sur le site, nom vérifié sur le site, nom exact (site injoignable), site déjà présent, or the reason nothing was written.

Every input column is carried through unchanged (column passthrough contract).

Lifecycle

POST /api/jobs/site-finder → pending → running → completed.

Rows that already have a website are written straight to the output and never searched, so chaining this module after a cheaper one costs nothing on the rows the cheaper one already filled.

Cancellation is honoured between items. A row that fails twice is written with site_finder_match = recherche indisponible rather than dropped.

Pipeline

input pois_any
output pois
needs nom
produces site_web, site_finder_match

Recommended order: sirene → opendata → site_finder → emails. The first two are free and instant; this one costs network time, so it should only see the rows they could not fill.

Errors

Case Behaviour
No usable name in the whole list 400 with the list of columns that were read
Search engine unavailable The row is retried on another VPN exit, then written empty with an explicit reason
Candidate site unreachable Accepted only if the domain is an exact name match, otherwise skipped
Same-name company elsewhere Rejected: the postcode/town proof fails, nothing is written

What's next

The output feeds any module that needs a website. emails is the usual next step.