Processors transform extracted values (strip whitespace, cast types, apply regex, etc.). They run sequentially in the order specified.
Remove leading and trailing whitespace from strings.
Parameters: None
Example:
{
"css": "h1::text",
"processors": [{"type": "strip"}]
}Input → Output:
" Hello World " → "Hello World"
Works on: Strings and lists of strings
Replace substring in strings.
Parameters:
old(required): Substring to replacenew(required): Replacement string
Example:
{
"css": "span.price::text",
"processors": [
{"type": "replace", "old": "$", "new": ""},
{"type": "replace", "old": ",", "new": ""}
]
}Input → Output:
"$1,299.99" → "1299.99"
Works on: Strings and lists of strings
Extract substring using regular expression pattern.
Parameters:
pattern(required): Regex pattern to matchgroup(optional): Capture group to extract (default: 1)
Example:
{
"css": "span::text",
"processors": [
{"type": "regex", "pattern": "Price: \\$([\\d.]+)"}
]
}Input → Output:
"Price: $99.99" → "99.99"
Multiple groups:
{
"css": "span::text",
"processors": [
{"type": "regex", "pattern": "(\\d+) items", "group": 1}
]
}Returns original value if no match.
Works on: Strings only
Convert value to specified type.
Parameters:
to(required): Target type -"int","float","bool", or"str"
Example:
{
"css": "span.rating::attr(data-rating)",
"processors": [
{"type": "cast", "to": "float"}
]
}Input → Output:
"4.5" → 4.5
"42" → 42 (for int)
"true" → True (for bool)
Boolean conversion:
true,1,yes,on→ True- Everything else → False
Returns None if conversion fails.
Works on: Any type
Join list values into a single string.
Parameters:
separator(optional): String to join with (default:" ")
Example:
{
"css": "li.feature::text",
"get_all": true,
"processors": [
{"type": "join", "separator": ", "}
]
}Input → Output:
["WiFi", "Bluetooth", "GPS"] → "WiFi, Bluetooth, GPS"
Filters out None values automatically.
Works on: Lists only
Return default value if input is None, empty string, or empty list.
Parameters:
default(required): Fallback value
Example:
{
"css": "span.optional::text",
"processors": [
{"type": "default", "default": "N/A"}
]
}Input → Output:
None → "N/A"
"" → "N/A"
[] → "N/A"
"actual value" → "actual value"
Works on: Any type
Convert strings to lowercase.
Parameters: None
Example:
{
"css": "span.status::text",
"processors": [
{"type": "strip"},
{"type": "lowercase"}
]
}Input → Output:
"IN STOCK" → "in stock"
Works on: Strings and lists of strings
Parse datetime string into ISO format.
Resolution order:
- If
formatis given, use strptime (explicit wins). - Else try
dateparser— handles relative dates ("2 weeks ago", "yesterday"), 200+ languages, and fuzzy fragments. - Else fall back to
dateutil.
Parameters:
format(optional): strptime format string. Use when the input is consistent and you want strict parsing.languages(optional): list of language hints fordateparser(e.g.["en", "de"]). Speeds parsing and disambiguates locales.
Example with format:
{
"css": "time.date::attr(datetime)",
"processors": [
{"type": "parse_datetime", "format": "%Y-%m-%d"}
]
}Example with language hint:
{
"css": "span.date::text",
"processors": [
{"type": "parse_datetime", "languages": ["de"]}
]
}Example without format (auto-detect):
{
"css": "span.date::text",
"processors": [
{"type": "parse_datetime"}
]
}Input → Output:
"2024-02-24" → "2024-02-24T00:00:00"
"February 24, 2024" → "2024-02-24T00:00:00"
"24/02/2024" → "2024-02-24T00:00:00"
"2 weeks ago" → datetime 2 weeks before now (dateparser)
"yesterday" → datetime for yesterday at midnight
"15. März 2024" (de) → "2024-03-15T00:00:00"
Stored as ISO string in database (automatically serialized).
Returns None if parsing fails.
Note on fuzzy fragments: Strings like "Published on March 15, 2024" may still fail because the leading text trips both parsers. Either pre-strip the prefix with a regex processor, or keep a raw-text fallback field — don't grow date regexes; capture the raw value alongside.
Works on: Strings only
Processors run sequentially. Output of one becomes input to the next.
{
"css": "span.price::text",
"processors": [
{"type": "strip"}, // " $99.99 " → "$99.99"
{"type": "replace", "old": "$", "new": ""}, // "$99.99" → "99.99"
{"type": "cast", "to": "float"} // "99.99" → 99.99
]
}{
"css": "div.rating::text",
"processors": [
{"type": "strip"}, // " Rating: 4.5 stars " → "Rating: 4.5 stars"
{"type": "regex", "pattern": "([\\d.]+)"}, // "Rating: 4.5 stars" → "4.5"
{"type": "cast", "to": "float"} // "4.5" → 4.5
]
}{
"css": "span.status::text",
"processors": [
{"type": "strip"},
{"type": "lowercase"},
{"type": "replace", "old": " ", "new": "_"}
]
}Input: " In Stock "
Output: "in_stock"
{
"css": "span.optional-field::text",
"processors": [
{"type": "strip"},
{"type": "default", "default": "Not specified"}
]
}Processors handle errors gracefully:
- strip, replace, lowercase, join: Return original value if not applicable type
- regex: Returns original value if pattern doesn't match
- cast: Returns None if conversion fails
- parse_datetime: Returns None if parsing fails
- Unknown processor type: Skipped, logs warning
This means: If a processor fails mid-chain, subsequent processors receive the last valid value or None.
{
"css": "span.price::text",
"processors": [
{"type": "strip"},
{"type": "regex", "pattern": "\\$([\\d,.]+)"},
{"type": "replace", "old": ",", "new": ""},
{"type": "cast", "to": "float"}
]
}Handles: "$1,299.99", "Price: $99", " $42.50 "
{
"css": "div.quantity::text",
"processors": [
{"type": "regex", "pattern": "(\\d+)"},
{"type": "cast", "to": "int"}
]
}Handles: "23 items", "Quantity: 5", "42"
{
"css": "span.availability::text",
"processors": [
{"type": "lowercase"},
{"type": "regex", "pattern": "(in stock|available)"},
{"type": "cast", "to": "bool"}
]
}Returns: True if "in stock" or "available", else False
{
"css": "time::attr(datetime)",
"processors": [
{"type": "parse_datetime"}
]
}Auto-detects format, stores as ISO string.
{
"css": "li.tag::text",
"get_all": true,
"processors": [
{"type": "join", "separator": ", "}
]
}Input: ["Python", "Web Scraping", "Automation"]
Output: "Python, Web Scraping, Automation"
- Always strip text fields - Prevents whitespace issues
- Use regex before cast - Extract numeric part first, then convert type
- Chain replace for complex cleaning - Multiple replace processors handle different cases
- Default at the end - Apply fallback after all transformations
- Test selectors first - Use
./scrapai analyze --test "selector"before adding processors - Validate processor output - Run
--limit 5crawl and check withshowcommand