- Add backend stale process monitoring API (/api/stale-processes) - Add users management route - Add frontend landing page and stale process monitor UI on /scraper-tools - Move old development scripts to backend/archive/ - Update frontend build with new features 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
import { firefox } from 'playwright';
|
|
import { getRandomProxy } from './src/utils/proxyManager.js';
|
|
|
|
async function findPriceLocation() {
|
|
const proxy = await getRandomProxy();
|
|
if (!proxy) {
|
|
console.log('No proxy available');
|
|
process.exit(1);
|
|
}
|
|
|
|
const browser = await firefox.launch({ headless: true });
|
|
const context = await browser.newContext({
|
|
viewport: { width: 1920, height: 1080 },
|
|
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
|
proxy: {
|
|
server: proxy.server,
|
|
username: proxy.username,
|
|
password: proxy.password
|
|
}
|
|
});
|
|
|
|
const page = await context.newPage();
|
|
|
|
const brandUrl = 'https://dutchie.com/embedded-menu/AZ-Deeply-Rooted/brands/alien-labs';
|
|
console.log(`Loading: ${brandUrl}`);
|
|
|
|
await page.goto(brandUrl, { waitUntil: 'domcontentloaded', timeout: 60000 });
|
|
await page.waitForTimeout(5000);
|
|
|
|
// Find where the prices are in the DOM
|
|
const priceLocations = await page.evaluate(() => {
|
|
const findPriceElements = (root: Element) => {
|
|
const walker = document.createTreeWalker(
|
|
root,
|
|
NodeFilter.SHOW_ELEMENT,
|
|
null
|
|
);
|
|
|
|
const results: Array<{
|
|
tag: string;
|
|
classes: string;
|
|
text: string;
|
|
isProductCard: boolean;
|
|
parentInfo: string;
|
|
}> = [];
|
|
|
|
let node: Node | null;
|
|
|
|
while (node = walker.nextNode()) {
|
|
const element = node as Element;
|
|
const text = element.textContent?.trim() || '';
|
|
|
|
if (text.includes('$') && text.match(/\$\d+/)) {
|
|
const isProductCard = element.closest('a[href*="/product/"]') !== null;
|
|
const parent = element.parentElement;
|
|
|
|
results.push({
|
|
tag: element.tagName.toLowerCase(),
|
|
classes: element.className,
|
|
text: text.substring(0, 150),
|
|
isProductCard,
|
|
parentInfo: parent ? `${parent.tagName.toLowerCase()}.${parent.className}` : 'none'
|
|
});
|
|
}
|
|
}
|
|
|
|
return results.slice(0, 15);
|
|
};
|
|
|
|
return findPriceElements(document.body);
|
|
});
|
|
|
|
console.log('\n' + '='.repeat(80));
|
|
console.log('PRICE ELEMENT LOCATIONS:');
|
|
console.log('='.repeat(80));
|
|
|
|
priceLocations.forEach((loc, idx) => {
|
|
console.log(`\n${idx + 1}. <${loc.tag}> ${loc.classes ? `class="${loc.classes}"` : ''}`);
|
|
console.log(` In product card: ${loc.isProductCard ? 'YES' : 'NO'}`);
|
|
console.log(` Parent: ${loc.parentInfo}`);
|
|
console.log(` Text: ${loc.text}`);
|
|
});
|
|
|
|
console.log('\n' + '='.repeat(80));
|
|
|
|
await browser.close();
|
|
process.exit(0);
|
|
}
|
|
|
|
findPriceLocation().catch(console.error);
|