Separate discovery from detail.
Geographic tiles and pagination organize the search for listing IDs. Detail extraction is a separate step, so finding a listing and reading its fields can be checked independently.
Data collection engineering
Turning listing pages into structured records.
Custom data collection for a client
Python development · Data normalization · Integration testing
Normalized listing fields
Illustrative records| name | property_type | accommodates | bedrooms | bathrooms | city | country |
|---|---|---|---|---|---|---|
| Harbor apartment | Apartment | 4 | 2 | 1 | Example Bay | United States |
| Garden cottage | Cottage | 6 | 3 | 2.5 | Example Bay | United States |
| Hillside house | House | 8 | null | 3 | null | United States |
Scroll to see all fields.
The data shape
Replacement collection code for a property monitoring platform, covering listing discovery, detail extraction, record normalization, and an integration layer for the existing schema. The work includes testing against live sources.
The normalized record keeps property details in a defined shape. Counts and location fields can be missing; the output preserves that distinction for downstream handling.
Collection pipeline
Retrieve source pages, identify listings, extract their fields, then normalize records for the existing platform schema.
Search results identify listings; detail pages supply the property fields available from the source.
The fetch layer retrieves source pages for the collection code.
Geographic tiles and pagination organize discovery. A separate detail step extracts the fields for each listing.
Source-scoped identifiers and defined fields give the integration layer a consistent input. Missing values remain explicit.
An integration layer and write controls define how collected records can update the existing product.
PostgreSQL records collection runs and attempts. Sentry supplies diagnostic context for errors.
Engineering decisions
Geographic tiles and pagination organize the search for listing IDs. Detail extraction is a separate step, so finding a listing and reading its fields can be checked independently.
Identifiers are scoped by source, with collision checks at the integration boundary. Normalization produces defined fields while preserving missing values instead of substituting zero or an invented address.
Run and attempt records capture coverage, parsing outcomes, request cost, and latency. Explicit write controls separate collection from changes to the existing platform records.
What would you like to build or improve?
hello@outermost.us