- Add WorkerFingerprint interface with timezone, city, state, ip, locale - Store fingerprint in TaskWorker after preflight passes - Pass fingerprint through TaskContext to handlers - Apply timezone via CDP and locale via Accept-Language header - Ensures browser fingerprint matches proxy IP location This fixes anti-detect detection where timezone/locale mismatch with proxy IP was getting blocked by Cloudflare. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
56 lines
2.2 KiB
TypeScript
56 lines
2.2 KiB
TypeScript
/**
|
|
* Compare MED vs REC product menus for same location
|
|
*/
|
|
import puppeteer from 'puppeteer-extra';
|
|
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
|
|
puppeteer.use(StealthPlugin());
|
|
|
|
async function main() {
|
|
const browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox'] });
|
|
const page = await browser.newPage();
|
|
|
|
await page.goto('https://www.iheartjane.com/stores', { waitUntil: 'domcontentloaded' });
|
|
await new Promise(r => setTimeout(r, 2000));
|
|
|
|
// Fetch REC products (store 3379)
|
|
const recProducts: number[] = await page.evaluate(async () => {
|
|
const res = await fetch('https://search.iheartjane.com/1/indexes/menu-products-production/query', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ query: '', hitsPerPage: 100, filters: 'store_id=3379' }),
|
|
});
|
|
const data = await res.json();
|
|
return data.hits?.map((h: any) => h.product_id) || [];
|
|
});
|
|
|
|
// Fetch MED products (store 4540)
|
|
const medProducts: number[] = await page.evaluate(async () => {
|
|
const res = await fetch('https://search.iheartjane.com/1/indexes/menu-products-production/query', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ query: '', hitsPerPage: 100, filters: 'store_id=4540' }),
|
|
});
|
|
const data = await res.json();
|
|
return data.hits?.map((h: any) => h.product_id) || [];
|
|
});
|
|
|
|
const recSet = new Set(recProducts);
|
|
const medSet = new Set(medProducts);
|
|
|
|
const recOnly = recProducts.filter(id => !medSet.has(id)).length;
|
|
const medOnly = medProducts.filter(id => !recSet.has(id)).length;
|
|
const shared = recProducts.filter(id => medSet.has(id)).length;
|
|
|
|
console.log('\nHana Phoenix - MED vs REC comparison (100 products each):');
|
|
console.log(' REC products fetched:', recProducts.length);
|
|
console.log(' MED products fetched:', medProducts.length);
|
|
console.log(' REC-only:', recOnly);
|
|
console.log(' MED-only:', medOnly);
|
|
console.log(' Shared:', shared);
|
|
console.log(' Menus are:', shared === 0 ? 'COMPLETELY DIFFERENT' : shared === recProducts.length ? 'IDENTICAL' : 'PARTIALLY OVERLAPPING');
|
|
|
|
await browser.close();
|
|
}
|
|
|
|
main().catch(console.error);
|