Demographic researchers, probate investigators, and local media analysts often need structured death notices and funeral service listings. Most public obituary platforms distribute notices unevenly across regional portals, wrap content in variable DOM structures, or omit fields unpredictably when funeral homes fail to provide complete details. Parsing those pages directly leaves downstream pipelines full of placeholder text, empty strings, and null fields that break ingestion schemas.
The Echovita Obituary & Funeral Home Scraper extracts directory records and full obituary pages across four countries: the United States, Canada, Australia, and New Zealand. It handles HTTP-based data collection without requiring site authentication, and it strips missing properties so downstream records contain only populated keys.
Regional Taxonomies and Scraper Modes
Echovita organizes its directory around specific geographic hierarchies depending on the target country. To collect records cleanly, the scraper exposes seven operating values for the mode parameter:
-
search: Queries names vianameQuery. -
byState: Scrapes at the state, province, or region level. -
byCity: Targets a specific municipality alongside the required regional code. -
byDate: Pulls records for people who died on an exact date passed todeathDate(YYYY-MM-DD). -
byUrls: Fetches specific pages from an array of direct links inobituaryUrls. -
funeralHomes: Scrapes funeral home directory profiles rather than individual notices. -
byFuneralHome: Pulls all obituaries published by a specific directory listing viafuneralHomeUrl.
Because regional administrative divisions vary by market, the country parameter dictates which location parameter must accompany the query:
-
country: "us"pairs withstate(e.g.,tx,ca). -
country: "ca"pairs withcaProvince(e.g.,on,qc). -
country: "au"pairs withauState(e.g.,nsw,vic). -
country: "nz"pairs withnzRegion(nifor North Island orsifor South Island).
When using mode: "byCity", the scraper normalizes city names into lowercase, hyphenated URL slugs (such as los-angeles). If a slug yields no active records, the run finishes cleanly with zero records instead of throwing an unhandled exception.
Managing Recency and Year Boundaries
Unbounded obituary crawls can quickly pull historical records that fall outside an active investigation window. The actor provides built-in parameters to filter items before they reach the output dataset.
The rangeTime parameter allows server-side recency filtering across browse and search modes:
-
"0": Last 7 days -
"1": Last month -
"2": Last 6 months -
"3": Last year -
"4": All time (default)
For historical queries spanning specific calendar intervals, you can set integer boundary thresholds using minBirthYear, maxBirthYear, minDeathYear, and maxDeathYear. Setting minDeathYear: 2020 drops any notice where the recorded death occurred prior to 2020.
Here is an example input configuration that queries recent notices in Ontario, Canada, limited to deaths occurring in 2023 or later:
{
"mode": "byState",
"country": "ca",
"caProvince": "on",
"rangeTime": "1",
"minDeathYear": 2023,
"maxItems": 100
}
Parsing Output Schemas and Null Handling
A core design feature of this actor is omission over padding: empty fields are not emitted as null, "", or []. If an obituary lacks service details or geo-coordinates, those keys are excluded from the dataset item.
An obituary record (recordType: "obituary") contains fields such as:
{
"obituaryId": "18492011",
"fullName": "Jane Doe",
"givenName": "Jane",
"familyName": "Doe",
"birthDate": "1945-03-12",
"deathDate": "2026-02-01",
"birthYear": 1945,
"deathYear": 2026,
"ageAtDeath": 80,
"city": "Toronto",
"state": "Ontario",
"stateCode": "on",
"country": "Canada",
"countryCode": "ca",
"latitude": 43.6532,
"longitude": -79.3832,
"biography": "Full biography text published by the family...",
"headline": "Jane Doe Obituary (1945-2026) | Toronto, ON",
"datePublished": "2026-02-03",
"funeralHomeName": "Sample Funeral Centre",
"funeralHomeUrl": "https://www.echovita.com/ca/funeral-homes/on/toronto/sample-centre-101",
"serviceName": "Memorial Service",
"serviceStartDate": "2026-02-10T14:00:00",
"serviceLocationName": "Sample Chapel",
"serviceAddress": "123 Main St, Toronto, ON",
"sourceUrl": "https://www.echovita.com/ca/obituaries/on/toronto/jane-doe-18492011",
"recordType": "obituary",
"scrapedAt": "2026-02-15T08:30:00.000Z"
}
The socialImageUrl field points to Echovita's auto-generated share-card image (which overlays dates and names on a template) rather than a verified photograph of the deceased.
When running mode: "funeralHomes", the output shifts to directory data (recordType: "funeralHome"), outputting phone, address, website, logoUrl, and servicesOffered[] (such as cremation or pre-arrangements).
Execution and Pricing Model
The actor operates on a pay-per-event pricing model. Charges are calculated directly from flat event fees rather than variable compute time:
-
Actor Start (
apify-actor-start): $0.005 per GB of memory allocated to the run, charged once when the run initializes. -
Dataset Result (
result): $0.005 per emitted item under the FREE volume tier ($5.00 per 1,000 items). Higher volume tiers adjust this item price: BRONZE ($0.00433), SILVER ($0.00367), and GOLD, PLATINUM, or DIAMOND ($0.003 per item).
Because Echovita serves pages without aggressive bot countermeasures, the default run does not require specialized proxy networks.
Implementation Walkthrough
You can execute a targeted search and process results downstream using the Apify Python client.
- Install the official client library:
pip install apify-client
- Initialize the client and run a query targeting a specific surname within a US state:
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_API_TOKEN")
run_input = {
"mode": "search",
"nameQuery": "Miller",
"country": "us",
"state": "oh",
"rangeTime": "1",
"maxItems": 50
}
run = client.actor("crawlerbros/echovita-scraper").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
name = item.get("fullName")
death_date = item.get("deathDate", "Unknown")
funeral_home = item.get("funeralHomeName", "None listed")
print(f"{name} | Died: {death_date} | Provider: {funeral_home}")
- Export or ingest the resulting dataset items directly into your analytical storage.
This scraper does not aggregate records from smaller independent memorial sites that do not syndicate to Echovita's directory.
Echovita Obituary & Funeral Home Scraper is the Actor behind these examples. If a selector in your own version breaks, compare your output against the fields listed in its README first.
Prices quoted above are this Actor's published pay-per-event rates on the Apify Store, read from the Apify platform API on 2026-09-14. Check the Actor page for the current rates.
Top comments (0)