Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
You can build a Cass Art product dataset by starting with its category sitemap, collecting product links from category pages, and extracting each product’s structured data and visible page content. Before crawling, check Cass Art’s current terms and live robots.txt; the terms say site content is copyrighted and may not be reproduced without prior written permission beyond limited personal viewing, downloading or printing. Treat the method below as a workflow for data you are authorized to collect—not as permission to copy or republish retailer content.
Plan the crawl before requesting pages
First decide what you are collecting, why you need it, and what you are permitted to retain or publish. Cass Art’s terms apply to cassart.co.uk and cover product descriptions, prices, specifications and care guidance. They also state that website content is copyrighted and may not be reproduced without prior written permission, apart from limited individual viewing, downloading and printing. If your project involves storing, redistributing or commercially using product content, get written permission from Cass Art before running it.
For a permitted project, define the smallest useful dataset and keep the crawler gentle. A category page is a listing, not a product record: the representative route /watercolours/watercolour-paint-sets has a category heading and descriptive copy. Use category pages to discover product links, then fetch product pages separately. Cass Art publishes a category sitemap covering areas such as paints, brushes, paper, canvas, studio equipment, art books, craft and brand paths. That makes sitemap-led discovery a sensible starting point, but it does not override the site’s terms or robots rules.
Check current crawl controls
- Fetch the live
/robots.txton the Cass Art site you intend to access. Read the user-agent group that applies to your crawler, itsDisallowandAllowrules, any crawl-delay signal, and any sitemap declarations. - Use the sitemap declarations to locate the current category sitemap rather than relying on a guessed or hard-coded sitemap path. Sitemap and robots instructions help control access; they are not permission to reproduce content.
- Review Cass Art’s current terms and obtain written approval if the intended collection or reuse goes beyond the limited activity they allow.
- Keep a URL ledger and use a descriptive, stable user agent. Request one page at a time, pause between requests, cache responses, and stop or back off on 403, 429 or repeated server errors.
Shopify’s documentation describes common robots.txt structure and sitemap declarations, but it does not establish that Cass Art uses Shopify. Do not use platform-specific assumptions as a substitute for checking Cass Art’s live file.
#1 Best Overall
- 50 VIBRANT COLORS FOR EVERY CREATION: This set includes 50 richly pigmented watercolor pans that inspire colorful landscapes, portraits, illustrations, and everyday creative projects. The compact design makes it easy to paint wherever inspiration strikes.
- COMPLETE PAINTING KIT: Explore the rainbow with 168 vivid shades. All paints are stored in a durable, sleek box that’s great for gifting or storing in your art space. No extra tools required to start creating.
- HIGH-PIGMENT, BLENDABLE PAINT: These creamy watercolor paints blend effortlessly to create smooth gradients, vibrant washes, and fine details. Perfect for beginners, hobbyists, and experienced artists.
- PORTABLE METAL TRAVEL CASE: The lightweight metal case keeps your paints and brushes organized and protected. Ideal for painting at home, outdoors, in the classroom, or while traveling.
- SAFE FOR ALL AGES: All paints are non-toxic, mess-free, and certified to ASTM D-4236 and EN71 standards. The paint set is suitable for kids, teens, and professional artists alike.
Choose a discovery and parsing strategy
There are two useful discovery approaches. Sitemap-first collection can provide broad category coverage with fewer exploratory requests; a category walk lets you select only relevant sections and can expose links the sitemap does not make obvious. For a focused dataset, use sitemap entries to choose category seeds, then collect product URLs from those categories. Deduplicate canonical URLs before fetching product pages.
| Approach | Useful when | Main trade-off |
|---|---|---|
| Sitemap-first, then category pages | You need broad coverage across product families and brand paths. | Requires checking current sitemap declarations and filtering non-product or irrelevant paths. |
| Selected category walk | You need a limited set of departments, such as watercolour sets. | Coverage depends on the category pages and links you include. |
| Server-rendered HTML parsing | The needed fields already appear in the downloaded HTML or its JSON-LD. | May miss fields populated only after JavaScript runs. |
| Browser-rendered fallback | A required field is absent from the response HTML but appears after page scripts run. | Uses more resources and adds browser timing, selector and rendering failure modes. |
Start with ordinary HTTP requests and inspect the response. Look for canonical links, headings, visible price and availability text, breadcrumbs, image URLs, product code or SKU, specifications and JSON-LD. Use a browser only for fields you have confirmed are added or changed after JavaScript executes. Retain the response HTML or a permitted snapshot reference along with the parser version so you can diagnose changes and reprocess records.
Rank #2
- 50 Essential Colors for Every Artist: A carefully curated palette of vibrant, rich pigments that cater to all artistic styles—just add a little water to activate these semi-transparent watercolors.
- 6 Premium Brushes Included: Enjoy precision painting with high-quality brushes (sizes 3/0 to 3) featuring fine-pointed tips—no cheap water brush pens or wooden substitutes here!
- Built-In Mixing Tray for Easy Blending: The integrated mixing space lets you create custom colors effortlessly—no extra tools needed for seamless color exploration.
- Beginner-Friendly All-in-One Kit: Perfect for new artists! This set simplifies watercolor painting with ready-to-use colors and tools, so you can start creating confidently right away.
- Portable Metal Case for Artists On-the-Go: Everything stores neatly in a sturdy metal "tool box"—ideal for travel, or plein air painting adventures.
Normalize products and variants without mixing fields
A page can represent a product with selectable colours, sizes or other options. Do not assume that one URL always means one sellable item. Where the page exposes distinct SKUs or variant objects, write one record per SKU or variant. Bind the name, colour or size, price, availability and image to the same variant object. If a selector changes but the extracted SKU or price remains unchanged, mark the result for review rather than silently associating the wrong values.
Free tools Windows power users keep installed
One-click scans. No signup required.
Use a stable schema, and represent missing data explicitly as null rather than borrowing from a neighbouring product or variant. A useful starting point is:
Rank #3
- 100 Bright and Vivid Watercolors: Immerse yourself in unlimited creative possibilities with an expansive collection of 100 different watercolors. This paint set has a spectrum of colors that features 50 regular shades, 35 metallic colors, 5 fluorescent hues, and 10 candy colors. The variety of paints produce bright and vivid colors, allowing you to spend less time having to blend and create custom colors. With 100 rich and vibrant colors to choose from, the possibilities are endless!
- Versatile for Every Artist: Whether you're a budding beginner or a seasoned professional, this premium watercolor set is designed to empower artists of all skill levels. You will be pleasantly surprised at the value you get from our premium watercolor paint set. The colors are made with high-quality pigments so that they are soluble, can be easily blended, and have good working properties. Experience the joy of painting, knowing that you have a paint set that will work with your growing expertise!
- Everything You Need in One Premium Set: Experience the convenience of having everything you need to create beautiful watercolor paintings in one set. In addition to 100 unique colors, this premium set comes with 3 watercolor brush pens, 2 regular paint brushes, 1 art sponge, and 1 swatch card. Our versatile brushes each feature a different tip, so you can choose what works best for you and your art. Find all your creative essentials in one set for making effortless masterpieces.
- Portable Watercolor Studio: Paint on-the-go with this portable watercolor set! The watercolors are all protected inside a sturdy metal case, which is sized perfectly at only 3.25x8x1.5cm so you can take it with you wherever you go. This compact paint set is lightweight, easy to carry around, and won’t take up much space in your bag. Whether you're at home, in a cafe, or exploring the world, this set travels with you so you can unleash your creativity anywhere, anytime!
- High-Quality, Non-Toxic Paint Set: Paint with confidence using our premium, non-toxic watercolors. Our paints are made with high-quality pigments and conforms to ASTM D-4236 and EN71 safety standards. They are formulated to be non-toxic, while still providing rich and vibrant colors, so you can let your imagination roam free!
url, canonical_url, title, brand, product_code, sku, variant_name, colour, size, price, currency, sale_price, availability, description, specifications, breadcrumbs, image_urls, source_retrieved_at, http_status, content_hash, parser_version, raw_snapshot_reference
Store price as a parsed numeric value only when you can also preserve the displayed currency and any sale or promotion text. Keep the original availability wording as well as any normalized status you derive; wording can be ambiguous, and the retailer says displayed stock levels are only a guide. Add a retrieval timestamp to every record. A price or availability result is a snapshot, not a guarantee of what will be available when someone later visits or buys.
Example: collect authorized pages with Python
This small script demonstrates the workflow for a category you are authorized to access. It checks the live robots rules for each requested URL, fetches the category, follows same-site product links, extracts Product JSON-LD where available, and writes one CSV row per discovered product page. It does not interact with variant selectors, and it deliberately does not invent variant-level data when the page does not expose it in structured data. Install the dependencies with python -m pip install requests beautifulsoup4. Set a descriptive user agent and adjust the pause to meet the site’s live controls and any permission terms; if access is disallowed, stop rather than trying to evade the restriction.
Rank #4
- 48 Vivid Colors Best Watercolor Paints Set -- The watercolour paint set including 42 unique vibrant colors, fine pigment powder make them soluble in water easily. The color is saturated and beautiful, the effect of halo dyeing is good, the texture is light and thin, with high transparency, and create a natural blooming in your painting paper. You can play your imagination and talent more freely, easy to blend to create an endless range of colors
- Portable Watercolor Cake -- These watercolor pan set large capacity but lightweight, comes in a lightweight and sturdy plastic box makes it easy for storage and carrying. The removable cover design of case allows it not only works as a normal cover for pan, but also as a palette, to keep the watercolor paints organized and tidy. Profect for ield sketching, natural journaling or coffee-house painting, capture every beautiful moment by watercolor painting whenever inspiration strikes
- Upgraded Watercolors Set & Bright Art Paintbrushes -- Blablaovy Perfect and convenient water coloring paint set, including 48 Premium Colors, 2 paint brush and 1 water pen. Convenient for both beginners and professional artist to start painting just with few drops of water, ideal for home painting, indoors, countryside, beach, park, garden, city and anywhere you want. Bring this watercolour paint box and come to painting in suburbs on weekends ,Enjoy happy artistic creation time
- Perfect High-Quality Water Paint Supplies -- Blablaovy use elevated concentration of finely ground top permanence rating and durability pigments, make our solid watercolor paints will not crack. They are easy to blend colors, washable and dry fast , fading resistant and have excellent fluid, and there's no chalky or grainy feel to them after they are dry, is an ideal arts & crafts supply choice for outdoor sketching, scrapbooking, creative interactive classroom activities, scho
- Safety and Quality Watercolor kit -- Blablaovy Washable Watercolors is 100% Non-toxic tested and certified for safe use. Conforms to ASTM D4236 & EN71. Makes it a perfect gift for Birthday, Thanksgiving, Christmas and New Year's Eve. Suitable for kid preschoolers, students to painting novices, art lovers. Recommended Age Rage: 3 Years & Up. Best choice for encourage a passion for kids arts and crafts
import csv
import hashlib
import json
import time
from datetime import datetime, timezone
from urllib.parse import urljoin, urlparse
from urllib.robotparser import RobotFileParser
import requests
from bs4 import BeautifulSoup
BASE = "https://www.cassart.co.uk"
CATEGORY_URLS = [BASE + "/watercolours/watercolour-paint-sets"]
USER_AGENT = "ExampleResearchBot/1.0 (contact: [email protected])"
PAUSE_SECONDS = 5
session = requests.Session()
session.headers.update({"User-Agent": USER_AGENT})
robots = RobotFileParser()
robots.set_url(urljoin(BASE, "/robots.txt"))
robots.read()
def allowed(url):
return robots.can_fetch(USER_AGENT, url)
def get_page(url):
if not allowed(url):
print("Skipped by robots.txt:", url)
return None
time.sleep(PAUSE_SECONDS)
response = session.get(url, timeout=30)
if response.status_code in (403, 429) or response.status_code >= 500:
print("Stopping on response status", response.status_code, url)
return None
response.raise_for_status()
return response
def same_site(url):
return urlparse(url).netloc == urlparse(BASE).netloc
def product_links(html, source_url):
soup = BeautifulSoup(html, "html.parser")
found = set()
for link in soup.select("a[href]"):
url = urljoin(source_url, link.get("href"))
if same_site(url) and urlparse(url).path.rstrip("/") != urlparse(source_url).path.rstrip("/"):
found.add(url.split("#")[0])
return found
def jsonld_objects(soup):
for tag in soup.select('script[type="application/ld+json"]'):
try:
data = json.loads(tag.string or tag.get_text())
except (json.JSONDecodeError, TypeError):
continue
items = data if isinstance(data, list) else [data]
for item in items:
if isinstance(item, dict) and isinstance(item.get("@graph"), list):
items.extend(x for x in item["@graph"] if isinstance(x, dict))
elif isinstance(item, dict):
yield item
def first_product(html):
soup = BeautifulSoup(html, "html.parser")
for item in jsonld_objects(soup):
kind = item.get("@type", [])
kinds = kind if isinstance(kind, list) else [kind]
if "Product" in kinds:
return soup, item
return soup, {}
def text(value):
if isinstance(value, dict):
return value.get("name") or value.get("@id") or ""
return value if isinstance(value, str) else ""
rows = []
seen = set()
for category_url in CATEGORY_URLS:
category = get_page(category_url)
if category is None:
continue
for url in sorted(product_links(category.text, category.url)):
if url in seen:
continue
seen.add(url)
response = get_page(url)
if response is None:
continue
soup, product = first_product(response.text)
canonical = soup.select_one('link[rel="canonical"]')
offers = product.get("offers", {})
if isinstance(offers, list):
offers = offers[0] if offers else {}
images = product.get("image", [])
if isinstance(images, str):
images = [images]
rows.append({
"url": response.url,
"canonical_url": canonical.get("href") if canonical else None,
"title": text(product.get("name")) or (soup.h1.get_text(" ", strip=True) if soup.h1 else None),
"brand": text(product.get("brand")) or None,
"product_code": product.get("mpn") or product.get("productID"),
"sku": product.get("sku"),
"variant_name": None,
"colour": None,
"size": None,
"price": offers.get("price") if isinstance(offers, dict) else None,
"currency": offers.get("priceCurrency") if isinstance(offers, dict) else None,
"sale_price": None,
"availability": offers.get("availability") if isinstance(offers, dict) else None,
"description": text(product.get("description")) or None,
"specifications": json.dumps(product.get("additionalProperty"), ensure_ascii=False),
"breadcrumbs": None,
"image_urls": json.dumps(images, ensure_ascii=False),
"source_retrieved_at": datetime.now(timezone.utc).isoformat(),
"http_status": response.status_code,
"content_hash": hashlib.sha256(response.content).hexdigest(),
"parser_version": "example-1",
"raw_snapshot_reference": None,
})
if rows:
with open("cass_art_products.csv", "w", newline="", encoding="utf-8") as output:
writer = csv.DictWriter(output, fieldnames=rows[0].keys())
writer.writeheader()
writer.writerows(rows)
print("Wrote", len(rows), "product-page records")
else:
print("No product records collected; check access, robots rules, and page structure.")
The example’s broad same-site link collection is intentionally simple, not a claim about Cass Art’s exact page markup. For production, narrow it to product links identified from the actual category HTML or structured data, and add a reviewed allowlist of category routes. The script records one product record per page and leaves variant-only fields null. Do not treat that output as variant-complete until you validate the page’s variant model and associate each value with the right SKU.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Validate, monitor and preserve evidence
- Compare a sample of extracted records with the corresponding page as displayed. Check title, product code, price, currency, availability, images and variant association individually.
- Retain status code, retrieval time, content hash and parser version. A hash helps identify unchanged responses so you can avoid unnecessary repeat processing; it is not proof that the retailer’s underlying inventory is unchanged.
- Alert when expected JSON-LD fields or page selectors disappear. Save permitted raw HTML or another reference to the response for debugging, subject to the terms and your written permission.
- Keep nulls and failed records visible in the export or a companion log. Silently dropping pages can make a partial crawl look complete.
- Refresh near the time you use the data. Cass Art explicitly describes stock levels as a guide, not a guaranteed inventory state. It also warns that displayed colour may differ from the product and that swatches are guides.
Common failures and fixes
| Symptom | Likely cause | Safe next step |
|---|---|---|
| 403 or 429 response | The site denied or rate-limited the request. | Stop the affected requests, reduce request volume and seek permission or guidance from Cass Art. Do not rotate identities or otherwise try to bypass a block. |
| Repeated 5xx errors or timeouts | Temporary server trouble, network issues or a page taking longer than the client timeout. | Stop rapid retries, wait before trying again, log the failure and resume only at a conservative pace if access remains permitted. |
| Category crawl returns few useful links | The page structure differs from the generic link selector, or the chosen route is a listing rather than a product page. | Inspect a permitted response and tighten link selection against its actual markup. Use the category sitemap to identify additional relevant category seeds. |
| Price or availability is missing | The value may be absent from server HTML, represented differently in JSON-LD, or rendered after JavaScript runs. | Check the visible page and structured data. Use a browser-rendered fallback only if needed and permitted; store a null if you cannot verify the field. |
| Two variants share a price or SKU in your output | The parser may have read the default variant repeatedly or attached page-level data to every option. | Do not infer the other variants. Inspect the variant data model and validate that each option’s SKU, price, availability and image change together. |
| Canonical URL differs from the requested URL | The page declares a preferred URL, or the request redirected. | Record both the requested/final URL and canonical URL, then deduplicate carefully without erasing the crawl history. |
Or skip the browser setup
If you need a visual record of a permitted page rather than structured product fields, ScreenshotNeo can return a screenshot or PDF with one GET request. It is a screenshot API and MCP server, not a product-data parser: use your own extraction workflow for fields such as SKU, price and variant values. For a page where access is permitted, this cURL request saves a WebP screenshot:
Best Value
- 【24 Colors All-in-One Watercolor Kit】: This 24 colors watercolor paint set is a complete mini watercolor travel set, featuring a magnetic walnut wooden watercolor paint case with 24 solid watercolor pans. Includes a refillable water brush, detail paintbrushes, acrylic mixing palette, collapsible water cup, sponge, spray bottle, watercolor sketchbook, heart-shaped clip, and storage bag for organized travel painting.
- 【Compact Travel Storage Design】:Designed for portability, this mini watercolor travel set allows you to paint wherever inspiration strikes—at home, outdoors, or on the road. All art supplies store neatly in a zippered fabric bag measuring approx. 5.35 × 8.15 in, featuring interior elastic straps to secure each component for compact and organized travel storage.
- 【Ideal for Travel & Plein Air Painting】:Designed for outdoor sketching and travel painting, this mini watercolor travel set makes it easy to capture landscapes, city scenes, and creative moments wherever you go. A compact watercolor kit for inspiration on the move.
- 【Professional Smooth Blending Watercolors】:This watercolor paint set features 24 richly pigmented solid watercolor pans designed for consistent, professional color performance. The durable paints activate easily with a small amount of water, delivering smooth blending, controlled washes, and buildable layers for glazing and gradient techniques.
- 【Giftable Art Supplies Set】:This versatile watercolor paint set is suitable for adults, kids, beginners, hobbyists, and artists alike. A stylish gift choice and a practical addition to any art supplies collection.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://www.cassart.co.uk/watercolours/watercolour-paint-sets -o shot.webp
See the ScreenshotNeo API documentation for the request options and response headers. Cookie banners, popups and chat widgets are removed before capture; each of those steps can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, with X-Page-Verdict and X-Billed response headers indicating the result. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients. The free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots. Every feature is on every plan.
Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.
Cost, refresh cadence and responsible use
A crawler’s main costs are request volume, browser rendering when needed, storage and the engineering time spent maintaining selectors and validating variants. Sitemap-led discovery and content-hash checks can reduce unnecessary re-fetching, but neither justifies collecting or retaining material you are not authorized to use. Choose a refresh cadence based on the task, and capture a fresh timestamp every time. Because Cass Art describes stock as a guide and colours as screen-dependent, avoid presenting an old scrape as a definitive statement of current stock or exact physical colour.
For a reproducible dataset, retain the source URL, final and canonical URL when available, retrieval time, response status, content hash, parser version, explicit nulls and a permitted raw-snapshot reference. These fields make it possible to distinguish a real product change from a parser regression or an incomplete run.
Frequently Asked Questions
Can a product-page scrape establish what is in stock right now?
No. Cass Art says the stock levels shown on its site are a guide. A scrape records what the page returned at a particular retrieval time, not a guarantee of current inventory.
Does a sitemap or an allowed robots.txt path authorize reuse of product descriptions or images?
No. Sitemap and robots rules help with discovery and crawl controls; Cass Art’s terms separately address copyright and reproduction. Get written permission for reuse beyond the limited activity described in those terms.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

