// Настройки скрипта const SETTINGS = { scrollDelay: 1000, // Задержка между прокрутками (в миллисекундах) scrollStep: 72, // Шаг прокрутки (в пикселях) enableLogs: true, // Включить логирование scrollContainerSelector: '.x1n2onr6.x1n2onr6.xyw6214.x78zum5.x1r8uery.x1iyjqo2.xdt5ytf.x6ikm8r.x1odjw0f.x1hc1fzr.x1tkvqr7', // Селектор контейнера для прокрутки participantSelector: '.x10l6tqk.xh8yej3.x1g42fcv', // Селектор элементов участников nameSelector: '.x1iyjqo2.x6ikm8r.x10wlt62.x1n2onr6.xlyipyv.xuxw1ft.x1rg5ohu._ao3e', // Селектор имени участника numberSelector: 'span._ajzr span._ao3e', // Селектор номера телефона statusSelector: '.x13faqbe._ao3e.selectable-text.copyable-text', // Селектор статуса участника }; // Глобальные переменные let allParticipants = []; // Массив для хранения всех участников let previousParticipants = []; // Массив для хранения участников на предыдущем шаге // Функция для прокрутки списка участников function scrollParticipants() { const scrollContainer = document.querySelector(SETTINGS.scrollContainerSelector); // Контейнер для прокрутки if (scrollContainer) { // Симулируем фокус на контейнере scrollContainer.focus(); // Прокручиваем на заданный шаг scrollContainer.scrollTop += SETTINGS.scrollStep; if (SETTINGS.enableLogs) { console.log(`Прокрутка выполнена: scrollTop = ${scrollContainer.scrollTop}px`); } return scrollContainer.scrollTop; // Возвращаем текущее значение scrollTop } else { console.error('Контейнер для прокрутки не найден'); return 0; } } // Функция для проверки, является ли строка номером телефона function isPhoneNumber(text) { // Простая проверка на наличие цифр и символов, характерных для номеров return /[\d\s\+\-()]{6,}/.test(text); } // Функция для парсинга данных function parseParticipants() { const participants = []; const participantElements = document.querySelectorAll(SETTINGS.participantSelector); // Элементы участников participantElements.forEach(participant => { const nameElement = participant.querySelector(SETTINGS.nameSelector); const numberElement = participant.querySelector(SETTINGS.numberSelector); // Номер телефона const statusElement = participant.querySelector(SETTINGS.statusSelector); let name = nameElement ? nameElement.innerText : 'N/A'; let number = numberElement ? numberElement.innerText : 'N/A'; const status = statusElement ? statusElement.innerText : 'N/A'; // Если в поле "имя" находится номер, переносим его в поле "номер" if (isPhoneNumber(name) && !isPhoneNumber(number)) { number = name; name = 'N/A'; } participants.push({ name, number, status }); }); return participants; } // Функция для удаления дубликатов function removeDuplicates(participants) { const uniqueParticipants = []; const seen = new Set(); participants.forEach(participant => { const participantKey = `${participant.name}-${participant.number}`; // Уникальный ключ if (!seen.has(participantKey)) { seen.add(participantKey); uniqueParticipants.push(participant); } }); return uniqueParticipants; } // Функция для поиска новых контактов function findNewParticipants(currentParticipants, previousParticipants) { const newParticipants = []; const previousKeys = new Set(previousParticipants.map(p => `${p.name}-${p.number}`)); currentParticipants.forEach(participant => { const participantKey = `${participant.name}-${participant.number}`; if (!previousKeys.has(participantKey)) { newParticipants.push(participant); } }); return newParticipants; } // Функция для создания и скачивания CSV-файла function downloadCSV(data) { const csvContent = "data:text/csv;charset=utf-8," + "Имя,Номер,Статус\n" // Заголовки столбцов + data.map(p => `"${p.name}","${p.number}","${p.status}"`).join("\n"); // Данные const encodedUri = encodeURI(csvContent); const link = document.createElement("a"); link.setAttribute("href", encodedUri); link.setAttribute("download", "contacts.csv"); document.body.appendChild(link); link.click(); // Автоматически скачиваем файл document.body.removeChild(link); } // Функция для автоматической прокрутки и сбора данных function collectData() { const scrollContainer = document.querySelector(SETTINGS.scrollContainerSelector); if (!scrollContainer) { console.error('Контейнер для прокрутки не найден'); return; } // Получаем общую высоту контента const totalHeight = parseInt(scrollContainer.scrollHeight, 10); if (SETTINGS.enableLogs) { console.log(`Общая высота контента: ${totalHeight}px`); } // Функция для выполнения прокрутки и сбора данных const scrollAndCollect = () => { const currentScrollTop = scrollParticipants(); // Прокручиваем const currentParticipants = parseParticipants(); // Собираем данные // Находим новые контакты const newParticipants = findNewParticipants(currentParticipants, previousParticipants); if (newParticipants.length > 0 && SETTINGS.enableLogs) { console.log(`Добавлено новых контактов: +${newParticipants.length}`); console.log('Новые контакты:', newParticipants.map(p => `${p.name} (${p.number})`).join(', ')); } // Обновляем предыдущий список участников previousParticipants = currentParticipants; // Добавляем новые данные в общий массив allParticipants.push(...newParticipants); // Удаляем дубликаты allParticipants = removeDuplicates(allParticipants); // Проверяем, достигли ли мы конца списка if (currentScrollTop + scrollContainer.clientHeight >= totalHeight) { if (SETTINGS.enableLogs) { console.log('Достигнут нижний предел. Все данные собраны:'); console.table(allParticipants); // Вывод данных в виде таблицы } // Создаем и скачиваем CSV-файл downloadCSV(allParticipants); } else { // Продолжаем прокрутку через заданную задержку setTimeout(scrollAndCollect, SETTINGS.scrollDelay); } }; // Запускаем процесс scrollAndCollect(); } // Запуск сбора данных collectData();