PetSmart Product, Price & Promo Scraper (US)
Pricing
from $1.95 / 1,000 product scrapeds
PetSmart Product, Price & Promo Scraper (US)
PetSmart scraper: search terms or category, brand and offer pages to one row per product with USD price, list price, discount, price range across sizes, running promotions, rating, reviews, Autoship flag, brand and image. For pet-supply price and promo watching.
Pricing
from $1.95 / 1,000 product scrapeds
Rating
0.0
(0)
Developer
Superslow Sloth
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
8 days ago
Last modified
Categories
Share
Search PetSmart (the US pet retailer) by keyword, or read a category, brand or new-arrivals page, and get one flat row per product: the current price and the list price in USD, the discount in dollars and percent, the lowest and highest price across the product's sizes, the promotions currently running on it (Autoship offers, code offers, shipping and loyalty messages), rating and review count, brand, category, pet type, the product link and the photo. Run it on a schedule and diff the dataset to get a pet-supply price and promo watch: which foods, litters and treats dropped in price, and which only advertise an Autoship discount or a code.
No account, no API key, no login, no browser. One request returns 40 products.
Input
| Field | Notes |
|---|---|
searchTerms | One or more search terms, one per line (cat food, dog dental chews, kong). A brand name such as royal canin or friskies is sent by the site to that brand's page and that whole list is read; any other term is read as search results. A product found by two terms is returned once, under the first. |
startUrls | PetSmart pages to read in full: a category (/dog/food/, /cat/food-and-treats/dry-food/), a brand (/featured-brands/royal-canin/) or a collection (/new-and-featured/f/pet/cat). A filter kept in the address (?brand=Royal+Canin) is kept on every page. A search URL (/search/?q=...) is read as that search term. The page must list products; the home page, /sale/ and /store-locator/ list none and fail with a message. Give terms, URLs or both. |
maxItems | Products to read per term or page (default 100, up to 10,000). 40 per page. |
onlyOnSale | Return only products whose current price is below the list price. Products that are not reduced are read, not returned and not charged. |
sort | relevance (default), best-sellers, price-asc, price-desc, new-arrivals, top-rated: the choices of the site's own sort menu. See the depth note below: only relevance goes past 1,000 products. |
proxyConfiguration | Apify datacenter proxy by default. |
Example input:
{"searchTerms": ["cat food", "dog dental chews"],"startUrls": [{ "url": "https://www.petsmart.com/dog/food/" }],"maxItems": 120,"onlyOnSale": true,"sort": "price-asc"}
Output
Prices are numbers in US dollars; currency is the currency the page states
(USD on every page measured).
| Field | Notes |
|---|---|
query, position | The search term or page URL that first found the product, and its place in the site's list for that source and sort (1 is first). |
product_id, master_product_id, url | PetSmart's item number (5209028), the number of the product page it belongs to (20995; sizes and flavors of one product share it) and the product link. url comes from the page's structured data and is null if the page did not send it. |
name, brand | As the page shows them (HTML entities decoded). |
category, categories, pet_types | The primary category (Dry Food), the category list the site files it under, and the pets it is for (Cat, Dog, ...). |
price, original_price | price is the price now. original_price is the list price. They are equal when the product is not reduced. Both are the price of the product's default size, see below. |
on_sale, discount_amount, discount_percent | on_sale is true when price is below original_price. discount_amount is the dollars off and discount_percent is worked out from the two prices (one decimal place). Both are null when the product is not on sale, never 0. |
price_min, price_max | The lowest and highest price across the product's sizes and flavors, the figures behind the card's "$15.58 - $28.59". Equal for a product with one price. |
promotions, promo_text | The promotions PetSmart attaches to the product that are running now, in the site's own order. Each has text, type (autoship or null), discount (35% or null), starts and ends (ISO times or null). promo_text is the first one's text. An empty list and a null promo_text mean none. |
variations | The card's variation labels, e.g. ["3 Sizes", "1 Flavor"]. |
rating, review_count | Average star rating and number of reviews. Null for a product with no reviews. |
autoship_eligible | True if the product can be put on Autoship (repeat delivery). |
in_store_only, online_only | The site's availability flags. Null when the page does not send the flag, which is common: null is not false. |
discontinued | True for a product the site marks discontinued. Null for the rest (the page only sends the flag on some). |
upc | The barcode number where the page sends one. |
image_url | The product photo. |
Example row (real values, 2026-10-16):
{"query": "cat food","position": 5,"product_id": "5209028","master_product_id": 20995,"name": "Hill's® Science Diet® Perfect Weight Adult Dry Cat Food - Chicken","brand": "Hill's Science Diet","url": "https://www.petsmart.com/cat/food-and-treats/dry-food/hills-science-diet-perfect-weight-adult-dry-cat-food---chicken-20995.html","image_url": "https://s7d2.scene7.com/is/image/PetSmart/5209028?$sclp-prd-main_large$","category": "Dry Food","categories": ["Dry Food"],"pet_types": ["Cat"],"currency": "USD","price": 69.99,"original_price": 71.99,"on_sale": true,"discount_amount": 2.0,"discount_percent": 2.8,"price_min": 24.99,"price_max": 69.99,"promotions": [{ "text": "Earn $10 back in savings (5,000 points) when you spend $39+ with Free Same-Day Delivery thru 10/18. One-time use.", "type": null, "discount": null, "starts": "2026-10-13T09:30:00.000Z", "ends": "2026-10-19T09:30:00.000Z" },{ "text": "Get 40% OFF your 1st Hill's Autoship order, 20% OFF your 2nd & 10% OFF your 3rd. Place your first order by 10/31.", "type": "autoship", "discount": "40%", "starts": "2026-10-02T09:30:00.000Z", "ends": "2026-11-01T09:30:00.000Z" },{ "text": "Save an additional 20% on your 1st Autoship order of select dog & cat food with code: EXTRA20", "type": null, "discount": null, "starts": "2026-10-08T09:30:00.000Z", "ends": "2026-10-20T09:30:00.000Z" },{ "text": "Free Same-Day Delivery, No Order Minimum!", "type": null, "discount": null, "starts": null, "ends": null },{ "text": "Sign In & Enjoy Free Shipping Over $49", "type": null, "discount": null, "starts": "2026-02-03T23:00:00.000Z", "ends": null }],"promo_text": "Earn $10 back in savings (5,000 points) when you spend $39+ with Free Same-Day Delivery thru 10/18. One-time use.","variations": ["3 Sizes", "1 Flavor"],"rating": 4.5,"review_count": 1144,"autoship_eligible": true,"in_store_only": false,"online_only": false,"discontinued": null,"upc": "052742297002"}
What the price fields mean
PetSmart sells one product in several sizes. The page gives the product a
default size with a list price and a current price, and a range across all
sizes. price and original_price are the default size's two prices (they are
the current and list figures the page sends, and the card's price text agrees
with them on every product measured: 960 products checked). price_min and
price_max are the card's range. In the example, the 24.99 to 69.99 range comes
from sizes of the same food; the default size costs 69.99, so price_max equals
price here. That is common but not a rule (the default size was the top of the
range on 267 of the 342 ranged products measured). To compare one size over time,
join on product_id and watch price.
An Autoship or code offer is not a reduction. "Save 35% on your first
Autoship order" and "with code: EXTRA20" do not change the shelf price: price
does not include them, and on_sale stays false when the product is not
otherwise reduced. They are in promotions. Filter on
promotions[].type == "autoship"on_sale for shelf reductions.
Promotions: what is in the list
The site attaches to every product its store-wide messages ("Free Same-Day
Delivery, No Order Minimum!", "Sign In & Enjoy Free Shipping Over $49",
loyalty-point offers) as well as product-specific ones, so the list is rarely
empty. The page also still sends promotions whose end date has passed and
promotions with no text (price steps of the Autoship program). The actor drops
both: a promotion is kept only if it has text and is running at the time the
page was served (judged on the page's own clock). Check starts and ends to
see how long an offer lasts.
Honest nulls
A field the page did not send is null, never 0 or "".
- No rating (
rating,review_countnull) means the product has no reviews. in_store_onlyandonline_onlyare null when the page omits the flag. Do not read null as false.urlis null if the page's structured data did not list the product.discontinuedis only ever true or null.
Pricing
Pay per event:
- $0.002 per run (
actor-start), charged only after your input is validated, so a run that fails on bad input costs nothing. - $0.00195 per product row written (
product-scraped), i.e. $1.95 per 1,000 products. A row that is not written is not charged: rows filtered byonlyOnSale, and repeats of a product another term already returned, are free.
How it fetches
It reads the product list that petsmart.com's own pages embed: the first answer of the site's search engine, as JSON in the page, plus the page's structured data for the product links. Measured 2026-10-16: HTTP 200 from a plain home connection and from an Apify datacenter address, no key or cookie needed. A refusal (403, 429, 5xx), a 200 that is not a PetSmart product list, or a dropped connection is treated as the address being blocked, and the actor rotates to a fresh one and retries. No refusal page was ever served while this was built, so that path is tested against a stand-in, not a recorded page.
Things worth knowing, all measured:
- A page is about 1.5 MB and takes 2 to 4 seconds. A run of 1,000 products is 25 pages, around 40 MB of proxy traffic.
- Depth depends on the sort.
relevancegoes up to 250 pages, which is 10,000 products (a search matching 16,912 products answered page 250 and refused page 251). Every other sort stops at 25 pages, 1,000 products, however many match (cat foodmatches 3,478; its price-descending page 26 is empty). The log says so when a list was cut short, and the run summary names those sources. To see more than 1,000 in price order, narrow the search or use a category page. - Category and brand pages default to best sellers, which is a sorted list and
so also stops at 1,000 (
/dog/food/has 1,810). The actor always sends the sort you chose (relevance unless you set another), so a category read with the default settings reads the whole list. - A sort the site does not know is ignored, not refused. The site answers a misspelled sort with relevance order and HTTP 200. The actor sends only the values of the site's own menu and checks which list answered each page; if it is not the one asked for, that source fails with "sort was ignored" instead of returning the wrong order.
- A brand name is redirected.
royal canin,friskies,blue buffaloandhill's science dietare sent by the site to/featured-brands/<brand>/, and the redirect drops the sort and the page. The actor reads that brand page, again with your sort, and continues from there; the run log names the page.querystays the term you typed. Most other terms (cat food,litterwith a sort,purina) are answered in place as search results. - Terms are cleaned. Spaces at the start and end and doubled spaces change the
site's result count (
cat foodfinds 3,219 andcat food3,478), so the actor trims and collapses them. Case does not matter. - A search with no match is not an error. The site answers it with HTTP 404 and no products; the actor reports "no results" in the log and returns nothing for that term, at no charge. A page that does not exist (an unknown category path) is also HTTP 404, but its body is the site's whole default list; the actor treats that as a missing page and fails the source.
- Not offered. The site's facet filters are not inputs. A filter kept in a
start URL's address (
?brand=Royal+Canin) is honoured by the site and kept by the actor; start from a page that already narrows the list. - No stock levels. Product pages hold the stock; the list pages do not, so the
rows say nothing about availability beyond
in_store_onlyandonline_only.