Vexaloom Labs

Use Craigslist Classifieds Scraper with Category Attributes with Python

Scrape Craigslist search results and individual posts across any city subdomain, with category-specific attributes for jobs, housing, autos, and for-sale posts. No login or proxy required.

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.

{
  "category": "sss",
  "condition": "any",
  "cryptoOk": false,
  "deliveryAvailable": false,
  "hasImage": false,
  "hideDuplicates": false,
  "includeDetails": true,
  "maxItems": 3,
  "mode": "search",
  "postedToday": false,
  "region": "sfbay",
  "searchQueries": [
    "bike"
  ],
  "sellerType": "all",
  "sortBy": "newest",
  "titlesOnly": false
}

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

FieldTypeRequiredDescription
modestringrequiredWhat to collect: keyword search, a category browse, specific Craigslist URLs, or the region/subarea reference list.
regionstringoptionalCraigslist city/region to search (mode=search/category). Pick a common region, or use Custom region for any of the 707 Craigslist sites.
customRegionstringoptionalAny Craigslist hostname or abbreviation (e.g. humboldt, tokyo, sfbay). Overrides Region. (mode=search/category)
subareastringoptionalOptional Craigslist subarea abbreviation inside the region (e.g. sfc, eby, brk). Leave blank for the whole region. (mode=search/category)
categorystringoptionalCraigslist category to search or browse. The default is all for-sale listings.
searchQueriesarrayoptionalOne or more keywords. Each query is searched separately; results are de-duplicated. Leave empty for a category browse. (mode=search)
startUrlsarrayoptionalCraigslist search pages, new-style /view/d/... post URLs, or old /region/category/post-id.html URLs. (mode=byUrl)
minPriceintegeroptionalOnly listings at or above this price. Posts without a price are excluded when a price filter is set.
maxPriceintegeroptionalOnly listings at or below this price. Posts without a price are excluded when a price filter is set.
postedTodaybooleanoptionalOnly listings posted in the last 24 hours (Craigslist's posted-today filter).
hasImagebooleanoptionalOnly listings with at least one photo.
titlesOnlybooleanoptionalMatch the keywords against titles only instead of titles and descriptions.
sellerTypestringoptionalFilter by owner, dealer, or either.
sortBystringoptionalOrder of results within each query.
conditionstringoptionalFor for-sale and auto categories: only items in this condition.
minBedroomsintegeroptionalHousing only.
maxBedroomsintegeroptionalHousing only.
minBathroomsintegeroptionalHousing only.
maxBathroomsintegeroptionalHousing only.
minSqftintegeroptionalHousing only.
maxSqftintegeroptionalHousing only.
autoMakeModelstringoptionalAuto categories only, e.g. honda civic.
minAutoYearintegeroptionalAuto categories only.
maxAutoYearintegeroptionalAuto categories only.
maxAutoMilesintegeroptionalAuto categories only.
postalCodestringoptionalOptional ZIP/postal code to anchor the search geographically. Use with Search radius.
searchRadiusMilesintegeroptionalDistance around the postal code. Requires Postal code.
hideDuplicatesbooleanoptionalAsk Craigslist to group duplicate/reposted listings together.
deliveryAvailablebooleanoptionalFor-sale and auto categories: only listings offering delivery.
cryptoOkbooleanoptionalFor-sale and auto categories: only listings that accept crypto.
countryCodestringoptionalTwo-letter country code to filter the areas list (mode=areas), e.g. US, CA, GB. Leave blank for all 707 sites.
maxItemsintegeroptionalHard cap across all queries and URLs. Craigslist returns at most 10,000 results per search.
includeDetailsbooleanoptionalFetch each listing's full description, attributes, images, coordinates, and repost status. Turn off for faster search-card-only results.

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/PfjY6S7qeKQpmGEqc/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.

Craigslist listings with prices, descriptions, photos, coordinates, category attributes, repost status, and region/subarea records.

Questions before you run

Which inputs are required?

The published required fields are mode

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 HWKb9T9uefJQgHpvH and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.