Groups, rules and exports
Rules for all scrapers
A scraped price is rarely comparable as it is. One shop shows 9,99 €, another £8.50, a third 12.49 USD. One lists 500 ml, another 0.5 l. The cheaper number can be the more expensive product. Rules fix this after the scrape and before matching. You write them once on the group and they run on every scraper in it, also on uploaded files.
Four things usually need a rule:
- One currency. Convert every price to EUR with the daily ECB rate. The rate and its date are written next to the price.
- One unit. Divide the price by the pack size to get a price per 50 g, per 100 g, per litre or per piece.
- One label. Map
In stock,Availableand1to one word. - One number. Take the pack size out of text such as
2 x 250 ml.
The rules add new columns. They never change what you scraped, unless you tick Replace the extracted value in on a rule (see the screen list below). When a rule cannot work, for example the pack size is missing, the cell stays empty and the row gets a marker. A rule never writes a value it had to guess.
- Open the 3-dots menu of the group and pick Rules for all scrapers. The dialog has three parts: Rules, Scrapers and Labels.
- In Rules press Add a rule and pick a kind.
- Convert currency: under Take the value from pick the price column. Pick Fixed currency and a From currency, or From a column and name the column that holds the currency code (Currency code is in this column). Pick the target in To, for example EUR. Name the new column in Save the result as, for example
price_eur. - Price per unit: pick the price column. Under Pack size is in this column pick the column with the pack size, for example
pack_grams. Or use Fixed number and Divide by this fixed number. Type the size to compare at in Rescale to this size, for example 50. The buttons Cents → units (÷100), kg → g (×1000), oz → g and lb → g fill the numbers for common cases. Name the new column, for exampleunit_price. - Take a number from text: reads a number and a unit out of text such as
Ball 100 g. Use Add a unit or Edit as a list to say which unit words count. - Replace values from a list: When scraped value is one thing, Save as another. Add another row for more. Use If no row matches, save this instead for the rest.
- Clean up text: type Which characters to keep? and pick Letter case.
- To test, type a real value in Paste or type a real value from your data (and a Sample pack size for a unit rule) and press Try it. Nothing is saved.
- Press Add to list. To change a rule later use Update rule. Keep editing and Close without saving protect unsaved work.
- Use Add a condition when a rule should run only on some rows, for example only where
product_typeisyarn. A rule can have up to 3 conditions and all must be true. - When one calculation has several versions, put its rules in a Choice group with one Choice each, for example per 50 g, per 100 g and per piece. Add choice, Edit choice and Delete choice manage them. A row must fit exactly one choice.
- Press Save new rules to save the whole list.
- In Labels press Add label, type a Label name and give each scraper its value, for example
product_typeisyarnfor one shop. Labels only steer conditions. They are not written into the rows. - In Scrapers search with Search scrapers. see Problems and see Own rules filter the list. Show all problems opens every problem. Reload reads the rules again.
To run the current rules again on the rows of a finished run, open History on the group’s data page and press Re-apply rules on the run. Look at the numbers and press Re-apply. Stop re-apply rules ends it. Rows already changed keep their new values.
- Base address
https://portal.scrapewise.ai/api/scraper-api, headerAuthorization: Bearer <key>. Which key: a Read key looks, a Full key also changes things, see Read or Full. - With a Read key, read the rules:
GET /api/scraper/group/{id}/post-process-rules. Noteversion. - With a Full key, test one rule:
POST /api/scraper/preview-rulewithrule,sampleValueand, for a unit rule,sampleQuantity. Remove theconditions,branchSetandbranchlines from the rule first (delete those keys from the JSON), because the test ignores them. - With a Full key, save the whole list:
PUT /api/scraper/group/{id}/post-process-ruleswithexpectedVersion,rulesandscraperValues, and a newIdempotency-Key. The PUT replaces all rules. Readwarningsin the answer. A warning is not an error. - Run a scraper with a Full key, then check the new columns with a Read key on a few rows.
- To change rows of a finished run, use the re-apply calls below (Full key).
The exchange rates that the Convert currency rule uses are open to read: GET /api/fx/rates with a Read key. The answer has base (EUR), date and rates, the units of each currency for 1 EUR. To change X from currency A to currency B, work out X / rates[A] * rates[B].
Kinds of rule (kind): CURRENCY_CONVERT (Convert currency), QUANTITY_NORMALIZE (Price per unit), NUMBER_EXTRACT (Take a number from text), ENUM_MAP (Replace values from a list), REGEX_CLEAN (Clean up text). Run GET /api/scraper/config/parameters for the allowed values and limits.
curl -X PUT "https://portal.scrapewise.ai/api/scraper-api/api/scraper/group/[GROUP ID]/post-process-rules" \
-H "Authorization: Bearer $SCRAPEWISE_FULL_KEY" \
-H "Idempotency-Key: [NEW UUID]" \
-H "Content-Type: application/json" \
-d '{
"expectedVersion": 0,
"scraperValues": { "[SCRAPER ID]": { "product_type": "yarn" } },
"rules": [
{ "kind": "CURRENCY_CONVERT", "sourceField": "price", "outputField": "price_eur", "outputType": "NUMBER",
"params": { "fromField": "currency", "to": "EUR" } },
{ "kind": "QUANTITY_NORMALIZE", "sourceField": "price", "outputField": "unit_price", "outputType": "NUMBER",
"params": { "quantityField": "pack_grams", "targetQuantity": 50 },
"branchSet": "basis", "branch": "per_50g",
"conditions": [ { "field": "product_type", "op": "equals", "value": "yarn" },
{ "field": "pack_grams", "op": "notBlank" } ] },
{ "kind": "QUANTITY_NORMALIZE", "sourceField": "price", "outputField": "unit_price", "outputType": "NUMBER",
"params": { "quantityField": "pack_pieces", "targetQuantity": 1 },
"branchSet": "basis", "branch": "per_piece",
"conditions": [ { "field": "product_type", "op": "equals", "value": "accessory" },
{ "field": "pack_pieces", "op": "notBlank" } ] }
]
}'
In this example expectedVersion is 0 because the group has no rules yet. If it has rules, send the version you read in step 2. scraperValues gives a value per scraper for a column the conditions read: { "<scraper id>": { "<column>": "<value>" } }.
Order. A scraper’s own rules run first, top to bottom. Then the group rules run. A group rule can read a column that a scraper rule wrote. A scraper rule cannot read a group rule’s column. If a scraper has its own rule for the same outputField, the scraper’s rule wins on that scraper.
Conditions. At most 3 per rule, all must be true. op is equals, in, contains, notBlank or blank. Comparing ignores upper and lower case and outer spaces. The value is taken from the row column, or from the scraper’s label of the same name when the row has none.
Choice groups. Give rules a branchSet and a branch. Each rule of a choice group needs at least one condition. Choices of one group may write the same output column. Per row: one matching choice runs. No match gives the marker RULE_NO_BRANCH:<set>, more than one gives RULE_MULTI_BRANCH:<set>, and nothing from the group is written. There is no default choice. Write conditions that exclude each other.
Limits. At most 50 rules, a document of 64 KB, 3 conditions per rule, 10 choice groups with 2 to 10 choices each, 5 label names, label values of 1 to 50 characters.
Row markers in _sw_warnings: RULE_NO_BRANCH, RULE_MULTI_BRANCH, RULE_NO_INPUT:<output> (a needed column is missing), RULE_UNUSABLE:<output> (the input cannot be used or the output name is already a column) and RULE_RATE_CONFLICT:<to>_rate (two conversions needed different rates). A product with no sale_price simply gets no sale_price_... columns.
Re-apply to a finished run. With a Read key POST /api/scraper/data/job/{jobId}/reapply-rules/preview shows what would change on the first rows. With a Full key POST /api/scraper/data/job/{jobId}/reapply-rules re-runs the rules on every row in the background. GET /api/scraper/data/job/{jobId}/reapply-rules (Read) shows its state: PENDING, RUNNING, COMPLETED, CANCELLED or FAILED. GET /api/scraper/data/reapply-rules/active (Read) lists the ones in progress. POST /api/scraper/data/job/{jobId}/reapply-rules/cancel (Full) stops one.
Changes apply to runs that start after the save. A run that is already going keeps the rules it started with.
- Connect your assistant with a Full key. See Connect Claude.
- Ask it to read the rules first:
scrapewise_get_scraper_group_post_process_rules(Read). It must send back theversionit read. - Ask it to test each rule before saving:
scrapewise_preview_scraper_preview_rule(Read). Conditions and choice groups are left out of the test. - Ask it to save:
scrapewise_update_scraper_group_post_process_rules(Full) withid, a newidempotency_keyand abodythat holdsexpectedVersion,rulesandscraperValues. - Ask it to read
warnings(a Read tool) and fix everything except the known harmless ones. A unit rule for pieces on a scraper that has only grams is fine. - To redo a finished run:
scrapewise_preview_reapply_rules(Read), thenscrapewise_run_reapply_rules(Full),scrapewise_get_reapply_rules(Read) to follow it,scrapewise_list_reapply_rules(Read) for all active ones andscrapewise_cancel_reapply_rules(Full) to stop.
scrapewise_get_scraper_group_post_process_rules
{ "id": "[GROUP ID]" }
When an assistant builds the setup for you, it follows one best practice: scrapers copy raw values with the same column names, and the group does the maths. The agent skill describes it.
A price-compare layout that works
- Two rules outside any choice: Convert currency
pricetoprice_eurandsale_pricetosale_price_eur, both with the currency from thecurrencycolumn. - One choice group
basis, with one choice for each unit, for example per 50 g, per 100 g and per piece. Each choice writes the same columns:unit_price,sale_unit_price,unit_price_eur,sale_unit_price_eurandunit. Theunitis a fixed word such as50 g, written with Replace values from a list from thepricecolumn. - Each scraper gets a label, for example
product_typeisyarn,accessoryormixed. The conditions use it together with the pack size column. - Never scrape a column called
unit,unit_price,sale_unit_priceor any*_eur. A scraped column with a rule’s output name blocks the rule.
Note
The platform writes eur_rate and eur_rate_date on every converted row. Do not name a column that.
Errors you may see
version.Questions
Why on the group and not on each scraper?
With twelve scrapers you would copy the same rule twelve times and the copies drift. On the group it exists once. A scraper can still override one rule, and you can see which scrapers do.
Does a rule change the price I scraped?
No. A rule only adds columns. If the row already has a column with the rule’s output name, the rule is skipped and your column stays.
When do changes apply?
To runs and samples that start after you save. Use Re-apply rules to update the rows of a finished run.
Do rules run on uploaded files?
Yes, on a replace import and on the new rows of an add import. Rows that an add import only fills in get no rules.
Why is a price converted at a different rate than today's?
The rate belongs to the day the row was scraped. eur_rate_date shows which day.
Everything on this screen
The dialog:
- The title reads Rules for all scrapers and the group name.
- Rules, Scrapers and Labels: the three parts. Each shows a count, for example Rules (3).
- Save: saves the list. It says Saving while it works. close leaves the dialog.
- Rules run when the scraper runs. Click a chip on the left to edit a rule, or add more on the right.
Inside a rule:
- Remove this row: deletes one row of a Replace values from a list rule.
- Condition 1 value: the value a column must have for the rule to run. Each condition has a column box, an operator box (is, is not and so on) and this value. Remove condition 1 deletes the condition.
- Unit word 1: a unit word to look for in the text, for example g or kg. The number next to it says how many base units one word is worth. Remove unit 1 deletes it.
- Replace the extracted value in: tick it when the new value is more reliable than what the page gave. The old value in that column is then replaced.
Choice groups:
- Choice name: the name of one choice, for example per 50 g.
Labels part:
- Rename label opens a New name for label box. Save name of label keeps the new name. Delete label removes it.
Scrapers part:
- Details: shows more about a scraper and its rules or problems.
- The filter chips above the list switch between all scrapers, scrapers with problems and scrapers with their own rules.
- Rows per page, Prev and Page 1: move through a long list.
Last updated 4 November 2026