const puppeteer = require('puppeteer'); const url = 'https://minsu.xiaozhu.com/detail?luId=354701406371854&startDate=2025-12-21&endDate=2025-12-22'; console.log('📋 Extracting conditions/rules from listing...\n'); (async () => { const browser = await puppeteer.launch({ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'] }); const page = await browser.newPage(); await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15'); try { console.log('🌐 Loading page...'); await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 }); await new Promise(resolve => setTimeout(resolve, 5000)); // Click on "须知" (rules) tab if it exists await page.evaluate(() => { const buttons = Array.from(document.querySelectorAll('button, div, span')); const rulesButton = buttons.find(b => b.textContent.includes('须知')); if (rulesButton) rulesButton.click(); }); await new Promise(resolve => setTimeout(resolve, 2000)); const info = await page.evaluate(() => { const result = { houseRules: [], checkInOut: '', deposit: '', restrictions: [], specialNotes: [], description: '', fullText: document.body.textContent }; const text = document.body.textContent; // Check-in/out times const checkInMatch = text.match(/入住[时時]间[::]\s*([^\n]{5,30})/); if (checkInMatch) result.checkInOut = checkInMatch[1].trim(); const checkOutMatch = text.match(/退房[时時]间[::]\s*([^\n]{5,30})/); if (checkOutMatch) result.checkInOut += ' | 退房: ' + checkOutMatch[1].trim(); // Deposit const depositMatch = text.match(/押金[::]\s*([^\n]{3,30})/); if (depositMatch) result.deposit = depositMatch[1].trim(); // Look for rules sections const elements = document.querySelectorAll('div, p, li, span'); elements.forEach(el => { const elText = el.textContent.trim(); // House rules if (elText.includes('房屋守则') || elText.includes('入住须知')) { if (elText.length < 200) { result.houseRules.push(elText); } } // Restrictions if ((elText.includes('不允许') || elText.includes('禁止') || elText.includes('不可')) && elText.length < 100) { result.restrictions.push(elText); } // Special conditions (男士/女士/夫妻等) if ((elText.includes('男士') || elText.includes('女士') || elText.includes('夫妻') || elText.includes('确认')) && elText.length < 150 && elText.length > 5) { result.specialNotes.push(elText); } // Description snippets if (elText.includes('房源介绍') && elText.length > 50) { result.description = elText.substring(0, 500); } }); return result; }); console.log('📋 CONDITIONS & RULES:\n'); console.log('⏰ CHECK-IN/OUT:'); console.log(info.checkInOut || ' Not specified in extracted text'); console.log('\n💰 DEPOSIT:'); console.log(info.deposit || ' Not found - need to ask landlord'); if (info.restrictions.length > 0) { console.log('\n⚠️ RESTRICTIONS:'); [...new Set(info.restrictions)].slice(0, 5).forEach(r => console.log(` - ${r}`)); } if (info.specialNotes.length > 0) { console.log('\n📌 SPECIAL NOTES:'); [...new Set(info.specialNotes)].slice(0, 5).forEach(n => console.log(` - ${n}`)); } if (info.houseRules.length > 0) { console.log('\n📜 HOUSE RULES:'); [...new Set(info.houseRules)].slice(0, 3).forEach(r => console.log(` - ${r}`)); } // Extract key info from description console.log('\n\n📄 KEY INFO FROM DESCRIPTION:\n'); const keyInfo = []; if (info.fullText.includes('单身男士优先')) { keyInfo.push('⚠️ Preference: Single men (单身男士优先)'); } if (info.fullText.includes('女士或夫妻需和房东再确认')) { keyInfo.push('⚠️ Women/couples need landlord confirmation (女士或夫妻需和房东再确认)'); } if (info.fullText.includes('可做饭')) { keyInfo.push('✅ Cooking allowed (可做饭)'); } if (info.fullText.includes('可带宠物')) { keyInfo.push('✅ Pets allowed (可带宠物)'); } if (info.fullText.includes('有停车位')) { keyInfo.push('✅ Parking available (有停车位)'); } if (info.fullText.includes('立即确认')) { keyInfo.push('✅ Instant booking (立即确认)'); } if (info.fullText.includes('民用燃气')) { keyInfo.push('✅ Gas stove/cooking (民用燃气)'); } if (info.fullText.includes('独立卫生间')) { keyInfo.push('ℹ️ Private bathroom available (extra cost - 独立卫生间套房需加价)'); } keyInfo.forEach(k => console.log(` ${k}`)); console.log('\n\n🏠 ROOM TYPE:'); if (info.fullText.includes('单间')) console.log(' Private room (单间) - NOT entire apartment'); if (info.fullText.includes('15m²')) console.log(' Size: 15m²'); if (info.fullText.includes('3间卧室1厅2卫1厨')) console.log(' Shared apartment: 3 bedrooms, 1 living room, 2 bathrooms, 1 kitchen'); if (info.fullText.includes('1床2人')) console.log(' 1 bed, sleeps 2 people'); if (info.fullText.includes('加客30元/人')) console.log(' Extra guest: +¥30/person'); } catch (err) { console.error('❌ Error:', err.message); } finally { await browser.close(); } })();