WooCommerce Scraper With Store Contact Leads avatar

WooCommerce Scraper With Store Contact Leads

Pricing

from $4.99 / 1,000 results

Go to Apify Store
WooCommerce Scraper With Store Contact Leads

WooCommerce Scraper With Store Contact Leads

WooCommerce Scraper discovers online stores and extracts public store details, product data, business information, contact pages, emails, phone numbers, and social profiles. Build targeted ecommerce datasets for lead generation, market research, and competitor analysis.

Pricing

from $4.99 / 1,000 results

Rating

0.0

(0)

Developer

API Empire

API Empire

Maintained by Community

Actor stats

0

Bookmarked

8

Total users

1

Monthly active users

2 days ago

Last modified

Share

WooCommerce Scraper — Extract Products and Store Contact Leads as JSON

WooCommerce Scraper With Store Contact Leads turns a WooCommerce catalogue pull into a merchant lead list. Point it at any WooCommerce shop's URL and it reads the store's public product catalogue (or categories, reviews, pages, posts and eight other record types) through the WooCommerce Store API and WordPress REST API, then attaches one contact-lead block per store — e-mails, phone numbers, postal address, social profiles — read once from the shop's own home page, real page slugs and REST page bodies. Every response is typed, normalized JSON — no HTML, no selectors, no parsing. No WooCommerce login and no API key are required for either the catalogue or the contact data. After a run you have a merchant lead list with the products (or other records) and the shop's own published contacts sitting on the same row.

What is WooCommerce Scraper With Store Contact Leads?

WooCommerce Scraper With Store Contact Leads is an Apify Actor that reads any public WooCommerce store's /wp-json/wc/store/* and /wp-json/wp/v2/* endpoints — the same public APIs the storefront's own JavaScript uses — and layers a contact-lead harvester on top. No WooCommerce account, admin login, consumer key or secret is required for the store you're scraping; you only need an Apify account to run the Actor itself.

  • Scrape the product catalogue — price, stock, SKU, rating, images, variations
  • Scrape 10 other record types on the same shop: categories, brands, tags, attributes, reviews, pages, posts, comments, taxonomies and users
  • Scrape one store contact-lead block per shop — e-mails classified as role or personal, phone numbers, postal address, social profiles, and the page each was found on
  • Export as JSON via the Apify API, or download as CSV/Excel from the dataset
  • No proxy management required — the Actor escalates from a direct request to Apify datacenter and residential proxies on its own when a store blocks it

⚠️ The contact-lead block only ever reports what a store already publishes on its own pages. Nothing is guessed, generated from the domain name, or inferred — a shop that publishes no e-mail or phone returns null lead fields, not a fabricated one.

What data does WooCommerce Scraper With Store Contact Leads collect?

Every run reads one catalogue record type per store (resource input, 11 choices) and, when contact finding is on, one contact-lead block per store that is attached to every row from that store.

Data TypeKey FieldsJSON Field Names
Products (default)name, SKU, price, stock status, rating, imagesname, sku, price_value, currency_code, is_in_stock, average_rating, review_count
Store contact leadse-mail (role/personal), phone, address, socialslead_email, lead_email_type, lead_phone, lead_city, lead_country, lead_socials, storeContact
Reviewsrating, reviewer, product referencereturned exactly as the shop's Store API publishes them
Pages & poststitle, slug, rendered contentreturned exactly as the shop's wp/v2 endpoint publishes them
Categories, tags, brands, attributesid, name, slug, countreturned exactly as the shop's Store API taxonomy endpoint publishes them

Need more WooCommerce data?

This Actor covers the storefront side of a WooCommerce shop — everything a logged-out visitor's browser can see. If you're building lead lists across other store platforms too, the same account also runs Shopify-Merchant-Scraper (verified contacts and lead rating), Shopify-Products-Scraper and Shopify-Store-Scraper for the Shopify side of the same workflow.

How does WooCommerce Scraper With Store Contact Leads differ from the official WooCommerce API?

The WooCommerce REST API is the platform's official developer API: the store owner generates a consumer key and secret from their own WordPress admin panel, and every request is authenticated with those keys. This Actor never touches that authenticated API — it reads the public WooCommerce Store API and WordPress REST API instead, the same unauthenticated endpoints the storefront's own theme and checkout already call in the visitor's browser.

FeatureWooCommerce REST APIWooCommerce Scraper With Store Contact Leads
Credentials requiredConsumer key + secret, issued by the store ownerNone — no login, no API key
Who can query a storeOnly the store owner, or whoever holds the keysAnyone who can start the Actor with the store's URL
Contact-lead dataNot provided — the API returns catalogue/order data, not merchant contact detailsBuilt-in: e-mails, phones, postal address, socials, harvested per store
Entity coverageFull store data, including orders and customers (admin-only)11 public storefront-side record types; no orders or customer data (not publicly exposed)
Setup per storeGenerate and store API keys before any callPaste the store's URL and run
Anti-bot / blocked requestsNot applicable — first-party authenticated callsAutomatic TLS-impersonating client and proxy escalation when a store's HTML surface blocks plain requests

The official REST API is the right choice when you own the store and need order or customer data behind your own keys. This Actor is the right choice when you need public catalogue and contact data from stores you do not control — competitor research, supplier discovery, merchant lead lists — without ever asking that store for access.

Why do developers and teams scrape WooCommerce stores?

For sales, growth and lead-generation teams

Build outreach lists of WooCommerce merchants without manually visiting each shop's contact page. Point the Actor at a list of store URLs with onlyStoresWithContacts on, and it returns only the shops that publish an e-mail or phone — lead_email, lead_email_type (role vs personal), lead_phone and lead_socials sit on every row, so a CRM import can go straight from dataset to pipeline without a manual pass to find a way to contact each merchant.

For dropshippers, pricing analysts and category researchers

Pull price_value, regular_price_value, on_sale and is_in_stock across a set of supplier or competitor WooCommerce stores to track catalogue overlap and price movement. Because resource also reads categories, tags and attributes verbatim, a single run can map a shop's taxonomy before pulling the full product list filtered by category or product_type.

For AI engineers and agent builders

Feed a store's typed product rows and its storeContact block directly into an agent tool or a RAG index — no HTML to parse, no selectors to maintain. A lead-qualification agent can read hasEmail, lead_email_type and price_value from the same JSON object to decide, in one pass, whether a merchant is worth a follow-up.

For market researchers and analysts

Study public storefront composition — catalogue size, pricing, review volume — across a niche of WooCommerce shops using only what each store already publishes. average_rating, review_count and the reviews resource type give a public read on customer sentiment without touching any account-gated data.

How to scrape WooCommerce stores (step by step)

  1. Open WooCommerce Scraper With Store Contact Leads on the Apify Store and click Try for free (or Run), or call it via the Apify API using its Actor ID.
  2. Provide store URLs in startUrls (or url) — one line per shop; a home page, a bare domain or a sub-directory install all work.
  3. Set resource to the record type you want (defaults to products) and, for products, narrow the results with category, tag, sku, stock, featured, sale, rating, min_price or max_price as needed.
  4. Start the run. Leave findStoreContacts on (its default) to get the contact-lead block on every row, or turn it off for the plain catalogue only.
  5. Download the results as JSON, CSV or Excel from the run's dataset, or read them via the Apify API.

What to do when a WooCommerce store changes its structure

The Actor reads the store's own public API responses, not its HTML markup or theme, so a visual redesign of the shop does not break the run. The output schema is maintained and stays stable, so integrations built against it keep working.

⬇️ Input

All inputs are optional — the schema has no required field, but a run needs at least one store URL in startUrls or url.

ParameterTypeDefaultDescription
startUrlsarrayOne line per shop: a home page (https://example.com), a bare domain, or a sub-directory install. Fill this or url.
urlarraySame as startUrls, under the key url — for driving the Actor from the API with an existing list called url.
findStoreContactsbooleantrueRead the shop's home, contact, about and policy pages and return published e-mails, phones, address and socials. Off = catalogue only.
discoverContactPagesbooleantrueAsk WordPress which pages the shop actually has (one request) instead of guessing URLs, since many shops lack /contact or /privacy-policy but do have contact-us, tos or impressum.
readContactsFromApiContentbooleantrueAlso read page bodies straight from the WordPress REST API. Keeps working on shops whose HTML pages are behind Cloudflare.
storeContactPathsarray["/contact", "/contact-us", "/about", "/impressum", "/privacy-policy"]Fallback paths, tried after the shop's real page list. Localised paths like /kontakt still matter for EU imprint pages.
maxContactPagesPerStoreinteger5 (min 0, max 20)Cap on HTML pages opened per shop while hunting for contacts. The home page is always first; 0 uses the API-only channel and opens no HTML page.
onlyStoresWithContactsbooleanfalseDrop every row of a shop that publishes neither an e-mail nor a phone. A shop whose pages could not be read at all is kept, not dropped — "not checked" isn't "no contact".
resourcestring (enum)"products"Record type: products, categories, brands, tags, attributes, reviews, pages, posts, comments, post-categories, post-tags, users. Non-product types are returned exactly as the shop's API publishes them.
limitinteger10 (min 1, max 1000)Maximum records returned per shop. Variations fetched via include_variations are on top of this number.
include_variationsbooleanfalseAlso fetch every variation of variable products (one extra request each). Variation rows carry parent and type: "variation".
formatstring (enum)"md"How description/review text is rendered: md (Markdown), text (plain text), html (raw HTML).
searchstringFree-text filter, applied by the shop's own API. Not supported for attributes or reviews.
categorystringProduct category ID(s), comma separated. Products only.
tagstringProduct tag ID(s), comma separated. Products only.
skustringReturn only the product with this SKU. Products only.
product_typestring (enum)"" (Any)simple, grouped, external, variable, wbs_bundle, variation. Products only.
stockstring (enum)"" (Any)instock, outofstock, onbackorder. Products only.
featuredbooleanfalseReturn only products marked featured. Products only.
salebooleanfalseReturn only products currently on sale. Products only.
ratingstring (enum)"" (Any)15. The Store API honours one value; only the first is applied. Products only.
min_priceintegerMinimum price in the shop's minor currency unit (1999 = 19.99 on a 2-decimal shop). Products only.
max_priceintegerMaximum price in the shop's minor currency unit. Products only.
sortstring (enum)"date"date, modified, id, include, title, slug, price, popularity, rating, menu_order, comment_count. Not every value is supported by every resource; an unsupported one falls back to the store's own order.
orderstring (enum)"" (Auto)asc or desc, applied only when sort is supported by the resource.
proxyConfigurationobject{"useApifyProxy": false}No proxy by default; the Actor escalates to an Apify datacenter proxy and then a residential proxy on its own if a store refuses the direct request.
dev_proxy_configstringYour own http:// or https:// proxy URL, used instead of the Apify proxy. SOCKS is not supported.
dev_custom_headersstringExtra HTTP headers as a JSON array of {name, value}, a JSON object, or one Name: value per line. Sent on both API and contact-page requests.
dev_custom_cookiesstringExtra HTTP cookies, same accepted formats as headers.
dev_transform_fieldsstringComma-separated field paths to keep, e.g. storeContact.emails.0.address, images.0.src. Everything else is dropped from the row.
dev_dataset_namestringWrite results to a named dataset instead of the default one. Supports {ACTOR}, {DATE}, {TIME} masks.
dev_dataset_clearbooleanfalseEmpty the named dataset above before writing. Has no effect without dev_dataset_name.
dev_no_stripbooleanfalseKeep null/empty values in the output instead of stripping them — useful to see which storeContact keys are empty on a given shop.
dev_fileuploadstringURL of a text or JSON file with one shop URL per line (or a JSON array of URLs), added to the top of the list.

Example input:

{
"startUrls": ["https://porterandyork.com"],
"findStoreContacts": true,
"discoverContactPages": true,
"readContactsFromApiContent": true,
"storeContactPaths": ["/contact", "/contact-us", "/about", "/impressum", "/privacy-policy"],
"maxContactPagesPerStore": 5,
"onlyStoresWithContacts": false,
"resource": "products",
"limit": 20,
"include_variations": false,
"format": "md",
"search": "",
"category": "",
"tag": "",
"sku": "",
"product_type": "",
"stock": "",
"featured": false,
"sale": false,
"rating": "",
"sort": "date",
"order": "",
"proxyConfiguration": { "useApifyProxy": false }
}

Common pitfall: product filters (category, tag, sku, stock, featured, sale, rating, min_price, max_price) only apply when resource is products — set on any other record type, they're logged as ignored and have no effect. Setting dev_proxy_config also replaces the automatic proxy escalation with your single proxy; the Actor will not fall back to Apify's proxies if your own proxy is blocked.

⬆️ Output

Every result is a flat JSON object — typed fields, consistent keys per resource, no HTML fragments to parse (unless you set format to html). Results are available as JSON, CSV, Excel or HTML table from the dataset, or through the Apify API. By default, null, empty-string, empty-array and empty-object values are stripped from each row (booleans and zeros are always kept); set dev_no_strip to true to keep them.

Scraped product (with the store's contact lead attached)

{
"url": "https://porterandyork.com/product/tomahawk-steak/",
"id": 4821,
"name": "Tomahawk Steak",
"slug": "tomahawk-steak",
"type": "simple",
"sku": "TMHK-32OZ",
"short_description": "Bone-in ribeye, dry-aged 28 days.",
"description": "Full product description...",
"on_sale": true,
"prices": {
"price": "8900",
"regular_price": "9900",
"sale_price": "8900",
"currency_code": "USD",
"currency_symbol": "$",
"currency_minor_unit": 2,
"currency_decimal_separator": ".",
"currency_thousand_separator": ",",
"currency_prefix": "$",
"currency_suffix": ""
},
"price_value": 89.0,
"regular_price_value": 99.0,
"sale_price_value": 89.0,
"currency_code": "USD",
"average_rating": "4.8",
"review_count": 132,
"images": [{ "id": 512, "src": "https://porterandyork.com/wp-content/uploads/tomahawk.jpg" }],
"categories": [{ "id": 17, "name": "Steaks", "slug": "steaks" }],
"is_purchasable": true,
"is_in_stock": true,
"is_on_backorder": false,
"sold_individually": false,
"add_to_cart": { "minimum": 1, "maximum": 10, "multiple_of": 1, "url": "?add-to-cart=4821" },
"store": "https://porterandyork.com",
"resource_type": "products",
"hasEmail": true,
"hasPhone": true,
"contactCheckReachable": true,
"lead_email": "hey@porterandyork.com",
"lead_email_type": "role",
"lead_phone": "+1 555-201-9922",
"lead_country": "US",
"lead_socials": "facebook, instagram",
"lead_contact_page": "https://porterandyork.com/contact-us/",
"lead_pages_read": 3
}

Store contact lead block (storeContact, attached to every row from that shop)

{
"storeUrl": "https://porterandyork.com",
"siteRoot": "https://porterandyork.com",
"channelsUsed": [
"wp/v2/pages discovery (14 page(s))",
"REST page bodies (6 scanned)",
"HTML pages (3 opened, TLS-impersonating client)"
],
"htmlSurfaceBlocked": false,
"pagesChecked": [
{ "url": "https://porterandyork.com/", "httpStatus": 200, "source": "home page", "contentHarvested": true },
{ "url": "https://porterandyork.com/contact-us/", "httpStatus": 200, "source": "page discovered via wp/v2/pages", "contentHarvested": true }
],
"discoveredPageSlugs": ["contact-us", "shipping-policy", "tos", "about-us"],
"emails": [
{ "address": "hey@porterandyork.com", "type": "role", "foundOn": "https://porterandyork.com/contact-us/", "source": "mailto link" }
],
"phones": [
{ "number": "+1 555-201-9922", "numberDigits": "15552019922", "numberFormatted": "+1 555-201-9922", "foundOn": "https://porterandyork.com/contact-us/", "source": "schema.org telephone" }
],
"postalAddress": null,
"socialProfiles": [
{ "platform": "instagram", "url": "https://instagram.com/porterandyork", "foundOn": "https://porterandyork.com/", "source": "page link" }
],
"contactFormUrls": ["https://porterandyork.com/contact-us/"],
"emailCount": 1,
"phoneCount": 1,
"socialProfileCount": 1,
"primaryEmail": "hey@porterandyork.com",
"primaryEmailType": "role",
"notes": []
}

For the other 10 record types (categories, brands, tags, attributes, reviews, pages, posts, comments, post-categories, post-tags, users), the row is the shop's own API response passed through unchanged, with store, resource_type and, when findStoreContacts is on, the same lead_*/storeContact fields added on top — the field names inside the record itself belong to that shop's WordPress installation, not to this Actor.

How does WooCommerce Scraper With Store Contact Leads compare to other WooCommerce scrapers?

FeatureWooCommerce Scraper With Store Contact LeadsGeneric alternative
Output formatTyped, normalized JSON per rowOften raw HTML or a custom parser you maintain
Store contact-lead extractionBuilt-in, two independent channels (HTML + REST) per storeNot offered — you build and maintain your own harvester
Entity coverage11 record types from one Actor (resource input)Usually product listings only
Anti-bot handlingTLS-impersonating client and automatic proxy escalation, built inManual header/proxy setup per blocked store
Schema stabilityFixed transform for products, documented passthrough for the restBreaks when the target shop's theme markup changes

If you're building an AI agent or RAG pipeline, the output format row is the decision-maker — parsing HTML inside an agent loop is a reliability failure mode, not a feature.

How many results can you scrape with WooCommerce Scraper With Store Contact Leads?

limit caps each store at 1–1000 rows (default 10); there is no hard cap in the Actor beyond that. Requests are paginated in batches of up to 100 records (per_page), advancing by offset until the limit is reached or the store returns a shorter page. When include_variations is on, expanded variation rows come on top of limit, capped by an internal fetch budget of min(limit × 20, 500) variation lookups per store. The contact-lead block itself is fetched once per store regardless of how many rows you pull, so it costs the same whether limit is 1 or 1000.

Integrate WooCommerce Scraper With Store Contact Leads and automate your workflow

WooCommerce Scraper With Store Contact Leads works with any language or tool that can send an HTTP request, through the Apify API.

REST API integration

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("<YOUR_USERNAME>/woocommerce-scraper-with-store-contact-leads").call(
run_input={
"startUrls": ["https://porterandyork.com"],
"resource": "products",
"limit": 50,
"findStoreContacts": True,
}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["name"], item.get("lead_email"))

Works in Python, Node.js, Go, Ruby, cURL.

Automation platforms (n8n, Make, LangChain)

In n8n, the Apify node's Run Actor and get dataset operation can call this Actor by its Actor ID and pass the same JSON input shown above. In Make, the Apify module's Run an Actor action does the same, with the dataset items available to downstream modules. In a LangChain or similar agent framework, wrap the Apify API call above as a tool function — the JSON rows returned need no further parsing before they go into a prompt or a vector store.

Yes — this Actor only reads pages a WooCommerce store already publishes to any logged-out visitor, through the same public API endpoints the storefront itself uses. No login, paywall or admin data is accessed.

The product catalogue, categories, reviews and other record types are business and product data; using them is governed by the target store's own terms of service and, where applicable, database-rights law — not by data-protection rules. The contact-lead block is different: e-mails (some classified as personal rather than role), phone numbers and postal addresses can be personal data. If you store or use that lead data for outreach, GDPR (EU) and CCPA (California) rules on lawful basis, storage and opt-out apply to how you use it, even though the Actor only collects what the store already made public.

Consult legal counsel for commercial use cases involving bulk personal data.

Frequently asked questions

Does WooCommerce Scraper With Store Contact Leads work without a WooCommerce account?

Yes. It reads the store's public WooCommerce Store API and WordPress REST API — the same endpoints the storefront itself calls — with no login, cookie or API key needed for the target store. You only need an Apify account to run the Actor.

How often is the scraped data updated?

Every run fetches live from the store's own API and pages at the moment it runs; nothing is cached or served from a previous run.

What happens if a store blocks the request or a page no longer exists?

A blocked HTML page (commonly Cloudflare's 403) is retried through the TLS-impersonating client and, if still blocked, the Actor falls back to reading the same content from the WordPress REST API's page bodies instead. A missing page is logged with its HTTP status in storeContact.pagesChecked and simply contributes nothing to the contact block — it does not stop the catalogue rows from being returned.

Can I scrape private or login-gated WooCommerce data?

No. Only content a logged-out visitor's browser could reach is returned — the public product catalogue and the store's own public pages. Order data, customer accounts and anything behind the WordPress admin login are not accessible and are not requested.

How much does a run cost?

Pricing is pay-per-result: each row written to the dataset — a product, category, tag, brand, attribute, review, page, post, comment or user, with its store's contact-lead block attached — is one billed row_result event. Stores that don't answer, and resources that return no records, are not charged.

Does WooCommerce Scraper With Store Contact Leads work for AI agent workflows and LLM pipelines?

Yes. It's callable as an HTTP endpoint through the Apify API from any agent framework, and every row is typed JSON — no HTML, no selectors, no parsing step before it reaches an LLM context window or a vector store.

How does it handle Cloudflare and other anti-bot protections?

HTML pages are fetched with a TLS-impersonating client (curl_cffi, Chrome 131 profile) rather than a plain HTTP client, because a Cloudflare-protected store can answer 403 to a standard client and 200 to a browser-matching TLS fingerprint from the same request. If a store's HTML surface still blocks every attempt, the WordPress REST API's page-body channel keeps working independently. Both the catalogue API calls and the contact-page requests also escalate automatically from no proxy to an Apify datacenter proxy and then a residential proxy when a store refuses the direct request.

What makes this different from a plain WooCommerce catalogue scraper?

The contact-lead block. Most catalogue pulls stop at product data; this Actor also discovers a shop's real page slugs via wp/v2/pages, reads their content through both the HTML site and the REST API, and returns classified e-mails, phone numbers, a schema.org postal address and social profiles — nothing invented or guessed from the domain name.

Can I use WooCommerce Scraper With Store Contact Leads without managing proxies?

Yes. By default no proxy is used, and the Actor escalates to Apify's own datacenter and residential proxies automatically if a store blocks the direct request. You can also supply your own proxy via dev_proxy_config or an Apify proxy group via proxyConfiguration.

What happens when a WooCommerce store changes its structure or blocks the scraper?

The Actor is maintained, and it reads the store's own API responses rather than its theme's HTML, so a visual redesign doesn't change the output. Field names and types on your end stay stable across runs.

Your feedback

Found a bug or missing a field? We want to know. Open an issue on the Actor's Apify Store page or reach out through Apify's support channel — reports like this keep the Actor's output schema accurate as WooCommerce and individual stores evolve.