ScreenshotNeo

BlogHow-to

How to Scrape Costco Product Data: Prices, Items, and Availability

Learn what Costco product data means, how prices and availability differ by channel, and how to build a compliant extraction workflow.

By the ScreenshotNeo team29 September 20269 min read

How to Scrape Costco Product Data: Prices, Items, and Availability

Direct answer: Costco product data is channel-specific and time-sensitive. A useful record normally includes an item number, description, observed price, channel, warehouse or geography, availability status, and retrieval timestamp. However, Costco’s US Site Terms restrict commercial use, collection of product listings or descriptions, and automated extraction such as bots and spiders. Do not treat a publicly visible product page as permission to scrape it. For a business use case, obtain written authorization or use an authorized data arrangement that you verify with Costco.

This guide explains what Costco exposes through its consumer interfaces, how to model observations, and how to build a parser for HTML you are authorized to collect. It also covers the differences between Costco.com, warehouse lookup, and Costco Same-Day. The examples avoid bypassing controls, CAPTCHAs, login barriers, rate limits, or other access restrictions.

1. Read the access rules before writing code

The cited Costco US Terms and Conditions of Use grant a limited license for personal use. Under “License and Site Access,” Costco says the grant does not include “any resale or commercial use” of the sites or site materials. The same section excludes collection and use of product listings or descriptions and data-mining methods such as bots, spiders, and automated tools. These terms were last updated January 28, 2023. They apply to the US site; check the applicable terms for another Costco country site.

Costco also reserves the right to change products, prices, specifications, and offers without notice. Its terms do not guarantee that site materials are accurate, complete, reliable, current, or error-free. A captured price is therefore an observation at a particular time and through a particular channel, not a durable quote.

Costco Same-Day is a separate service. Its terms say Costco transmits warehouse prices and item availability to Instacart, which adds costs and fees. The terms limit access to interfaces provided for that service and give automated scraping as an example of prohibited access. Do not assume that Same-Day data is a public API or that access to Costco.com authorizes collection from Same-Day.

2. What “Costco product data” can mean

Before collecting anything, define the fields your application actually needs. The following is a proposed record design, not a claim that Costco publishes these fields together in a downloadable feed.

Field Purpose Why it matters
item_number Costco item identifier Useful for matching observations over time.
description Product name and variant Distinguishes sizes, colors, pack counts, and models.
price and currency Observed amount Store as a number plus currency; preserve the displayed text separately when needed.
channel online, warehouse, or same_day Prevents unlike prices from being compared as if they were identical.
location Warehouse, ZIP code, region, or country Availability and pricing can vary geographically.
availability Observed status Keep values such as in_stock, limited, unavailable, or unknown separate from a numeric quantity.
observed_at UTC retrieval time Shows when the observation was made and helps detect stale data.
source_reference Authorized page, export, or agreement reference Provides an audit trail without pretending the observation is permanent.

Keep raw evidence, such as an authorized HTML snapshot or export, alongside normalized rows. Record parser version and retrieval method so a correction can be reproduced without repeatedly requesting the source.

3. Costco.com, warehouse lookup, and Same-Day are different channels

Channel What you may observe Interpretation limits
Costco.com Online catalog listings, descriptions, and online prices Online products may differ in price from local warehouse items. Offers and specifications can change.
Warehouse lookup When an item is found, Costco Customer Service says results can include pricing, availability, item number, department, and a photo. Inventory and pricing may be delayed by up to 30 minutes, are subject to change, and out-of-stock items are not displayed.
Costco Same-Day Warehouse prices and item availability transmitted to Instacart Additional service costs and fees can be added. Same-Day terms prohibit automated scraping of the service.

Never merge rows from these channels without retaining the channel, geography, and timestamp. A lower online price does not prove a lower warehouse price, and a Same-Day total can include costs that are absent from a warehouse observation.

Keep online, warehouse, and Same-Day observations separate because their prices and availability have different meanings.
Keep online, warehouse, and Same-Day observations separate because their prices and availability have different meanings.

4. A compliant do-it-yourself workflow

  1. Confirm authority and scope. Get written permission or an authorized feed for the exact pages, fields, frequency, and use case. If you only need a one-off comparison, use Costco’s consumer interface manually and record the displayed context.
  2. Choose a source artifact. Prefer an export, documented endpoint, or HTML snapshot supplied under the authorization. Do not defeat a bot check, CAPTCHA, consent mechanism, login control, or rate limit.
  3. Capture context. Save channel, warehouse or ZIP selection, country, currency, and UTC timestamp with every row.
  4. Parse conservatively. Treat missing price or availability as unknown. Do not infer that a product is out of stock merely because it is absent; Costco’s warehouse lookup does not display out-of-stock items.
  5. Validate changes. Compare item number, description, and price against the previous authorized snapshot. Flag changes for review instead of silently overwriting history.
  6. Respect retention and deletion terms. Remove data when your agreement or applicable law requires it, and keep credentials out of source control.

Python: parse an authorized HTML snapshot

Save a permitted snapshot as costco_snapshot.html. This parser reads product cards from your own artifact; it does not request Costco or bypass any control.

Parse an authorized snapshot and retain the channel, location, and observation time with every row.
Parse an authorized snapshot and retain the channel, location, and observation time with every row.
from bs4 import BeautifulSoup
from decimal import Decimal
from datetime import datetime, timezone
import json

with open("costco_snapshot.html", encoding="utf-8") as f:
    soup = BeautifulSoup(f, "html.parser")

observed_at = datetime.now(timezone.utc).isoformat()
rows = []
for card in soup.select("[data-product-card]"):
    def text(selector):
        node = card.select_one(selector)
        return node.get_text(" ", strip=True) if node else None

    price_text = text("[data-price]")
    price = None
    if price_text:
        cleaned = "".join(ch for ch in price_text if ch.isdigit() or ch == ".")
        price = str(Decimal(cleaned)) if cleaned else None

    rows.append({
        "item_number": card.get("data-item-number"),
        "description": text("[data-description]"),
        "price": price,
        "currency": card.get("data-currency", "USD"),
        "channel": card.get("data-channel", "unknown"),
        "location": card.get("data-location"),
        "availability": card.get("data-availability", "unknown"),
        "observed_at": observed_at,
    })

with open("products.json", "w", encoding="utf-8") as f:
    json.dump(rows, f, indent=2, ensure_ascii=False)

print(f"Wrote {len(rows)} observations")

cURL: preserve an authorized artifact

If your authorization provides a downloadable export, save it without transforming the response. Replace the placeholder with the URL supplied by the authorized provider.

curl --fail --location --output costco_snapshot.html "AUTHORIZED_EXPORT_URL"

Node.js: normalize parsed records

This example reads the JSON produced by the Python parser and filters records that have an item number. It is useful when a Node service owns downstream storage.

import { readFile, writeFile } from 'node:fs/promises';

const rows = JSON.parse(await readFile('products.json', 'utf8'));
const normalized = rows
  .filter(row => row.item_number)
  .map(row => ({
    ...row,
    availability: row.availability || 'unknown',
    observed_at: new Date(row.observed_at).toISOString()
  }));

await writeFile('products.normalized.json', JSON.stringify(normalized, null, 2));
console.log(`Normalized ${normalized.length} rows`);

5. Handling edge cases

  • Missing product: Absence from a result is not proof of discontinuation or out-of-stock status. Store unknown unless the authorized source explicitly states a status.
  • Delayed warehouse data: Costco Customer Service says lookup inventory and pricing can lag by up to 30 minutes. Display the observation time and delay caveat to users.
  • Price formatting: Currency symbols, thousands separators, sale labels, and unit prices can coexist. Preserve raw text and parse only when the currency and amount are unambiguous.
  • Variants: Match on item number plus variant attributes; descriptions alone can collide.
  • Location changes: A warehouse selection, ZIP code, or region change can alter availability. Treat location as part of the key.
  • Consent and dynamic content: If an authorized capture requires JavaScript, use the approved method and retain the resulting snapshot. Do not remove consent controls or automate interactions outside your permission.
  • Retries: Retry transient failures with bounded exponential backoff only when your agreement allows it. Never increase request volume to work around a block.

6. Validation, reliability, and cost controls

Use a small validation suite against saved fixtures: a normal product card, a missing price, a sale price, a variant, and a location-specific availability message. This catches selector changes without contacting Costco. Add schema checks that reject impossible negative prices, unknown currencies, and timestamps that are not UTC.

For reliability, make ingestion idempotent. A stable key such as channel + location + item_number + observed_at prevents duplicate rows when a job is retried. Queue work, cap concurrency, and keep a dead-letter record for artifacts that fail validation. Monitoring should report parse failures and schema drift rather than repeatedly retrying the same page.

Costs include authorized data-access fees, storage, review time, and compute. Warehouse lookup results can become stale within the stated 30-minute window, while online offers can change without notice. Choose refresh intervals from your business requirement and authorization, then show users when data was observed. Do not promise real-time inventory.

7. Troubleshooting

Symptom Likely cause Fix
HTTP 403, CAPTCHA, or bot-check page The source is restricting automated access. Stop. Confirm authorization and use an approved export or interface; do not bypass the control.
Products array is empty Selectors no longer match, or content is rendered after load. Inspect an authorized snapshot, update selectors, and add a fixture test. Do not increase request volume.
Price is null Sale or membership markup separates amount and label. Keep raw price text, parse only a clearly identified amount, and flag ambiguous rows.
Warehouse availability disagrees with a store Lookup data may lag by up to 30 minutes or omit out-of-stock items. Show channel and observation time; do not present the lookup as real-time.
Online and warehouse prices differ They are separate pricing bases and promotions. Store separate channel values and avoid cross-channel substitution.
Same-Day total is higher Instacart can add service costs and fees. Report the Same-Day channel and its displayed fees separately.

8. Or skip the browser setup

For an authorized page or internal catalog, ScreenshotNeo can return a screenshot or PDF through one request. See the ScreenshotNeo API documentation for parameters and response details.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://www.costco.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://www.costco.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://www.costco.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Use this only where you have permission to capture the target. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed as clean shots, and each response reports its page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. You get 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

9. Frequently asked questions

Can I scrape Costco prices for a commercial dashboard?

Not under the permissions described in Costco’s US Site Terms. Seek written authorization or an authorized data arrangement first, and confirm that it covers automated collection, retention, and redistribution.

Is Costco warehouse inventory real time?

No. Costco Customer Service says pricing and availability can be delayed by up to 30 minutes, can change, and do not display out-of-stock items.

Are Costco.com and Same-Day prices interchangeable?

No. Online, warehouse, and Same-Day are different channels. Same-Day can include additional service costs and fees.

Does Costco provide a public bulk product-data API?

The research for this guide did not verify one. Do not infer an API from a consumer-facing page; ask Costco or an authorized provider directly.

Where can I learn general Python scraping techniques?

Apress lists Website Scraping with Python: Using BeautifulSoup and Scrapy by Gábor László Hajba as general background on BeautifulSoup, Scrapy, data processing, and Selenium. It is not Costco-specific guidance or authorization to collect Costco data.

Sources