AliExpress Search Scraper — Prices and Promotion Context avatar

AliExpress Search Scraper — Prices and Promotion Context

Pricing

from $1.50 / 1,000 product rows

Go to Apify Store
AliExpress Search Scraper — Prices and Promotion Context

AliExpress Search Scraper — Prices and Promotion Context

Collect AliExpress keyword listings with displayed prices, currency, ratings, sales badges and promotion conditions. Independent search tool with locale checks and bounded diagnostics.

Pricing

from $1.50 / 1,000 product rows

Rating

0.0

(0)

Developer

tingyou333 zhuang

tingyou333 zhuang

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Collect AliExpress keyword listings with product IDs, titles, images, displayed prices, source currency, ratings, sales badges and the conditions attached to promotional offers. Export JSON, CSV or Excel for product discovery and catalog comparison.

Independent tool; not affiliated with AliExpress. The supported release scope is bounded keyword search. Product-detail/SKU extraction, delivery eligibility and broad international coverage are not established capabilities of this release.

What you can use it for

  • Build shortlists of listings for a keyword, retaining the product link and original source position.
  • Compare displayed offers together with their currency, promotion notices and selected SKU reference.
  • Export available ratings and sales badges with explicit nulls and lower-bound indicators.
  • Inspect source-locale and rejected-card diagnostics before using a result downstream.

Searches use public structured pages. The Actor does not use your cookies, log in, solve challenges or substitute static/sample products when the source is blocked.

Quick start

Start with one keyword, three results and one page. This example is the exact saved validation input; country is intentionally omitted. A Korean language/KRW request does not mean a Korean delivery destination. The historical cloud source reported US/ko/KRW for this input.

{
"keywords": [
"wireless earbuds"
],
"currency": "KRW",
"language": "ko",
"maxItems": 3,
"maxPages": 1,
"includeVariants": false,
"maxConcurrency": 1,
"maxRetries": 0,
"requestTimeoutSecs": 30,
"maxRunSeconds": 90,
"dnsMode": "system",
"proxyConfiguration": {
"useApifyProxy": false
},
"sort": "default",
"requireLocaleMatch": true,
"outputFormat": "kawsar"
}

After the run, open the dataset and SUMMARY. A nonempty dataset can belong to a PARTIAL run, so check both. Copy the complete input above. Selected fields from one actual result appear in Example and price conditions, with the observed counts and locale in Latest acceptance sample. These are historical observations, not current quotes.

The demonstrated acquisition scope includes small ko/KRW search samples; en/USD and explicit US settings have local saved-response and earlier live evidence. Each new request still needs observed source-locale verification. Shipping, seller eligibility and worldwide coverage are not inferred from language, currency or a regional hostname.

Inputs

FieldDefault / limitsBehavior
keywordsRequired unless an alternate target input is used; 1–10 combined targetsSearch each distinct keyword separately.
maxItems48; 1–200 per keywordMaximum valid output rows after filters and deduplication; not a promise to find that many.
maxPagesceil(maxItems / 60); 1–20Hard page cap. Results can end earlier due to source limits, duplicates or errors.
sortdefaultdefault, price_asc, price_desc, orders, rating. Default preserves source order; other modes sort collected candidates. Global catalog ranking is unverified.
minPrice, maxPriceAbsentInclusive filters on the raw displayed value in its source currency. No FX conversion or ordinary-price inference.
minRating, minOrdersAbsent; rating 0–5, orders ≥0Unknown values do not satisfy an active filter. Abbreviated sales badges are marked lower bounds.
currency, countryAbsentOptional uppercase currency (3 letters) and destination (2 letters). Country is never derived from language/currency.
languageRuntime request language en when omittedExplicit choices: en, de, es, fr, pt, it, nl, ja, ko. Input availability does not prove source support in every locale.
requireLocaleMatchtrueReject mismatched/unverified explicit locale requests. False retains actual source values but reports locale gaps/PARTIAL; it does not convert currency.
requestTimeoutSecs60; 30–180Per-request limit, also constrained by the whole-run budget.
maxRunSeconds95; 10–110Collection deadline; set a compatible platform timeout, such as 120 seconds.
maxConcurrency, maxRetries2 / 1; ranges 1–8 / 0–2Bounded parallel targets and retries. Challenges are not solved or repeatedly retried.
proxyConfiguration, useProxyOffOptional user-owned proxy settings. Configuration failures are explicit; real paid-proxy connectivity is unverified and proxy costs are extra.
dnsModesystemgoogle-doh is an explicit alternate resolver with TLS and public-IP checks. Keep system DNS for the supplied cloud example.
outputFormatkawsarPrimary field layout; devcake selects alternate names and string-valued tags. This is a field mapping, not complete competitor parity.
searchQueries, maxProducts, sortBySecondary aliasesmaxProducts defaults to 50 with searchQueries, range 50–1000. Conflicting aliases fail. sortBy omits rating.
productUrls, includeVariantsAbsent / falseDetail and SKU routes exist but are outside the validated release scope. Missing required detail/SKU data fails the target. Leave them unused for the supported search workflow.

Local filters and candidate sorting are implemented; exact server filter/sort behavior is not independently guaranteed. Requests for variants can make otherwise usable listings fail if the detail source is unavailable.

Output fields

FieldsTypeMeaning
keyword, page, positionstring, integer, integerOriginal query and 1-based source page/card position; positions can have gaps after filtering or rejection.
productId, productTitle, productUrlstringSource listing identity, full title and direct item link.
imageUrl, additionalImagesstring, string[]Source image links; extra images may be empty.
price, currencynumber, stringFinite displayed price and source currency. Never relabelled to the requested currency.
formattedPrice, originalPrice, originalFormattedPrice, discountstring/number or nullSource display/reference price and discount badge, when usable. Reference price is not a verified normal or historical selling price.
priceContextobjectPromotion type, builder, selected SKU, original page notice, marker sources and explicit uncertainty flags.
rating, reviewCountnumber/integer or nullAvailable source rating/review count; absent values stay null.
orders, ordersText, ordersIsLowerBoundinteger/null, string/null, booleanParsed sales badge, original text and whether it is abbreviated/qualified; not audited transaction history.
tags, shipping, shippingFromstring[], string/null, string/nullPublic card labels and optional explicit shipping/origin fields. Null is unknown, not free shipping or delivery eligibility.
isTopRatedbooleanThis Actor's rating ≥4.8 rule, not an independently verified AliExpress designation.
scrapedAt, recordTypestringUTC observation timestamp and record kind (search in the supported workflow).
variants, variantStatusarray/null, stringNull / NOT_REQUESTED for normal search. A selected SKU reference in priceContext is not a complete variant list.
_sourceobjectResponse URL/hash, observation time, requested versus observed locale and ordering scope.

The default dataset views are products, devcake and provenance. Both output formats preserve priceContext. The Output fields table describes the primary kawsar layout. The devcake option changes field names and uses string-valued tags; confirm its output shape in a small run before migrating.

Example and price conditions

This is an excerpt of one actual row observed on 26 September 2026 UTC. Selected fields from one of the three accepted cloud rows are shown below. The exact quickstart input completed its bounded three-row request with verified US/ko/KRW source locale. This does not establish complete catalog coverage.

{
"keyword": "wireless earbuds",
"page": 1,
"position": 1,
"productId": "3256811621288203",
"productTitle": "2026 뉴 에어 3【 프로 3 】 심박수 모니터링 기능이 있는 블루투스 무선 이어버드, 능동형 소음 제거 헤드폰, 일상 사용을 위한 방수 기능, 아이폰 IOS 스마트폰용, 게임/스포츠/피트니스 이어폰.",
"price": 29363,
"currency": "KRW",
"formattedPrice": "₩ 29,363",
"orders": 4000,
"ordersIsLowerBound": true,
"priceContext": {
"kind": "DISPLAYED_PROMOTIONAL_PRICE",
"builderType": "skuCoupon",
"selectedSkuId": "12000056622341651",
"ordinarySingleItemPrice": null,
"eligibilityVerified": false,
"sourcePriceTips": {
"confirm": "알겠습니다",
"title": "가격 설명",
"priceDesc": "신규 회원용 표시 가격은 #placeholder#에서 상품 3개를 구매할 때 지불할 총구매 가격입니다."
}
}
}

These are displayed promotional values, not verified ordinary single-item or checkout prices. Source notices can refer to new-member, coupon or multi-product offers. We retain the original notice and selected SKU instead of inferring eligibility, dividing a bundle value, converting currency or filling an ordinary price. A page-level notice does not prove that every item has identical conditions. ordinarySingleItemPrice=null and eligibilityVerified=false must remain visible in downstream use.

Result status and diagnostics

maxItems is an upper bound. With default order, no filters/variants and verified locale, the requested N valid rows can complete even when a later card is invalid. The run then retains a warning and sourceComplete=false. Unknown card types are diagnosed; valid advertisements are not discarded just because they are advertisements.

An uncertain card inside the selected prefix, too few valid rows with card issues, sorting/filter/variant uncertainty, repeated pages, source errors or locale mismatches remain PARTIAL/BLOCKED as appropriate. All fetched cards and page/query/locale checks run before the cap is accepted. Earlier valid pages may remain in the dataset after a later failure. No error object is written as a product.

sourceComplete concerns detected core-field integrity of fetched material, not proof of complete page/catalog enumeration, optional fields, details or delivery. Use the cap, selection-prefix and PARTIAL rules in this section when automating.

OutputContents
DatasetValid persisted product rows only.
SUMMARYOutcome, stop reasons, selected counts, warnings and locale observations.
DIAGNOSTICSHTTP/DNS failures and response hashes.
CARD_DIAGNOSTICSAt most 32 rejected-card samples and 32 KiB of complete SDK-serialized JSON per run; aggregate/truncation counts continue even when samples are omitted.

Pricing

The paid unit is one valid product row saved in the default dataset. Each separately saved record is another row. Inline arrays do not create extra row events. Failed requests, duplicate rows and diagnostic records do not create result events. A valid source record may have nullable optional fields; a row charge does not guarantee every field.

Apify planUSD per rowUSD per 1,000 rows
FREE0.0022.00
BRONZE0.00181.80
SILVER0.00161.60
GOLD0.00151.50
PLATINUM0.00151.50
DIAMOND0.00151.50

There is no startup event fee. FREE names the Apify subscription tier; it does not mean results are free. The Pricing tab shows the active rate before a run.

Apify platform compute, storage and transfer are charged separately, including for failed or empty runs. An explicitly enabled proxy can add provider fees. A row limit is not an all-inclusive dollar cap. Use small inputs first and inspect actual run usage. Historical owner test runs are not customer revenue or cost forecasts.

API example

Save the JSON from Quick start as input.json in your current directory. This example starts a charged run. Keep your Apify token in the APIFY_TOKEN environment variable.

import json
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
with open("input.json", encoding="utf-8") as handle:
actor_input = json.load(handle)
run = client.actor("2qUM3kDDGZaYKvMaE").call(
run_input=actor_input, memory_mbytes=256, timeout_secs=120
)
summary = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("SUMMARY")
rows = client.dataset(run["defaultDatasetId"]).list_items().items
print(run["status"], summary["value"], rows)

FAQ

Why did I get fewer results or a failed run? The cap is a maximum. Source challenges, locale mismatches and incomplete core cards are explicit outcomes. Check SUMMARY before treating partial data as complete.

Does Korean/KRW mean shipping to Korea? No. Country is separate. Request it explicitly if needed; strict mode requires the source to report that destination. Reported destination is still not proof of delivery eligibility.

Are stock, full variants or ordinary prices guaranteed? No. Those are outside the validated search scope. Unknown fields remain null and promotional conditions remain attached.

Can I migrate from another scraper? Common input and field layouts are supported, with documented type differences. Complete competitor coverage, exit-status parity and worldwide reliability are not claimed.

Can it use my cookies or solve a CAPTCHA? No. Only fresh anonymous public locale preferences are generated. Login/challenge pages are failures, not product rows.

The Latest acceptance sample section records the bounded cloud evidence; other coverage limits are stated in Inputs and Result status and diagnostics. Brand artwork identifies the target service; it does not imply affiliation or endorsement.

Latest acceptance sample

The quickstart input was checked in Apify Cloud on 2026-09-26 (UTC; run finished at 2026-09-26T18:34:39.340Z). It saved 3 valid rows. The output example on this page copies real source values from that dataset; it is a dated sample, not current inventory or a current quote.

The three-row core sample observed US/ko/KRW and 60 valid cards with no rejected cards. A separate one-row billing check of the identical runtime found 56 valid cards and four cards without prices at positions 39, 42, 46 and 57. All four were after the selected first row: the request succeeded with sourceComplete=false and INVALID_CARDS_AFTER_CAP. The four rejected cards were saved only in CARD_DIAGNOSTICS (8,161 serialized bytes), not as billed dataset rows. The 32 KiB truncation stress case has local test coverage only. Displayed promotional values do not establish an ordinary unit price or purchase eligibility.