Domain skill
flipkart
Markdown synced from browser-harness domain skills.
- Host
- flipkart
- Files
- 1
Agent prompt
Use this skill
Copy this prompt into your coding agent to make it enable browser-harness domain skills and read this exact domain folder before automating.
Set up https://github.com/browser-use/browser-harness for me if it is not already installed. If setup is needed, read `install.md` first to install and connect it to my real browser. Then read `SKILL.md` for normal usage and always read `helpers.py` because that is where the browser-harness functions are. Enable domain skills if they are not already enabled by setting `BH_DOMAIN_SKILLS=1` for browser-harness. Use the `flipkart` domain skill from `agent-workspace/domain-skills/flipkart/`. Read every markdown file for this domain before inventing an approach: - agent-workspace/domain-skills/flipkart/shopping.md Use those domain-skill notes to complete my task for `flipkart` in my real browser. When you open a setup, verification, or task tab, activate it so I can see the active browser tab.
Skill contents
What the agent will read
Gift & Product Shopping (Field-Tested)
shopping.md
- Field-tested against flipkart.com on 2026-04-27/28 using browser-harness CDP helpers (gotourl, js, clickatxy, typetext, capturescreenshot, scroll, presskey, pageinfo).
- ---
- Build your search via URL parameters with price and category filters baked in. Dismiss the login popup immediately on every new session. For delivery checks, enter the pincode on the product page — but note that...
- ---
Show full markdown
Field-tested against flipkart.com on 2026-04-27/28 using browser-harness CDP
helpers (goto_url, js, click_at_xy, type_text, capture_screenshot,
scroll, press_key, page_info).
TL;DR
Build your search via URL parameters with price and category filters baked
in. Dismiss the login popup immediately on every new session. For delivery
checks, enter the pincode on the product page — but note that changing pincode
may require login on some pages. Use __NEXT_DATA__ JSON extraction when
available, fall back to DOM selectors.
Gift Search URL Template
https://www.flipkart.com/search?q={query}&marketplace=FLIPKART&p%5B%5D=facets.price_range.from%3DMin&p%5B%5D=facets.price_range.to%3D{max_price}
Example — Gifts for kids under ₹500:
goto_url("https://www.flipkart.com/search?"
"q=gifts+for+kids+under+10+years"
"&marketplace=FLIPKART"
"&p%5B%5D=facets.price_range.from%3DMin"
"&p%5B%5D=facets.price_range.to%3D500")
Example — Toys under ₹200, sorted by price:
goto_url("https://www.flipkart.com/search?"
"q=toys+for+kids"
"&sort=price_asc"
"&p%5B%5D=facets.price_range.from%3DMin"
"&p%5B%5D=facets.price_range.to%3D200")
URL Parameters Reference
| Parameter | Type | Example | Notes |
|---|---|---|---|
q | string | gifts+for+kids | Search query |
page | int | 2 | Pagination (1-based) |
sort | string | price_asc | relevance, price_asc, price_desc, recency_desc, popularity |
marketplace | string | FLIPKART | Restrict to Flipkart marketplace |
p[] | string | facets.price_range.from=Min | Min price filter |
p[] | string | facets.price_range.to=500 | Max price filter |
p[] | string | facets.brand=Samsung | Brand filter |
p[] | string | facets.rating=4 | Minimum rating |
Note: p[] parameters must be URL-encoded as p%5B%5D=facets.price_range.to%3D500.
Login Popup — MUST DISMISS FIRST
Flipkart shows a login/signup modal on every new session. It blocks all interaction until dismissed. This is the #1 cause of automation failures.
js("""(()=>{
var btn = document.querySelector('button._2KpZ6l._2doB4z')
|| document.querySelector('[class*="close-btn"]')
|| document.querySelector('button[aria-label="Close"]');
if (btn) { btn.click(); return 'closed'; }
var overlay = document.querySelector('._2fS1Rz, ._3_UOR0');
if (overlay) { overlay.click(); return 'overlay_dismissed'; }
document.dispatchEvent(new KeyboardEvent('keydown', {key:'Escape', keyCode:27}));
return 'escape_sent';
})()""")
If the modal persists after JS dismiss, use coordinate click on the ✕ button (typically top-right of the modal):
click_at_xy(720, 180) # adjust based on screenshot
Delivery Check by Pincode
On search results page
Flipkart search results show estimated delivery per product. To check delivery for a specific pincode, you must visit individual product pages.
On product detail page
The delivery/pincode input is typically near the "Add to Cart" button:
# Step 1: Find and click the pincode input or "Change" link
js("""(()=>{
var change = [...document.querySelectorAll('span, a')].find(
e => e.textContent.includes('Change') && e.closest('[class*="pincode"], [class*="delivery"]')
);
if (change) { change.click(); return 'clicked change'; }
var input = document.querySelector('input[placeholder*="pincode"], input[placeholder*="Pincode"]');
if (input) { input.focus(); input.select(); return 'focused input'; }
return 'not found';
})()""")
# Step 2: Clear and type new pincode
type_text("560077")
press_key("Enter")
# Step 3: Wait and read delivery estimate
wait(3)
delivery = js("""(()=>{
var el = document.querySelector('[class*="delivery"], [class*="shipping"]');
return el ? el.innerText.trim() : 'not found';
})()""")
Gotcha: Changing pincode on some product pages requires login. If you see a login prompt after entering pincode, the delivery check won't work without authentication. In this case, use the default delivery estimate shown on the search results page.
Product Evaluation Workflow
For gift shopping, evaluate products on these criteria:
# After navigating to a product page:
evaluation = js("""(()=>{
var price = document.querySelector('div._30jeq3, [class*="selling-price"]')?.innerText?.trim();
var rating = document.querySelector('div._3LWZlK')?.innerText?.trim();
var ratingCount = document.querySelector('span._2_R_DZ')?.innerText?.trim();
var highlights = Array.from(document.querySelectorAll('li._21Ahn-'))
.map(e => e.innerText.trim()).filter(Boolean);
var delivery = document.querySelector('[class*="delivery"]')?.innerText?.trim();
var inStock = !document.querySelector('[class*="out-of-stock"], [class*="sold-out"]');
var seller = document.querySelector('[id*="seller"] a, div._3enH42')?.innerText?.trim();
return JSON.stringify({price, rating, ratingCount, highlights, delivery, inStock, seller});
})()""")
Gift suitability checklist:
- Price — within budget (parse
₹and Indian comma format) - Rating — prefer 4.0+ with 50+ ratings
- Delivery — check pincode delivery estimate (within required days)
- Availability — ensure "In Stock" / "Add to Cart" visible
- Reusability — read highlights/description for durability indicators
Filtering on Search Results Page
By price (via sidebar click)
If you need to adjust price after page load:
# Flipkart's price filter is in the left sidebar
# Look for price range inputs
js("""(()=>{
var inputs = document.querySelectorAll('input[class*="price"], input[name*="price"]');
return inputs.length + ' price inputs found';
})()""")
By rating (via sidebar click)
js("""(()=>{
var stars = [...document.querySelectorAll('div, label')].find(
e => e.textContent.includes('4★') && e.closest('[class*="filter"]')
);
if (stars) { stars.click(); return 'clicked 4-star filter'; }
return 'not found';
})()""")
By availability / delivery speed
Flipkart doesn't always expose delivery speed as a sidebar filter on all pages. When available, look for "Delivery in X days" checkboxes.
Data Extraction from Search Results
Strategy 1: __NEXT_DATA__ (Preferred)
import json
nd_raw = js("document.getElementById('__NEXT_DATA__')?.textContent")
if nd_raw:
nd = json.loads(nd_raw)
# Walk the JSON tree to find product arrays
def find_products(obj, depth=0):
if depth > 8: return None
if isinstance(obj, list) and len(obj) > 3:
if isinstance(obj[0], dict) and any(k in obj[0] for k in ['title','name','price','productId']):
return obj
if isinstance(obj, dict):
for v in obj.values():
result = find_products(v, depth + 1)
if result: return result
return None
items = find_products(nd)
Strategy 2: DOM Selectors (Fallback)
results = js("""(()=>{
var links = Array.from(document.querySelectorAll('a[href*="/p/"]'));
var seen = new Set();
return links.map(a => {
var href = a.getAttribute('href');
if (seen.has(href)) return null;
seen.add(href);
var card = a.closest('[data-id]') || a.closest('div[class]');
if (!card) return null;
return {
title: card.querySelector('div._4rR01T, a.IRpwTa, a.s1Q9rs')?.innerText?.trim()
|| a.getAttribute('title')
|| card.querySelector('img')?.getAttribute('alt'),
price: card.querySelector('div._30jeq3')?.innerText?.trim(),
rating: card.querySelector('div._3LWZlK')?.innerText?.trim(),
url: 'https://www.flipkart.com' + href,
};
}).filter(Boolean);
})()""")
Key Lessons (Field-Tested)
-
URL-first strategy — Encode search query, price range, sort order, and brand filters directly in the URL. Avoid interacting with sidebar filters when possible — they trigger React re-renders that can reset scroll position.
-
Login popup is mandatory — Every new browser session hits the login modal. Dismiss it before ANY other interaction. If JS dismiss fails, use a coordinate click on the close button.
-
Pincode delivery check has limitations — Changing delivery pincode on product pages may require login. The search results page shows a default delivery estimate that works without login.
-
Image overlay traps — Product pages have image zoom overlays that can capture clicks intended for other elements. If interactions stop working, press
Escapefirst to dismiss any overlays, then retry. -
Indian price format — Prices use
₹prefix with Indian grouping:₹1,23,456= 123,456 INR. Parse:.replace(/[₹,]/g, ''). -
Wait 3s after
wait_for_load()— Product cards load asynchronously via React.readyState=completefires before cards render. -
Use
new_tab()for first Flipkart load —goto_url()on the first visit can silently fail if the current tab resists navigation. -
Flipkart blocks datacenter IPs — Remote/headless browsers from cloud providers (e.g., Playwright Service) get
ERR_CONNECTION_TIMED_OUT. Flipkart only works from residential IPs (local Chrome). For cloud-based automation, consider alternative sites like FirstCry for kids' products. -
Category browse pages — Use
sidparameter for category navigation:https://www.flipkart.com/toys/pr?sid=tngfor toys. Combine with price facets for filtered browsing. -
Obfuscated class names change frequently — Flipkart uses Webpack-hashed CSS classes (
_4rR01T,_30jeq3). When selectors break, usea[href*="/p/"]as the stable anchor and walk up to card containers. Prefer__NEXT_DATA__extraction which is immune to class name changes.