{"record":{"id":"94fee4e35cd2968c","repo":"D4Vinci/Scrapling","slug":"self-class-name-must-set-target-website","errorCode":null,"errorMessage":"{self.__class__.__name__} must set `target_website`, `start_urls`, or `allowed_domains`","messagePattern":"(.+?) must set `target_website`, `start_urls`, or `allowed_domains`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scrapling/spiders/templates/shopify.py","lineNumber":43,"sourceCode":"class ShopifySpider(Spider):\n    \"\"\"A spider that extracts all products from any Shopify-powered website through its JSON API.\n\n    Set `target_website` to the store's domain (or set `start_urls`/`allowed_domains` instead), and the\n    spider walks the store's `/collections.json` pages, then each collection's `products.json` pages,\n    yielding one item per product variant without touching the website's HTML.\n    \"\"\"\n\n    name = \"shopify\"\n    target_website = \"\"\n    collections_url = \"https://{website}/collections.json?page={page}&limit=250\"\n    products_url = \"https://{website}/collections/{handle}/products.json?page={page}&limit=250\"\n    product_url = \"https://{website}/collections/{handle}/products/{product_handle}\"\n\n    def __init__(self, *args: Any, **kwargs: Any):\n        super().__init__(*args, **kwargs)\n        source = self.target_website or next(iter(self.start_urls or ()), \"\") or next(iter(self.allowed_domains), \"\")\n        if not source:\n            raise ValueError(f\"{self.__class__.__name__} must set `target_website`, `start_urls`, or `allowed_domains`\")\n        self.target_website = urlparse(source if \"://\" in source else f\"https://{source}\").netloc\n        self.collected_ids: Set[int] = set()\n\n    async def start_requests(self) -> AsyncGenerator[Request, None]:\n        yield Request(\n            self.collections_url.format(website=self.target_website, page=1),\n            callback=self.parse,\n            meta={\"page\": 1},\n        )\n\n    async def parse(self, response: \"Response\") -> AsyncGenerator[Union[Dict[str, Any], Request, None], None]:\n        collections = response.json()[\"collections\"]\n        if collections:\n            for collection in collections:\n                if collection[\"products_count\"]:\n                    yield Request(\n                        self.products_url.format(website=self.target_website, handle=collection[\"handle\"], page=1),\n                        callback=self.parse_collection,","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/spiders/templates/shopify.py#L25-L61","documentation":"The Shopify template derives the target store domain from target_website, start_urls, or allowed_domains (first non-empty value, in that order). If all three are unset/empty, __init__ raises ValueError because there is no way to build the Shopify collections/products URLs.","triggerScenarios":"Subclassing the Shopify spider without setting target_website, start_urls, or allowed_domains; setting start_urls = [] and allowed_domains = [] explicitly; setting attributes with different names (e.g. domain = \"store.myshopify.com\").","commonSituations":"Quick scaffolds of the template; renaming fields; expecting the base Spider defaults to carry over.","solutions":["Set target_website = \"store.myshopify.com\" on the subclass (bare host or full URL both work; netloc is extracted)","Alternatively provide start_urls or allowed_domains containing the store domain"],"exampleFix":"// before\nclass Store(ShopifySpider):\n    name = \"store\"\n\n// after\nclass Store(ShopifySpider):\n    name = \"store\"\n    target_website = \"store.myshopify.com\"","handlingStrategy":"validation","validationCode":"if not (target_website or start_urls or allowed_domains):\n    raise ValueError(\"set target_website, start_urls, or allowed_domains\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set target_website on Shopify spider subclasses","Use the bare myshopify.com host; the template normalizes to netloc"],"tags":["shopify","spider-template","configuration","validation"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}