- 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>
98 lines
2.7 KiB
TypeScript
98 lines
2.7 KiB
TypeScript
import { firefox } from 'playwright';
|
|
import { getRandomProxy } from './src/utils/proxyManager.js';
|
|
import { pool } from './src/db/migrate.js';
|
|
|
|
async function debugPage() {
|
|
const proxy = await getRandomProxy();
|
|
if (!proxy) {
|
|
console.log('No proxy available');
|
|
process.exit(1);
|
|
}
|
|
|
|
const browser = await firefox.launch({
|
|
headless: true,
|
|
firefoxUserPrefs: { 'geo.enabled': true }
|
|
});
|
|
|
|
const context = await browser.newContext({
|
|
viewport: { width: 1920, height: 1080 },
|
|
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
|
geolocation: { latitude: 33.4484, longitude: -112.0740 },
|
|
permissions: ['geolocation'],
|
|
proxy: {
|
|
server: proxy.server,
|
|
username: proxy.username,
|
|
password: proxy.password
|
|
}
|
|
});
|
|
|
|
const page = await context.newPage();
|
|
|
|
try {
|
|
console.log('Loading page...');
|
|
await page.goto('https://dutchie.com/embedded-menu/AZ-Deeply-Rooted/products/', {
|
|
waitUntil: 'domcontentloaded',
|
|
timeout: 60000
|
|
});
|
|
|
|
await page.waitForTimeout(5000);
|
|
|
|
// Take screenshot
|
|
await page.screenshot({ path: '/tmp/products-page.png' });
|
|
console.log('Screenshot saved to /tmp/products-page.png');
|
|
|
|
// Get HTML sample
|
|
const html = await page.content();
|
|
console.log('\n=== PAGE TITLE ===');
|
|
console.log(await page.title());
|
|
|
|
console.log('\n=== SEARCHING FOR PRODUCT ELEMENTS ===');
|
|
|
|
// Try different selectors
|
|
const tests = [
|
|
'a[href*="/product/"]',
|
|
'[class*="Product"]',
|
|
'[class*="product"]',
|
|
'[class*="card"]',
|
|
'[class*="Card"]',
|
|
'[data-testid*="product"]',
|
|
'article',
|
|
'[role="article"]',
|
|
];
|
|
|
|
for (const selector of tests) {
|
|
const count = await page.locator(selector).count();
|
|
console.log(`${selector.padEnd(35)} → ${count} elements`);
|
|
}
|
|
|
|
// Get all links
|
|
console.log('\n=== ALL LINKS WITH "product" IN HREF ===');
|
|
const productLinks = await page.evaluate(() => {
|
|
return Array.from(document.querySelectorAll('a'))
|
|
.filter(a => a.href.includes('/product/'))
|
|
.map(a => ({
|
|
href: a.href,
|
|
text: a.textContent?.trim().substring(0, 100),
|
|
classes: a.className
|
|
}))
|
|
.slice(0, 10);
|
|
});
|
|
console.table(productLinks);
|
|
|
|
// Get sample HTML of body
|
|
console.log('\n=== SAMPLE HTML (first 2000 chars) ===');
|
|
const bodyHtml = await page.evaluate(() => document.body.innerHTML);
|
|
console.log(bodyHtml.substring(0, 2000));
|
|
|
|
await browser.close();
|
|
await pool.end();
|
|
} catch (error) {
|
|
console.error('Error:', error);
|
|
await browser.close();
|
|
await pool.end();
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
debugPage();
|