Dataspryva

Use Houzz Pro Directory Finder by City & Category with Python

Find Houzz contractors, architects, and designers by city and category across 16 countries, with ratings, reviews, hires, services, license status, and location for each professional.

1. Choose the data you need

Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.

2. Prepare a source-based input

This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.

{
  "categorySlug": "",
  "city": "Los Angeles, CA",
  "country": "us",
  "directoryUrls": [],
  "enrichEmails": false,
  "fetchDetails": true,
  "fetchPhotoDetails": false,
  "includeReviews": false,
  "keyword": "",
  "maxItems": 1,
  "maxPages": 0,
  "maxReviewsPerPro": 20,
  "minRating": 0,
  "minReviewCount": 0,
  "mode": "search",
  "photoCategory": "kitchen",
  "photoStyle": "",
  "photoUrls": [],
  "profession": "general-contractor",
  "profileUrls": [],
  "sortBy": "relevance"
}

Download input.example.json and save your reviewed copy as input.json.

FieldTypeRequiredDescription
modestringoptionalWhat to scrape. `search` builds a directory from country + city + profession; `byUrls` reads directory URLs; `profiles` reads profile URLs; `reviews` emits review rows; `photos` browses photo inspiration.
countrystringoptionalHouzz market used for search and profile URLs.
citystringoptionalCity or city + state to search, e.g. `Los Angeles, CA`, `London`, `Berlin`. Used with profession or categorySlug in search mode.
professionstringoptionalUniversal profession mapped to the selected market's Houzz category. Used in search mode.
categorySlugstringoptionalExact Houzz category slug, used instead of the mapped profession, e.g. `general-contractor`, `architekten`, `architectes`. Use a direct directory URL if you are unsure.
keywordstringoptionalOptional keyword filter for professional search, or the search term for photo mode.
sortBystringoptionalServer-side order for professional directory results.
minRatingnumberoptionalDrop professionals below this star rating. Set 0 to keep all.
minReviewCountintegeroptionalDrop professionals with fewer reviews. Set 0 to keep all.
directoryUrlsarrayoptionalHouzz professional directory, category or search-result URLs. All live markets and localised paths are accepted.
profileUrlsarrayoptionalDirect Houzz professional profile URLs, including localised paths such as /experten/, /professionnels/ and /profesionales/.
photoUrlsarrayoptionalDirect Houzz photo detail URLs. Use mode=photos.
photoCategorystringoptionalRoom category for photo inspiration browsing. Use keyword to search instead.
photoStylestringoptionalOptional design style filter for photo inspiration.
includeReviewsbooleanoptionalAttach review history to each professional record.
maxReviewsPerProintegeroptionalReview cap per professional. Set 0 to fetch the full history (up to 1,024).
fetchDetailsbooleanoptionalOpen each professional profile for services, awards, socials, counts and licensing. Turn off for directory-card-only records.
fetchPhotoDetailsbooleanoptionalOpen each photo for full image sizes, owner, location and question count.
enrichEmailsbooleanoptionalBest-effort email lookup on each professional's own website. Adds requests and is optional.
maxItemsintegeroptionalHard cap on emitted records.
maxPagesintegeroptionalOptional page cap. Set 0 to use the source ceiling: 100 directory pages, 30 keyword pages, 250 photo pages or 10 photo keyword pages.

3. Start an Actor run

Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.

Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.

import json
import os
import urllib.request

# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
    actor_input = json.load(stream)

token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
    "https://api.apify.com/v2/acts/MLZXQoVRusx3cGvm5/runs?timeout=120&maxTotalChargeUsd=0.50",
    data=json.dumps(actor_input).encode("utf-8"),
    headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
    method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
    run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.

4. Inspect the actual results

Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.

Houzz professional profiles with contacts, services, awards, socials and reviews, review rows, and photo inspiration records.

Questions before you run

Which inputs are required?

No top-level fields are marked required in the published schema. Conditional requirements can still apply; check the README.

What does this guide verify?

The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.

What if the run request times out?

Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.

Generated from source build TRlqaqbv6wYcl6cdj and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.