How to build an AliExpress price monitor

Build a tracker that scrapes a category on a schedule and logs every run into Google Sheets, no code required.

AliExpress publishes no public price API. If you sell in a category AliExpress competes in, you have no way to see what it costs this week versus last, short of opening listings one tab at a time.

This tutorial builds the thing that looks for you. Three pieces do the work: E-commerce Scraping Tool reads the current prices off an AliExpress category, Google Sheets Import & Export writes every run into a spreadsheet, and an Apify schedule runs the pair whenever you need fresh data. The sheet gains a row per product per run, and a second tab collapses each run into one line: how many products came back, what the median price was, and how far it moved since last time.

Everything below happens in Apify Console and Google Sheets.

ℹ️
Apify is a marketplace of ready-to-run tools for AI, with thousands of Actors that automate everything from filling out web forms and sending emails to crawling millions of pages and transforming large datasets.

Actors run on Apify's infrastructure, so proxies, anti-bot handling, storage, and scheduling are already taken care of.

What you get in the sheet

Here’s a real output example from E-commerce Scraping Tool’s run, trimmed to the columns that matter for pricing:

name offers/price offers/priceCurrency rating reviewCount
SK26 Bluetooth 5.4 Wireless Earphones Small Earbuds Sleeping Sport Invisible Headphones 3.91 USD 4.9 86
UEESFIT A5 TWS Bluetooth Earphones HiFi Sound Headphones True Wireless ANC Noise Canceling Earbuds 3.01 USD 5 221
XIAOMI Redmi Airdots 2 Wireless Bluetooth Headset with Mic Earbuds TWS Wireless Headphones 9.18 USD 4.9 324

Prices across a single run tell you what the category costs today. Across multiple runs, they tell you which way the category is drifting. With rating and review count, you can judge whether a cheap listing is cheap because it's new or cheap because it’s a low-quality product. Review count is a maturity signal.

Each run also returns url, image, description, and inputUrl.

Step 1: Pick the category to track

Open the AliExpress category or search page whose pricing you want to follow, and copy its URL. Strip everything after the .html: AliExpress appends a long tail of session parameters (spm, guide_trace, scene_id, and friends) that change every time you open the page. In this example:

https://www.aliexpress.com/w/wholesale-Headphones-%26-Earphones.html

Step 2: Run the Actor

Open E-commerce Scraping Tool on Apify Store and click Try for free. You'll need an Apify account, which is free to create.

Apify sign-up screen for E-commerce Scraping Tool with Google, GitHub, and email options

This scraper supports three input methods: Category listing URLs, Product detail URLs, and Keywords search. You can only use one input type per run.

Input type What it is When to use it
Category listing URLs Search results or category pages with multiple products Discover many products, monitor whole categories, find new arrivals
Product detail URLs URLs pointing directly to a single product page Monitor known SKUs, track specific items for price/stock changes
Keyword search Search marketplaces (e.g. amazon.de, ikea.com, kaufland.at) by keywords Fast search - no need to gather URLs. Great for market research

In the Actor input:

  1. Paste the URL into the Category listing URLs field.
  2. Leave Scrape mode on AUTO unless runs start coming back empty, in which case try BROWSER.
  3. Set Total maximum products to a fixed number, say 20, and don't change it between runs. This caps what you can be charged, and it keeps your sample size constant.
  4. Keep the Include additional properties toggle off.
E-commerce Scraping Tool input form with Scrape mode set to Auto, an AliExpress category URL, and Total maximum products set to 20

Click Save & Start. A run takes a few minutes. When it finishes, open the Output tab and check that prices are there.

Now save the configuration as a task: click Save as a new task on the run. A task is a saved input you can schedule, which is what the next two steps need.

Step 3: Send every run into Google Sheets

Create a blank Google Sheet and give it two tabs: price_log for the raw rows, and tracker for the formulas you'll add in step 5. Keep them separate. The integration rewrites the layout of the tab it writes to on every run, so any formulas sharing that tab will be absorbed into the data and lost.

Back in Apify Console, open your task and go to the Integrations tab. Click Add integration, search for Google Sheets, and pick Google Sheets Import & Export.

Add integration screen in Apify Console with Google Sheets Import & Export highlighted in the results

Configure it like this:

  • Start when: Run succeeded. Failed runs then leave the sheet alone instead of writing a half-empty snapshot into your history.
  • Google Account: click to authorize. The Actor asks for access to the spreadsheets in that account.
  • Select file from Google Drive: pick the spreadsheet you created.
  • Mode: append. This is the setting that turns the sheet into a price history instead of a snapshot. replace wipes the sheet on every run and throws away everything you're trying to measure.
  • Range: price_log!A:G. Don't skip this one. Left empty, the Actor writes to whichever tab happens to be first, and it rewrites that tab's entire column layout on every run.
  • Columns order: ["url","name","offers/price","offers/priceCurrency","rating","reviewCount","scrapedAt"]. This pins the price to column C on every run.
  • Keep column order from sheet: on. Once the header row exists, this stops the Actor reshuffling it.
Google Sheets Import & Export integration settings with Start when set to Run succeeded, a connected Google account and file, and Mode set to append

Leave Deduplicate by field and Deduplicate by equality empty. Neither can be used alongside a transform function.

The raw output needs four fixes before it reaches the sheet, and one transform function does all of them. It stamps the date, which the Actor doesn't return. It strips the tracking parameters AliExpress appends to every URL. It converts prices like $41.70 from text into numbers you can do arithmetic on. And it drops every field you didn't ask for. It also reads the price from either shape the Actor might hand it, nested under offers or already flattened to offers/price. Paste it into Transform function:

({ spreadsheetData, datasetData }) => {
    var scrapedAt = new Date().toISOString().slice(0, 10);
    var pick = function (item, nested, flat) {
        if (item[flat] !== undefined && item[flat] !== null) return item[flat];
        var o = item.offers;
        if (o && o[nested] !== undefined && o[nested] !== null) return o[nested];
        return '';
    };
    var toNumber = function (v) {
        var n = parseFloat(String(v).replace(/[^0-9.]/g, ''));
        return isNaN(n) ? '' : n;
    };
    var rows = datasetData.map(function (item) {
        return {
            url: String(item.url || '').split('?')[0],
            name: item.name || '',
            'offers/price': toNumber(pick(item, 'price', 'offers/price')),
            'offers/priceCurrency': pick(item, 'priceCurrency', 'offers/priceCurrency'),
            rating: item.rating === undefined ? '' : item.rating,
            reviewCount: item.reviewCount === undefined ? '' : item.reviewCount,
            scrapedAt: scrapedAt,
        };
    });
    return spreadsheetData.concat(rows);
}

Save the integration. Now every time the Actor finishes running, you’ll get a new set of data. After three runs on three separate days, the spreadsheet looks like this:

Google Sheet price_log tab with AliExpress earphone listings from three runs, showing URL, name, price, currency, rating, review count, and scrape date

Step 4: Schedule it

Now, you can easily schedule the task by accessing Schedules in the left-hand navigation and clicking the Create a schedule button:

Apify Console Schedules page with the Create schedule button

You’ve already saved the task in step 2, so now it’s time to add it to the schedule. Click Add task at the bottom to customize your schedule, select a task, and choose how often you want the scraper to run - daily, weekly, monthly, or on any day that works best for you. Click Enable to complete your setup.

From here on, the sheet fills itself.

Step 5: Turn the log into a tracker

The price_log tab is now an append-only record: one row per product, per run. The tracker tab turns that into one row per run, which is the unit that means something when the products themselves change between runs.

Give tracker five columns: run date, products priced, median price, cheapest, and median change %. The formulas below assume offers/price is column C and scrapedAt is column G in price_log, which is what the Columns order setting in step 3 guarantees.

A2, the list of run dates. This one spills down on its own as runs accumulate:

=UNIQUE(FILTER(price_log!$G$2:$G$5000, price_log!$G$2:$G$5000<>""))

B2, how many products came back with a usable price. Not how many rows landed: a product with a blank price isn't in the sample the median is built from.

=IF($A2="","",COUNTIFS(price_log!$G$2:$G$5000,$A2,price_log!$C$2:$C$5000,"<>"))

C2, the median price for that run:

=IF($A2="","",IFERROR(MEDIAN(FILTER(price_log!$C$2:$C$5000,price_log!$G$2:$G$5000=$A2,price_log!$C$2:$C$5000<>"")),""))

D2, the cheapest listing in that run:

=IF($A2="","",IFERROR(MIN(FILTER(price_log!$C$2:$C$5000,price_log!$G$2:$G$5000=$A2,price_log!$C$2:$C$5000<>"")),""))

E2, the change in median since the previous run, as a percentage you can read without formatting the cell:

=IF($A2="","",IFERROR(ROUND(($C2-$C1)/$C1*100,1),""))

Fill B to E down twenty or thirty rows. They stay blank until column A spills a date beside them, so an empty tracker after your first run is the expected state, not a broken formula. You need two runs before anything appears in the change column.

Here are the results after three runs done on three separate dates:

Google Sheet tracker tab showing three runs with run date, products returned, median price, cheapest price, and median change percentage

Taking it further

The same pattern works anywhere the pieces fit together. Swap the Actor and you're tracking competitor prices in real time on the retail sites you sell against rather than the marketplace you source from. Swap Google Sheets for a database integration and the history becomes something you can query properly.

If you want to pull the same data into an AI agent instead of a spreadsheet, the Apify MCP server exposes every Actor on Apify Store as a tool, so you can ask a model how a category's pricing has shifted this week and get an answer from live data rather than a stale export

FAQ

Does AliExpress have an API for product prices?

Not a public one. The AliExpress affiliate and dropshipping APIs cover a limited product set and require program approval. For arbitrary listings, scraping the public page is the available route.

Prices on public product pages are public data, and collecting public data is generally lawful in the US and EU. What you do with it afterwards is where the obligations sit: don't republish copyrighted product descriptions or images as your own, and check AliExpress's terms for your specific use case.

How often should the scraper run?

Daily covers most category monitoring. Move to hourly only around major sale events, when prices change inside the day and the cost of catching one late is higher than the cost of the extra runs.

What happens when the products change between runs?

They will, on almost every run. That's why the tracker measures each run as a whole rather than following individual listings. A product dropping out of the results doesn't break anything, it simply isn't in that run's sample. What does matter is keeping the sample size constant, so leave Total maximum products alone once you've set it.

Why are some prices blank?

AliExpress doesn't return a price for every listing on every run, and the scraper doesn't always get through. The tracker counts only products that came back with a usable price, so a run with gaps produces a smaller sample rather than a wrong number.

On this page

Publish and earn on Apify Store

The largest marketplace of tools for AI

Start here