From 957e817edbdecd2202f54099d88c192037243638 Mon Sep 17 00:00:00 2001 From: dimaromsa Date: Tue, 7 Apr 2026 17:47:24 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20parse/=20collect=5Fdealers=5F2gis.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- parse/ collect_dealers_2gis.js | 89 ++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 parse/ collect_dealers_2gis.js diff --git a/parse/ collect_dealers_2gis.js b/parse/ collect_dealers_2gis.js new file mode 100644 index 0000000..69a8baf --- /dev/null +++ b/parse/ collect_dealers_2gis.js @@ -0,0 +1,89 @@ +(async () => { + + const processed = new Set(); + const results = []; + + let page = 1; + + while (true) { + console.log(`📄 Страница ${page} — сбор...`); + + const cardContainers = document.querySelectorAll('div._1kf6gff'); + + for (let i = 0; i < cardContainers.length; i++) { + const container = cardContainers[i]; + + const link = container.querySelector('a[href*="/firm/"]'); + if (!link) continue; + + const href = link.href.split('?')[0]; + const idMatch = href.match(/\/firm\/([^/]+)/); + const id = idMatch ? idMatch[1] : null; + + if (!id || processed.has(id)) continue; + processed.add(id); + + const name = container.querySelector('span._lvwrwt span, h3, [class*="name"]')?.innerText.trim() || '—'; + + console.log(` 🔥 ${processed.size} — ${name}`); + + container.click(); + await new Promise(r => setTimeout(r, 300)); + + const phoneBtn = document.querySelector('button, [role="button"], [class*="phone"], [aria-label*="телефон"]'); + if (phoneBtn && /телефон|позвонить|показать/i.test(phoneBtn.innerText || phoneBtn.getAttribute('aria-label') || '')) { + phoneBtn.click(); + await new Promise(r => setTimeout(r, 300)); + } + + let secondPhone = '—'; + const allPhones = []; + document.querySelectorAll('a[href^="tel:"]').forEach(l => allPhones.push(l.href.replace('tel:', '').trim())); + + if (allPhones.length >= 2) secondPhone = allPhones[1]; + else if (allPhones.length === 1) secondPhone = allPhones[0]; + + const address = container.querySelector('[class*="address"], ._sfdp8cg, ._klarpw, ._14quei')?.innerText.trim() || '—'; + + results.push({ + name: name, + address: address, + phones: secondPhone, + link: href + }); + + const closeBtn = document.querySelector('button[aria-label*="закрыть"], [class*="close"], [class*="modal"] button'); + if (closeBtn) closeBtn.click(); + await new Promise(r => setTimeout(r, 300)); + } + + console.log(`✅ Страница ${page} обработана (${results.length} записей)`); + + const nextBtn = document.querySelector('div._n5hmn94 svg:not([style*="rotate(90deg)"])'); + const nextButtonContainer = nextBtn ? nextBtn.closest('div._n5hmn94') : null; + + if (!nextButtonContainer) { + console.log('✅ Достигнут конец списка'); + break; + } + + nextButtonContainer.click(); + console.log(`➡️ Переход на страницу ${page + 1}`); + await new Promise(r => setTimeout(r, 500)); + + page++; + } + + console.table(results); + + const csv = "data:text/csv;charset=utf-8," + + "Название;Адрес;Телефоны;Ссылка\n" + + results.map(r => `"${r.name}";"${r.address}";"${r.phones}";"${r.link}"`).join("\n"); + + const a = document.createElement('a'); + a.href = encodeURI(csv); + a.download = `автосалоны_только_вторые_${new Date().toISOString().slice(0,10)}.csv`; + a.click(); + + console.log('%c🎉 Готово! Собрано ' + results.length + ' записей (только вторые номера)', 'color:#00ff00;font-size:18px'); +})(); \ No newline at end of file