A model declares the fields you want; tab.extract resolves every selector against the live DOM concurrently (asyncio.gather), reads text or an attribute, runs any transform, then Pydantic validates the result into a typed object. Watch each value get grabbed and dropped into its slot.

Page · rendered DOM

Aeron Chair $1,395.00 ★★★★★data-score="4.8" ergonomicoffice

Model → typed objectnot run

class Product(ExtractionModel):
name: str = Field(selector='.name') →
price: float = Field(selector='.price', transform=parse_price) →
rating: float = Field(selector='.stars', attribute='data-score', transform=float) →
tags: list[str] = Field(selector='.tag') →
asyncio.gather · all four fields resolve at once, not one by one