Monitor Competitor Prices Automatically for Free: No-Code Web Scraping with n8n
- tony56024
- 18 minutes ago
- 13 min read

In the fast-paced world of e-commerce, staying on top of your competitors’ pricing can be the difference between winning and losing sales. Yet, many founders and marketers lack the resources to build a full-fledged price-monitoring system.
We've published a video explaining this automation here if you'd like to check out :
If you’re an Amazon, Shopify, or WooCommerce seller without a dedicated data team or hefty IT budget, this guide is for you. In it, we’ll walk you through how to automatically track competitor prices—for free—using n8n, a powerful, open-source workflow automation tool. Along the way, you’ll learn basic web scraping concepts, how to structure your data, and ways to receive instant alerts when prices change.
Ready to take the guesswork out of your pricing strategy? Let’s dive in.
Download and Import the n8n Workflow JSON
Before diving into the details, we’ve made the complete n8n workflow JSON available for you. Please download the JSON file (link below) and import it into your n8n instance so you can follow along step-by-step as we build this automation. Having the workflow imported will let you see each node’s configuration in real time and test it as you go.
🔽 Download the n8n Workflow JSON: Download “competitor_price_tracker.json”
🔽 Download the Google Sheet For Running the automation: Download the Google Sheet”
Why Competitor Price Tracking Matters
Stay Competitive
Online retailers adjust prices daily—or even hourly—based on demand spikes, promotions, or flash sales. Monitoring competitor prices lets you react quickly, ensuring your product remains priced right without manual effort.
Protect Your Margins
If a competitor drops their price unexpectedly, you need to know before your inventory stagnates. Automated competitor price tracking ensures you can either match the price or highlight unique value propositions (e.g., free shipping, faster delivery) to maintain your profit margins.
Data-Driven Decisions
Instead of relying on hunches or periodic manual checks, you’ll have a clear view of price trends over time. This allows you to spot seasonal dips, bundle opportunities, and knock-out promotions that work in your niche.
No IT Team? No Problem
Traditional solutions can involve custom scripting, proxy rotations, and cloud servers—often beyond the budget of small-to-midsize online stores. By leveraging n8n, you can build a free, no-code/low-code price-tracking workflow that runs on a local machine, cloud VM, or even a Raspberry Pi.
Introducing n8n: The No-Code/Low-Code Automation Platform
n8n (pronounced “n-eight-n”) is an extendable workflow automation tool that connects with over 200 services, including Google Sheets, HTTP Requests, Telegram, Slack, and many more. It supports both drag-and-drop node connections and custom JavaScript code for situations where you need extra flexibility—like parsing HTML for price data.
For price monitoring, we’ll use these core features:
Schedule Trigger: Automatically kick off your workflow on a set interval (e.g., daily at 8 AM IST).
Google Sheets Integration: Maintain a master list of products and last-known prices in a Sheet.
HTTP Request + HTML Parsing: Scrape the competitor’s product page, extract the current price, and convert it into a numeric format.
Custom JavaScript (Code) Nodes: Clean and normalize data, calculate percentage changes, and format messages.
Conditional Logic (If Node): Only send alerts when the price actually changes.
Telegram Node: Push real-time price-change alerts directly to your phone or team chat.
Google Sheets Update/Append: Update the master data file to reflect new prices and append historical records to a “Price Tracking” sheet.
By chaining these nodes together, you can build a fully automated competitor price-monitoring system without writing a full backend. Let’s explore each step.
Step 1: Prepare Your Google Sheet (“Master Data”)
Before configuring n8n, set up a Google Sheet with at least these columns:
row_number: A unique numeric ID for each product (e.g., 1, 2, 3…).
product_url: The full URL of the competitor’s product page.
price: The last recorded price (filled manually for the first run, or left blank).
You can download the Google Sheet Sample from here and import to your google sheets
Save this Sheet and get its spreadsheet ID (the long alphanumeric string in the URL). In n8n, you’ll reference this ID to read and update your master data.
Step 2: Schedule Trigger (Run Every Day at 8 AM IST)
Add a “Schedule Trigger” node in n8n.
Set it to run daily at 08:00 hours.
If your n8n instance is set to UTC, adjust the timezone to Asia/Kolkata.
This will kick off the workflow automatically each morning, ensuring you always check prices early in the day.
Connect the Schedule Trigger’s main output to the next node (Google Sheets).
Step 3: Read Product List from Google Sheets
Add a “Google Sheets” node and connect it to the Schedule Trigger.
Choose the “Read” operation.
Paste in your spreadsheet ID and sheet name (e.g., Sheet1).
This node will pull in all rows of your master sheet: each item will have row_number, product_url, and price.
Test the connection to ensure n8n replicates the rows correctly. You should see an array of items like:
[
{
"row_number": 2,
"product_url": "https://coffeebros.com/products/cold-brew-coffee-blend",
"price": 40
},
{
"row_number": 3,
"product_url": "https://coffeebros.com/products/medium-roast-coffee-blend?",
"price": 30
},
{
"row_number": 4,
"product_url": "https://coffeebros.com/products/dark-espresso-roast-coffee",
"price": 10
}
]
Step 4: Loop Over Each Product (Split In Batches)
Add a “Split In Batches” node and connect it to the Google Sheets node.
This ensures that each product is processed individually, so if one item fails or takes longer, it doesn’t block the rest.
Keep the batch size as 1 (default). n8n will now pass one item at a time to the next nodes, effectively treating each product as its own mini-workflow.
Step 5: Delay to Avoid Request Blocking
Add a “Wait” node (label it “Delay to Avoid Request Blocking”).
Set it to wait for 20 seconds before sending the next request.
Many e-commerce sites have rate limits or IP-based filters; spacing out your HTTP requests reduces the chance of being temporarily blocked.
Connect the “Split In Batches” output to this “Wait” node. Now, for each product, n8n waits 20 seconds before performing the next action.
Step 6: Fetch the Competitor’s Product Page (HTTP Request)
Add an “HTTP Request” node and connect it to the “Wait” node.
URL: ={{ $json.product_url }} (this pulls the URL from the current batch item).
Method: GET.
Headers:
User-Agent: A realistic browser string (e.g., Chrome on Windows or Firefox on Mac).
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.9
Options: Enable “Follow Redirects” if the site uses permanent/temporary redirects.
Save and test: If successful, n8n should fetch the raw HTML of the product page.
Step 7: Parse HTML and Extract Current Price
Add an “HTML” node (named “Parse Data From The HTML Page”) and connect it to the “HTTP Request” node.
Operation: extractHtmlContent.
Extraction Values:
Key: current_price
CSS Selector: Targets the price element on the competitor’s site. For CoffeeBros, for example, it might be:
.price__regular > span.price-item--regular
Adjust this selector based on your competitor’s page structure (right-click → Inspect their price element to confirm).
An easier way is to right click, open google chrome ai assistant and then ask “share the css selector for extracting price “ share the value you see as pricing along with it.
Output: The node will return a JSON field current_price containing something like "$9.79".
Step 8: Data Cleaning (Convert to Numeric, Preserve Original)
Add a “Code” node (named “Data Cleaning”) connected to the “HTML” node.
Purpose: Clean and parse the scraped price string into a pure number, then merge it with the original data pulled from Google Sheets.
Snippet (JavaScript) (this matches what’s in your downloaded JSON):
// Get scraped result
const scraped = items[0].json;
// Retrieve the original data from the “Delay to Avoid Request Blocking” node
const original = $items("Delay to Avoid Request Blocking")[0].json;
// Convert "$9.79" → 9.79
const priceNum = parseFloat((scraped.current_price || "").replace(/[^0-9.]+/g, ""));
// Original price from Google Sheet
const lastPrice = parseFloat(original.price);
return [{
json: {
product_url: original.product_url,
row_number: original.row_number,
last_price: lastPrice,
current_price: priceNum
}
}];
What This Does:
Takes the current_price (e.g., "$9.79") and removes non-numeric characters to get 9.79.
Pulls last_price (e.g., 9.99) from the original Google Sheets row.
Returns a unified JSON object with product_url, row_number, last_price, and current_price.
In your case the code will be different, but don't worry - just paste the input and expected output to the chatgpt instance and it will get you the correct answer.
In this case the input is
[
{
"current_price": "$9.79"
}
]
The expected output is
[
{
"product_url": "https://coffeebros.com/products/dark-espresso-roast-coffee",
"row_number": 4,
"last_price": 10,
"current_price": 9.79
}
]
modify this with yours and chatgpt will help you generate the code
Step 9: Compare and Normalize Prices
Add a “Code” node (named “Compare and Normalize”) connected to the Data Cleaning step.
Purpose: Check whether the price changed, calculate the percentage difference, and attach a timestamp.
Snippet (JavaScript):
// Incoming item
const item = items[0].json;
// Did the price change?
const priceChanged = item.last_price !== item.current_price;
// Calculate percent difference
let priceDiffPct = null;
if (item.last_price && item.last_price !== 0) {
priceDiffPct = (
((item.current_price - item.last_price) / item.last_price) * 100
).toFixed(2);
}
return [{
json: {
product_url: item.product_url,
last_price: item.last_price,
current_price: item.current_price,
price_changed: priceChanged,
price_diff_pct: priceDiffPct !== null ? parseFloat(priceDiffPct) : null,
timestamp: new Date().toISOString(),
}
}];
What This Does:
Compares last_price vs. current_price.
Calculates price_diff_pct (e.g., -1.99 if price dropped).
Tags a UTC timestamp for logging/alerts.
Step 10: Fix Tab Issues (Optional Sanitization)
Add a “Code” node (named “Fixing the Broken Tab”) connected to the Compare and Normalize step.
Purpose: Clean any trailing tabs or whitespace from keys in the JSON (sometimes Google Sheets columns come with hidden tabs).
Snippet (JavaScript):
if (!items.length) return [];
const input = items[0].json;
const cleaned = {};
for (const key in input) {
const cleanKey = key.replace(/\t/g, "").trim();
cleaned[cleanKey] = input[key];
}
return [{
json: {
product_url: cleaned.product_url,
last_price: cleaned.last_price,
current_price: cleaned.current_price,
price_changed: cleaned.price_changed,
price_diff_pct: cleaned.price_diff_pct,
timestamp: cleaned.timestamp,
}
}];
What This Does:
Strips any accidental \t characters from the JSON keys.
Ensures your price_changed or price_diff_pct fields aren’t malformed.
Step 11: Conditional Logic (If Price Changed → Send Alert)
Add an “If” node connected to the “Fixing the Broken Tab” step.
Condition: Check if price_changed === true.
Logic:
If true, route data to the “Format for Output” node and append to the “Price Tracking” sheet.
If false, skip notification but still update the master sheet.
Why This Matters: You don’t want to spam yourself or your team with notifications every single day if prices haven’t changed. This node ensures you only act when there’s a real update.
Step 12: Format Alert for Telegram
Add a “Code” node (named “Format for Output”) connected to the “If” node’s true branch.
Purpose: Build a user-friendly message with emojis, price details, and IST timestamp.
const itemsFormatted = [];
for (const data of items) {
// Determine alert type
const isDrop = data.json.price_diff_pct < 0;
const alertType = isDrop ? "📉 *Price Drop Alert*" : "📈 *Price Hike Alert*";
// Convert UTC → IST (+5:30)
const date = new Date(data.json.timestamp);
const istOffset = 5.5 * 60 * 60 * 1000;
const istDate = new Date(date.getTime() + istOffset);
const formattedDate = istDate.toLocaleString("en-IN", {
day: "2-digit",
month: "short",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
hour12: true
});
// Build message
const message = `${alertType}
🛍️ Product: (${data.json.product_url})💸 Last Price: data.json.lastprice💰∗CurrentPrice:∗{data.json.last_price} 💰 Current Price: data.json.lastprice💰∗CurrentPrice:∗{data.json.current_price}📊 Change: ${data.json.price_diff_pct > 0 ? "+" : ""}${data.json.price_diff_pct}%🕒 Time: ${formattedDate}`;
What This Does:
Checks if the price dropped or rose (using emojis 📉 for drop, 📈 for hike).
Converts the UTC timestamp into IST (your local time).
Assembles a Markdown-formatted message with product URL, last/current prices, percentage change, and time.
Step 13: Send Alert via Telegram
Add a “Telegram” node connected to the “Format for Output” node.
Chat ID: Your personal (or team) Telegram chat ID (e.g., 7739958732).
Text: ={{ $json["message"] }}.
Ensure you’ve already created a Telegram Bot, copied its token into n8n’s credentials, and started a conversation with the bot so you can capture your chat ID.
Result: Whenever a price changes, you’ll get a real-time Telegram alert like:
📉 *Price Drop Alert*
🛍️ *Product:* (https://coffeebros.com/products/cold-brew-coffee)
💸 *Last Price:* $9.99
💰 *Current Price:* $9.49
📊 *Change:* -5.01%
🕒 *Time:* 02 Jun 2025, 11:30 AM
Step 14: Update Master Data File (Google Sheets)
After the “If” node (both branches), update the original row in the master Google Sheet so that the next run has the latest price.
Add a “Google Sheets” node (named “Update Master Data File”).
Operation: update.
Spreadsheet ID & Sheet Name: Same as your original.
Columns Mapping:
product_url → ={{ $json.product_url }}
price → ={{ $json.current_price }}
Matching Column: product_url (so the node knows which row to overwrite).
Why: This replaces the old price with the newly scraped price. When tomorrow’s run begins, n8n will see the updated “last_price” and calculate changes relative to that value.
Step 15: Append to “Price Tracking” Sheet (Historical Log)
Still on the “If” node’s true branch, after sending the Telegram alert, append a row to a separate sheet (tab) called “Price Tracking.”
Add a “Google Sheets” node (named Price Track Sheet1).
Operation: append.
Spreadsheet ID: Same file.
Sheet Name: Tab ID or name for “Price Tracking” (e.g., Price Tracking).
Columns Mapping (example):
timestamp: ={{ new Date($json.timestamp).toLocaleString('en-IN', { timeZone: 'Asia/Kolkata', day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', hour12: true }) }}
product_url: ={{ $json.product_url }}
current_price: ={{ $json.current_price }}
last_price: ={{ $json.last_price }}
price_diff_pct: ={{ $json.price_diff_pct }}
price_changed: ={{ $json.price_changed }}
Check “Use Append” so each new price-change event is logged below the last.
Result: You’ll build a date-stamped history of every price change, allowing you to chart trends and compute metrics like average discount periods, seasonal dips, or high-demand spikes.
Step 16: Final Wait Before Next Batch
After appending to the “Price Tracking” sheet (and/or updating master data), you may add a short “Wait” (e.g., 1 minute) before n8n moves on to the next item in the “Split In Batches” loop.
This extra delay can be useful if your competitor site has very strict rate limits or if you want to minimize load spikes.
Add a “Wait” node (named “Wait1”) connected to the “Price Track Sheet1” node, set to 1 minute. Then connect it back to the “Update Master Data File” node so the cycle completes properly.
Putting It All Together
Below is a high-level summary of the node flow:
Schedule Trigger (08:00 IST daily)
→ Google Sheets (Read master data)
→ Split In Batches (Process one product at a time)
→ Wait (Delay to avoid Request Blocking) (20 s)
→ HTTP Request (Scrape competitor page)
→ HTML Extract (Parse current_price via CSS selector)
→ Data Cleaning (Code Node) (Extract numeric price + merge with original)
→ Compare and Normalize (Code Node) (Compute price_changed, price_diff_pct, and timestamp)
→ Fixing the Broken Tab (Code Node) (Remove stray tabs from keys)
→ If (price_changed === true)
True →
Format for Output (Code Node) (Build Telegram message)
→ Telegram (Send alert)
→ Price Track Sheet1 (Append historical row)
→ Wait1 (1 minute)
→ Update Master Data File (Overwrite last price)
→ loops back (next item)
False →
Update Master Data File (Overwrite last price without alert)
→ loops back
By following these steps, you’ll have a fully automated, self-running competitor price tracker that runs every morning, scrapes your competitor’s product pages, compares prices, sends alerts to Telegram only when prices change, and builds a historical log for analysis.
Best Practices & Tips
Rotate User-Agents or Proxies (If Needed)If you’re scraping a large number of products or more restrictive websites, consider adding random User-Agent strings or lightweight proxy rotations. You can store a list of proxies in a separate Google Sheet and rotate them in your HTTP Request node.
Monitor for “No Data” or 404Sometimes product pages get removed (e.g., discontinued items). Add a second “If” node after the HTTP Request to check if current_price is empty or the HTTP status is 404. If so, send an alert that the product might have been delisted.
Error HandlingUse n8n’s built-in error workflow or add a “Catch Error” node to notify you if any part of the workflow breaks (e.g., CSS selectors changed). This way, you’ll know if scraping fails and can update your selectors or fix permission issues.
Use Descriptive Node NamesAs your automation grows, naming nodes like “Parse Data From The HTML Page” or “Format for Output” makes troubleshooting easier. Always label custom code nodes clearly (e.g., “Calculate Price Diff” vs. “Code #3”).
Clean Up Google Sheet FormattingAvoid hidden tabs/spaces in column headers—this can cause mismatches when matching columns in n8n. Always trim whitespace or special characters from header names.
Back Up Your WorkflowExport your n8n workflow as a JSON backup. That way, if you ever need to move servers or replicate the setup for a team member, you can import it quickly.
Use ChatGPT to Generate or Customize Code SnippetsEvery site’s HTML structure is different, and your needs may vary (e.g., selecting a different CSS class, handling currency symbols, or adjusting the date format). If you ever need to tweak or rewrite a JavaScript snippet, simply ask ChatGPT for help. For example, you might prompt:
“I need a custom n8n Function node code to parse the price from my competitor’s HTML. Their price is inside <span class="our-price">₹1234</span>. Generate a JavaScript snippet that:
Reads the inner text of .our-price.
Strips out the currency symbol (₹) and any commas.
Returns a number field called current_price.”
ChatGPT will then provide you with a ready-to-paste code snippet. If you need further adjustments—say, changing the date format or adding error handling—just continue the conversation:
“Now modify that snippet so it also sets price_changed to true/false by comparing with a field called last_price, and calculates a price_diff_pct.”
This way, you can avoid spending hours debugging JavaScript and instead get a clean, tested snippet you can drop into your “Code” node. Think of ChatGPT as an on-demand coding assistant: describe your desired inputs and outputs, and let the model craft the logic. Always review the generated code for your own site’s selectors and data types, but in most cases you’ll be able to paste-and-go.
Final Thoughts
Automated competitor price tracking levels the playing field for e-commerce founders and marketers who lack big budgets or technical teams. With just a handful of n8n nodes—and the JSON workflow you downloaded—you can build a robust system that:
Web scrapes competitor product pages for price data
Cleans, normalizes, and compares prices to your historic values
Sends alerts only when prices actually change
Logs each price update into a historical database for trend analysis
All without any paid subscriptions to commercial competitive intelligence platforms. And because n8n is open-source, you maintain full control over your data and workflows.
Watch our YouTube Video for Step by Step Guide on this : https://youtu.be/a9esT732mmE?si=7Jr2rVID3HUwumVR
If you’re ready to take your pricing strategy to the next level—or want to explore more advanced competitor monitoring solutions—reach out to the Datahut team today. We specialize in ethical, large-scale data extraction and can help you scale this workflow, add richer data points (e.g., dynamic promotions, stock status, review counts), or integrate with your existing BI dashboards.
About the Author
I'm Tony Paul, founder of Datahut,. We help e-commerce brands and retailers use data for smarter pricing and competitive insights. With over 14 years of experience working alongside large retail chains and major consumer brands, I've has guided countless businesses through the complexities of web scraping, data normalization, and pricing strategy.
My passion lies in making sophisticated data tools accessible to everyone—from bootstrapped startups to established enterprises—so they can make faster, data-driven decisions without a huge IT budget. I also enjoy sharing actionable tips and best practices to empower fellow founders and marketers.
Have questions or want to scale up your pricing strategy? Contact us.