caprabo¶
supermercapy.caprabo.Caprabo reads caprabo's online supermarket at www.capraboacasa.com. caprabo belongs to the eroski group and runs the same apache tapestry build as eroski: the same paths, the same category ids, the same markup and the same parser. this page covers what differs, and the eroski page explains the shared mechanics.
the catalog is caprabo's own. regional products carry their own ids and prices, so caprabo sells 18581678, a catalan semi-skimmed milk at 0,99 €, where eroski sells 18672311, a basque one at 1,06 €. an id from one store is not a product at the other.
nothing binds. the storefront pins the anonymous session to shop 8284 (caprabo's online platform), and choosing another needs an account, so store_id is None and each product carries the shop_id that priced it.
from supermercapy import Caprabo
with Caprabo(language="ca") as caprabo:
page = caprabo.search_products("llet") # one request
milk = page.products[0]
milk.name # "Llet semidesnatada de Catalunya EROSKI, brik 1 litre"
milk.availability.min_quantity # decimal("6"): sold in sixes
tree = caprabo.get_categories() # one request, about 770 kb
capabilities¶
| capability | supported | how |
|---|---|---|
CATALOG |
yes | iter_catalog reads the menu, then walks each root category's listing to its empty page |
NUTRITION |
yes | ingredients and the nutrition table from the product page's characteristics |
PROMOTIONS |
yes | multi-buy badges become Promotion records |
POSTAL_CODE / STORES |
no | the shop follows the account; an anonymous session cannot pick one |
OFFERS |
no | /es/supermercado/filter/offers/ redirects an anonymous visitor to a login |
NEW_ARRIVALS |
no | nothing marks a product new |
HOME |
no | the home page carries banners and no product tiles |
EAN / EAN_LOOKUP |
no | no barcode appears in any page |
FUTURE_PRICES |
no | prices carry no dates |
extensions¶
| method | what it does |
|---|---|
get_category_products(category_id, cursor=) |
one listing page of a category, its subtree included, paged like search |
the models add the same fields as eroski's: shop_id, is_marketplace, is_lowered_price, and from a product page manufacturer, manufacturer_address, alcohol_percentage and features. categories add path and url.
request counts¶
| call | requests | size |
|---|---|---|
search_products |
one per page | about 220 kb |
get_product |
one | about 630 kb |
get_categories |
one | about 770 kb |
get_category, get_category_products |
one, plus the menu once per client | about 220 kb |
iter_catalog |
the menu, then one per page of each root plus its empty page | hundreds of pages |
as at eroski, the sizes are the html after decompression, and the wire carries about a tenth of that.
quirks¶
two languages, and the names follow them. /es/ and /ca/ are the storefront's languages, and /en/ redirects to the error page, so language="en" raises ConfigurationError. unlike eroski, caprabo translates product names into catalan as well as the menu, so the same id reads Leche semidesnatada de Cataluña in spanish and Llet semidesnatada de Catalunya in catalan.
a smaller tree. the menu holds about 930 nodes under twelve roots, the food and household ones eroski also has. eroski's electronics, appliances and bedding roots are not there.
packs. many caprabo products sell in fixed packs. the purchase options of a milk brik read a minimum of six in steps of six. availability.min_quantity and availability.increment carry those numbers, and price.amount stays the price of one unit.
robots.txt. caprabo's robots.txt disallows /*:changelanguage/, */search/results/?q=, */?zipCode and session ids. it has no ?t:ac= rule, so the category listings the client reads at /es/supermarket:loadpage?t:ac=… are not disallowed. searches go to /es/search/results:loadpage?q=…, which does not match the search rule's path literally but is the same search. the owner chose to use these paths.
everything else, the fragments, the page cursor, the menu cache, the placeholder product slug, the redirects that mean "not found", the units, the edge's 403 for a few user agents and the one-second default pacing, works exactly as the eroski page describes.
non-goals¶
- choosing a shop. the anonymous session cannot, and logging in to pick one is out of scope.
- offers and filters. the offers page needs a login, and the filter menu stores its state in the session.
- reviews. product pages carry customer reviews and ratings. the client does not parse them.