Лайфхакер
Лайфхакер
Лучшее
Рубрики
Рецепты
Подкасты
Сервисы
Колонки
Лучшее
Рубрики
Рецепты
Подкасты
Сервисы
Колонки
Выгодные покупки
Новости
Здоровье
Спорт и фитнес
Покупки
Технологии
Отношения
Кино
Реклама
МакрадарТехнологии
5 июня 2015

Tweetbot 2.0 для Mac — без минусов не обошлось

Фото автора Александр Мураховский
Александр Мураховский

Tweetbot 2.0 для Mac — без минусов не обошлось

Вчера в Mac App Store появился обновленный Tweetbot версии 2.0. По словам разработчиков, приложение стало совершенно другим. В Tweetbot изменился внешний вид, расположение некоторых элементов, добавились новые возможности и, конечно же, обновилась иконка.

Обновление получилось не таким однозначным, как того ждали. Хотя в Mac App Store у приложения исключительно положительные отзывы, многие сетуют на то, что в новом Tweetbot не хватает привычных функций. К примеру, разработчики убрали вкладку с ретвитами и возможность включить небольшие превью изображений в ленте. Теперь можно либо выключить их совсем, либо использовать большие миниатюры.

Неприятно, что приложение постоянно напоминает о том, что вы отключили геолокацию. В прошлых версиях это происходило лишь единожды. И наконец, Tweetbot для Mac до сих пор не показывает эмбеды твитов, в отличие от версии для iOS. Правда, Тодд Томас — разработчик приложения — говорит, что это исправят в версии 2.1.

timeline

Кратко прошлись по плохому, давайте о хорошем. Теперь Tweetbot выглядит как нативное приложение для Yosemite. Как и в iOS-версии, здесь можно менять внешний вид аватаров.

Окно нового твита теперь не привязано к основной ленте — его можно перемещать отдельно от других вкладок. Работать с панелями так же просто, как и раньше. По правому клику на панель открывается окно, позволяющее отцепить ее для перемещения или удалить.

screen800x500

Невзирая на ряд недостатков, которые, возможно, исправят в следующих версиях, Tweetbot остается лучшим настольным клиентом для Twitter. Для пользователей, уже купивших приложение, обновление будет бесплатным. Для остальных же в течение некоторого времени действует скидка. Сейчас Tweetbot можно купить за 799 рублей вместо 1 190.

Приложение не найдено
Если нашли ошибку, выделите текст и нажмите Ctrl + Enter

Лучшие предложения

10 пар зимней обуви с хорошими скидками на «чёрной пятнице»

10 пар зимней обуви с хорошими скидками на «чёрной пятнице»

постельное белье

21 комплект постельного белья, который преобразит вашу спальню

Roborock Q5 Pro

Надо брать: робот-пылесос Roborock Q5 Pro со скидкой 76%

Гидравлический домкрат с высоким рейтингом отдают со скидкой 35% на AliExpress

Гидравлический домкрат с высоким рейтингом отдают со скидкой 35% на AliExpress

23 нарядных платья, которые можно надеть на новогодний корпоратив

23 нарядных платья, которые можно надеть на новогодний корпоратив

10 рюкзаков для ноутбука, которые не боятся мокрого снега и дождя

10 рюкзаков для ноутбука, которые не боятся мокрого снега и дождя

5 милых мягких игрушек для тех, кто любит мультфильмы Хаяо Миядзаки

5 милых мягких игрушек для тех, кто любит мультфильмы Хаяо Миядзаки

Самый популярный компрессор от Baseus отдают за полцены

Самый популярный компрессор от Baseus отдают за полцены

Это интересно
Коля идёт на смену! Как проходит первый день новичка на складе Ozon 

Коля идёт на смену! Как проходит первый день новичка на складе Ozon 

Рак груди во время беременности: что нужно знать

Рак груди во время беременности: что нужно знать

8 умных гаджетов для дома, которые делают быт проще и уютнее

8 умных гаджетов для дома, которые делают быт проще и уютнее

VK Education запускает кейс-чемпионат для студентов с призовым фондом 1 млн рублей

VK Education запускает кейс-чемпионат для студентов с призовым фондом 1 млн рублей

Комментарии
Сергей Король
12.06.15 19:39
Еще жирный минус этой проги, что теперь она не носит банлист, а только матит. Например сообщения ботов, троллей не удаляются, как в прошлой версии, а остаются висеть в ленте ответов. Разработчики сделали полное барахло, буду откатываться на старую версию.
Что вы могли пропустить
Xiaomi начала обновлять до HyperOS 3 ещё четыре смартфона, включая Redmi 13
Xiaomi начала обновлять до HyperOS 3 ещё четыре смартфона, включая Redmi 13
0
16:44
Android
Новости
Представлен внешний SSD с кнопкой уничтожения файлов без следа — прямо как в шпионских фильмах
Представлен внешний SSD с кнопкой уничтожения файлов без следа — прямо как в шпионских фильмах
0
14:18
Новости
Устройства
Испарительная камера рвётся голыми руками: OnePlus 15 проверили на прочность
Испарительная камера рвётся голыми руками: OnePlus 15 проверили на прочность
0
13:40
Новости
Устройства
Как выбрать хороший увлажнитель воздуха для квартиры и частного дома
Как выбрать хороший увлажнитель воздуха для квартиры и частного дома
0
13:00
Как выбрать
Ликбез
В «Блокноте» на Windows 11 появилась поддержка таблиц
В «Блокноте» на Windows 11 появилась поддержка таблиц
0
11:39
Windows
Новости
Huawei увеличит автономность смартфонов Mate 80 до 14 дней
Huawei увеличит автономность смартфонов Mate 80 до 14 дней
0
Вчера
Новости
Устройства
Бюджетные MacBook, iPhone и iPad выйдут в начале 2026 года
Бюджетные MacBook, iPhone и iPad выйдут в начале 2026 года
0
Вчера
Новости
Устройства
iPhone 11 и ещё три модели Apple: названы самые популярные смартфоны у россиян
iPhone 11 и ещё три модели Apple: названы самые популярные смартфоны у россиян
0
Вчера
Новости
Устройства
На Android вышло приложение, открывающее доступ к главным функциям AirPods
На Android вышло приложение, открывающее доступ к главным функциям AirPods
0
Вчера
Android
Новости
11 удобных приложений для заметок на Android и iOS
11 удобных приложений для заметок на Android и iOS
0
Вчера
Ликбез
Технологии
ИИ-браузер Comet от Perplexity вышел на Android — с голосовым режимом
ИИ-браузер Comet от Perplexity вышел на Android — с голосовым режимом
0
Вчера
Android
Браузеры
AirDrop теперь и на Android: смартфоны Pixel 10 научились отправлять и получать файлы с iPhone
AirDrop теперь и на Android: смартфоны Pixel 10 научились отправлять и получать файлы с iPhone
0
Вчера
Android
Новости
Google представила Nano Banana Pro — улучшенную модель генерации изображений на базе Gemini 3 Pro
Google представила Nano Banana Pro — улучшенную модель генерации изображений на базе Gemini 3 Pro
0
Вчера
Веб-сервисы
Новости
Представлен игровой планшет OneXPlayer Super X с AMOLED‑дисплеем и встроенной подставкой
Представлен игровой планшет OneXPlayer Super X с AMOLED‑дисплеем и встроенной подставкой
0
20 ноября
Новости
Устройства
В браузере Chrome наконец-то появились вертикальные вкладки
В браузере Chrome наконец-то появились вертикальные вкладки
0
20 ноября
Браузеры
Новости

Новые комментарии

Аватар автора комментария
Кирилл Тимонин3 минуты назад

0 / 0

22.11.2025 - новая версия скрипта для автоматического удаления постов со стены ВК, учитывающая все изменения алгоритма удаления постов и интерфейса ВК. У скрипта есть удобное меню для управления процессом. Пред запуском скрипта необходимо войти в режим просмотра сообщений стены с выбором по календарю (двойной клик по слову Сообщения). Далее - выбираете год и дату в календаре, с которой начинать удалять сообщения - например 31 декабря 2023 года. Сообщения будут удаляться в прошлое - весь декабрь, ноябрь, октябрь и так далее. В меню скрипта нужно выбрать год - это служит предохранителем от случайного удаления текущих постов этого года. Скорость удаления постов от 0.1 до 3 секунд. Настраивать в зависимости от скорости вашего интернета и мощности компьютера. Для максимально быстрой работы скрипта необходимо в настройках браузера отключить показ картинок и видео. Скрипт успешно тестировался в браузере Хром на любых скоростях. Удаляет без ошибок. var test = false, count = 0, targetYear = 2024, deletePause = 100; var controlElements = {}; // Объект для хранения элементов управления // Функция создания панели управления function createControlPanel() { var panel = document.createElement('div'); panel.style.cssText = ` position: fixed; top: 20px; right: 20px; z-index: 10000; background: rgba(0,0,0,0.8); color: white; border-radius: 10px; padding: 15px; font-family: Arial, sans-serif; min-width: 200px; backdrop-filter: blur(10px); `; var title = document.createElement('div'); title.innerHTML = '🎯 Управление удалением'; title.style.cssText = 'font-weight: bold; margin-bottom: 10px; font-size: 16px;'; panel.appendChild(title); var stats = document.createElement('div'); stats.id = 'controlStats'; stats.innerHTML = `Год: ${targetYear}Удалено: ${count}Пауза: ${deletePause/1000}сек`; stats.style.cssText = 'margin-bottom: 10px; font-size: 12px; line-height: 1.4;'; panel.appendChild(stats); // Кнопка остановки/продолжения controlElements.stopBtn = document.createElement('button'); controlElements.stopBtn.innerHTML = '🛑 Остановить'; controlElements.stopBtn.style.cssText = ` background: #ff4444; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; font-weight: bold; font-size: 12px; margin-right: 5px; margin-bottom: 5px; width: 100%; `; controlElements.stopBtn.onclick = function() { if (test) { // Останавливаем скрипт test = false; controlElements.stopBtn.innerHTML = '▶️ Продолжить'; controlElements.stopBtn.style.background = '#44aa44'; console.log('⏸️ Скрипт приостановлен пользователем'); } else { // Продолжаем скрипт test = true; controlElements.stopBtn.innerHTML = '🛑 Остановить'; controlElements.stopBtn.style.background = '#ff4444'; console.log('▶️ Скрипт продолжен пользователем'); // Запускаем процесс снова setTimeout(() => { processPostsContinuously(); }, 100); } updateControlPanel(); }; panel.appendChild(controlElements.stopBtn); // Кнопка перезапуска var restartBtn = document.createElement('button'); restartBtn.innerHTML = '🔄 Перезапустить'; restartBtn.style.cssText = ` background: #44aaff; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; font-weight: bold; font-size: 12px; margin-bottom: 5px; width: 100%; `; restartBtn.onclick = function() { test = false; console.log('🔄 Перезапуск скрипта...'); // Сбрасываем кнопку остановки к красному цвету if (controlElements.stopBtn) { controlElements.stopBtn.innerHTML = '🛑 Остановить'; controlElements.stopBtn.style.background = '#ff4444'; } setTimeout(() => { restartWithNewSettings(); }, 500); }; panel.appendChild(restartBtn); // Кнопка быстрых настроек var settingsBtn = document.createElement('button'); settingsBtn.innerHTML = '⚙️ Быстрые настройки'; settingsBtn.style.cssText = ` background: #ffaa00; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; font-weight: bold; font-size: 12px; width: 100%; `; settingsBtn.onclick = function() { quickSettings(); }; panel.appendChild(settingsBtn); document.body.appendChild(panel); return panel; } // Функция сброса кнопки остановки при перезапуске function resetStopButton() { if (controlElements.stopBtn) { controlElements.stopBtn.innerHTML = '🛑 Остановить'; controlElements.stopBtn.style.background = '#ff4444'; } } // Функция обновления панели управления function updateControlPanel() { var stats = document.getElementById('controlStats'); if (stats) { stats.innerHTML = `Год: ${targetYear}Удалено: ${count}Пауза: ${deletePause/1000}секСтатус: ${test ? 'активен' : 'пауза'}`; } } // Функция быстрых настроек function quickSettings() { if (test) { alert('Сначала остановите скрипт для изменения настроек!'); return; } var newPause = parseFloat(prompt('Новая пауза между удалениями (секунды):\n\n0.1-0.3 - Максимальная скорость\n0.5-1.0 - Баланс\n1.5-3.0 - Максимальная надежность', deletePause/1000)); if (!isNaN(newPause) && newPause >= 0.1 && newPause <= 3) { deletePause = newPause * 1000; console.log('⚙️ Пауза изменена: ' + newPause + ' сек.'); updateControlPanel(); } else { alert('Некорректное значение паузы!'); } } // Функция перезапуска с новыми настройками function restartWithNewSettings() { // Сбрасываем счетчик count = 0; // Запрос года для удаления var currentYear = new Date().getFullYear(); var newTargetYear = parseInt(prompt('Введите год, посты за который нужно удалить\n(например: 2024, 2023, 2022)', targetYear)); // Проверка корректности года if (isNaN(newTargetYear) || newTargetYear < 2000 || newTargetYear > currentYear) { alert('Некорректный год! Будет использован предыдущий год: ' + targetYear); } else { targetYear = newTargetYear; } // Настройка паузы между удалениями var pauseInput = parseFloat(prompt('Пауза между удалениями постов (секунды)\n\nРекомендации:\n• 0.1-0.3 - Максимальная скорость (риск ошибок)\n• 0.5-1.0 - Баланс скорости и надежности\n• 1.5-3.0 - Максимальная надежность', deletePause/1000)); // Проверка и ограничение паузы if (isNaN(pauseInput) || pauseInput < 0.1) { pauseInput = 0.1; } else if (pauseInput > 3) { pauseInput = 3; } deletePause = pauseInput * 1000; test = confirm("⚡ НОВЫЕ НАСТРОЙКИ УДАЛЕНИЯ:\n\n• Год: " + targetYear + "\n• Пауза между удалениями: " + pauseInput + " сек." + "\n• Медиа заблокированы: Да\n\nНачать удаление с новыми настройками?"); if (test) { console.log('🔄 ПЕРЕЗАПУСК С НОВЫМИ НАСТРОЙКАМИ'); console.log('🎯 Целевой год: ' + targetYear); console.log('⏱️ Пауза между удалениями: ' + pauseInput + ' сек.'); // Сбрасываем кнопку остановки к красному цвету resetStopButton(); updateControlPanel(); startContinuousDeletion(); } else { updateControlPanel(); } } // Остановка по клавише ESC document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && test) { test = false; if (controlElements.stopBtn) { controlElements.stopBtn.innerHTML = '▶️ Продолжить'; controlElements.stopBtn.style.background = '#44aa44'; } console.log('⏸️ Скрипт приостановлен по клавише ESC'); updateControlPanel(); } }); function disableMediaLoading() { document.querySelectorAll('img, video, iframe').forEach(el => { el.style.display = 'none'; }); const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { if (node.tagName === 'IMG' || node.tagName === 'VIDEO') { node.style.display = 'none'; } node.querySelectorAll?.('img, video').forEach(media => { media.style.display = 'none'; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); console.log('⚡ Медиа заблокированы'); } function itit() { disableMediaLoading(); // Запрос года для удаления var currentYear = new Date().getFullYear(); targetYear = parseInt(prompt('Введите год, посты за который нужно удалить\n(например: 2024, 2023, 2022)', currentYear)); // Проверка корректности года if (isNaN(targetYear) || targetYear < 2000 || targetYear > currentYear) { alert('Некорректный год! Будет использован текущий год: ' + currentYear); targetYear = currentYear; } // Точная настройка паузы между удалениями var pauseInput = parseFloat(prompt('Пауза между удалениями постов (секунды)\n\nРекомендации:\n• 0.1-0.3 - Максимальная скорость (риск ошибок)\n• 0.5-1.0 - Баланс скорости и надежности\n• 1.5-3.0 - Максимальная надежность', '0.5')); // Проверка и ограничение паузы if (isNaN(pauseInput) || pauseInput < 0.1) { pauseInput = 0.1; } else if (pauseInput > 3) { pauseInput = 3; } deletePause = pauseInput * 1000; test = confirm("⚡ НАСТРОЙКИ УДАЛЕНИЯ:\n\n• Год: " + targetYear + "\n• Пауза между удалениями: " + pauseInput + " сек." + "\n• Медиа заблокированы: Да\n\nНачать удаление?"); if (test) { console.log('⚡ ЗАПУСК С НАСТРОЕННЫМИ ПАРАМЕТРАМИ'); console.log('🎯 Целевой год: ' + targetYear); console.log('⏱️ Пауза между удалениями: ' + pauseInput + ' сек.'); createControlPanel(); startContinuousDeletion(); } } function startContinuousDeletion() { console.log('🔄 Начинаем непрерывное удаление...'); updateControlPanel(); processPostsContinuously(); } function processPostsContinuously() { if (!test) { console.log('⏸️ Скрипт на паузе'); return; } console.log(`\n=== ПОИСК ПОСТОВ ЗА ${targetYear} ГОД ===`); var posts = document.querySelectorAll('div._post'); console.log(`📊 На странице: ${posts.length} постов`); if (posts.length === 0) { console.log('📭 Постов не найдено, пытаемся загрузить...'); loadMorePosts().then((success) => { setTimeout(processPostsContinuously, 1000); }); return; } var postsToDelete = []; for (var i = 0; i < posts.length; i++) { var post = posts[i]; var postDate = extractDateFromPost(post); if (postDate && postDate.getFullYear() === targetYear) { postsToDelete.push({ element: post, date: postDate, index: i }); } } console.log(`🎯 Найдено постов за ${targetYear} год: ${postsToDelete.length}`); // Показываем информацию о найденных постах if (postsToDelete.length > 0) { console.log('📅 Даты найденных постов:'); postsToDelete.forEach(post => { console.log(' - ' + post.date.toLocaleDateString()); }); } if (postsToDelete.length > 0) { console.log('🔥 Начинаем удаление...'); deletePostsSequentially(postsToDelete, 0, () => { console.log(`✅ Удаление завершено. Всего удалено: ${count}`); updateControlPanel(); setTimeout(processPostsContinuously, 500); }); } else { console.log('📭 Постов за ' + targetYear + ' год не найдено, загружаем следующую страницу...'); loadMorePosts().then((success) => { setTimeout(processPostsContinuously, 1000); }); } } function loadMorePosts() { return new Promise((resolve) => { console.log('🔍 Поиск пагинации для загрузки следующей страницы...'); // Ищем кнопку "1" в пагинации (первая страница) var paginationButton = findPaginationButton(); if (paginationButton) { console.log('✅ Найдена кнопка пагинации, нажимаем...'); paginationButton.click(); console.log('⏳ Ждем загрузки новой страницы (3 секунды)...'); setTimeout(() => { // Прокручиваем немного для стимуляции загрузки window.scrollTo(0, 100); setTimeout(() => { console.log('✅ Новая страница загружена'); resolve(true); }, 1000); }, 3000); } else { console.log('❌ Кнопка пагинации не найдена, пробуем альтернативные методы...'); // Альтернативные методы загрузки var alternativeButtons = [ document.querySelector('#fw_load_more.pg_more_link'), document.querySelector('#wall_more_link'), document.querySelector('.wall_more_link'), document.querySelector('.pg_more_link'), findElementByText('к предыдущим постам') ]; var foundButton = alternativeButtons.find(btn => btn !== null); if (foundButton) { console.log('✅ Найдена альтернативная кнопка, нажимаем...'); foundButton.click(); console.log('⏳ Ждем загрузки постов (4 секунды)...'); setTimeout(() => { console.log('✅ Посты загружены через альтернативную кнопку'); resolve(true); }, 4000); } else { console.log('❌ Ни одна кнопка не найдена, используем прокрутку...'); var oldCount = document.querySelectorAll('div._post').length; window.scrollTo(0, 0); setTimeout(() => { window.scrollTo(0, document.body.scrollHeight); console.log('⏳ Ждем загрузки постов после прокрутки (5 секунд)...'); setTimeout(() => { var newCount = document.querySelectorAll('div._post').length; if (newCount > oldCount) { console.log(`✅ Загружено ${newCount - oldCount} постов через прокрутку`); resolve(true); } else { console.log('❌ Не удалось загрузить новые посты через прокрутку'); resolve(false); } }, 5000); }, 1000); } } }); } // Функция поиска кнопки пагинации "1" function findPaginationButton() { // Ищем все элементы пагинации var paginationContainers = [ document.querySelector('.pagination_page'), document.querySelector('.pagination_pages'), document.querySelector('.page_list'), document.querySelector('.pagination_list'), document.querySelector('[data-module="uiPagination"]'), document.querySelector('.ui_pagination') ]; // Ищем в контейнерах пагинации for (var container of paginationContainers) { if (container) { // Ищем кнопку с цифрой "1" var button = container.querySelector('a[href*="offset=0"], a[href*="page=1"], .pagination_page:first-child, .page:first-child'); if (button) return button; // Ищем по тексту "1" var buttons = container.querySelectorAll('a, span, .page, .pagination_page'); for (var btn of buttons) { if (btn.textContent && btn.textContent.trim() === '1') { return btn; } } } } // Ищем по всему документу ссылки с offset=0 var offsetLinks = document.querySelectorAll('a[href*="offset=0"]'); for (var link of offsetLinks) { if (link.textContent && link.textContent.trim() === '1') { return link; } } // Ищем любую кнопку с цифрой "1" в вероятных контейнерах пагинации var allButtons = document.querySelectorAll('a, span, .page, .pagination_page, .ui_pagination a'); for (var btn of allButtons) { if (btn.textContent && btn.textContent.trim() === '1' && (btn.href && btn.href.includes('wall') || btn.parentElement && btn.parentElement.className.includes('pagination'))) { return btn; } } return null; } function findElementByText(text) { var elements = document.querySelectorAll('a, span, div, button'); for (var i = 0; i < elements.length; i++) { var element = elements[i]; var elementText = element.textContent || element.innerText; if (elementText && elementText.trim() === text) { return element; } } return null; } function extractDateFromPost(postElement) { try { var dateElement = postElement.querySelector('.PostDateBlock__root'); if (dateElement) { var dateText = dateElement.textContent || dateElement.innerText; if (dateText) { return parseDateFromText(dateText); } } var likeWrap = postElement.querySelector('.like_wrap'); if (likeWrap) { var likeText = likeWrap.textContent || likeWrap.innerText; if (likeText) { return parseDateFromText(likeText); } } } catch (e) { return null; } return null; } function parseDateFromText(text) { if (!text) return null; text = text.replace(/\s+/g, ' ').trim(); var datePatterns = [ /(\d{1,2})\s+(янв|фев|мар|апр|май|июн|июл|авг|сен|окт|ноя|дек)\s+(\d{4})/i, /(\d{1,2})\s+(января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря)\s+(\d{4})/i ]; for (var pattern of datePatterns) { var match = text.match(pattern); if (match) { var day = parseInt(match[1]); var monthStr = match[2].toLowerCase(); var year = parseInt(match[3]); var months = { 'янв': 0, 'января': 0, 'фев': 1, 'февраля': 1, 'мар': 2, 'марта': 2, 'апр': 3, 'апреля': 3, 'май': 4, 'мая': 4, 'июн': 5, 'июня': 5, 'июл': 6, 'июля': 6, 'авг': 7, 'августа': 7, 'сен': 8, 'сентября': 8, 'окт': 9, 'октября': 9, 'ноя': 10, 'ноября': 10, 'дек': 11, 'декабря': 11 }; var month = months[monthStr]; if (month !== undefined) { return new Date(year, month, day); } } } return null; } function deletePostsSequentially(posts, currentIndex, callback) { if (currentIndex >= posts.length || test === false) { callback(); return; } var post = posts[currentIndex]; deleteSinglePost(post.element).then(() => { count++; console.log(`✅ Удален пост ${currentIndex + 1}/${posts.length}. Всего: ${count}`); // Используем настроенную пользователем паузу console.log(`⏱️ Ждем ${deletePause/1000} сек. перед следующим удалением...`); setTimeout(() => { deletePostsSequentially(posts, currentIndex + 1, callback); }, deletePause); }).catch((error) => { console.error('❌ Ошибка:', error); // При ошибке используем стандартную паузу 100мс setTimeout(() => { deletePostsSequentially(posts, currentIndex + 1, callback); }, 100); }); } function deleteSinglePost(postElement) { return new Promise((resolve, reject) => { try { var menuButton = postElement.querySelector('[data-testid="post_context_menu_toggle"]'); if (!menuButton) { reject('Кнопка меню не найдена'); return; } menuButton.click(); setTimeout(() => { var deleteButton = document.querySelector('[data-testid="post_context_menu_item_delete"]'); if (!deleteButton) { reject('Кнопка удаления не найдена'); return; } deleteButton.click(); setTimeout(() => { var confirmButton = document.querySelector('.vkuiButton--mode-primary'); if (confirmButton) { confirmButton.click(); } postElement.remove(); resolve(); }, 200); }, 200); } catch (error) { reject(error); } }); } function showFinalStats() { var message = `🎉 УДАЛЕНИЕ ЗАВЕРШЕНО!\n\n• Год: ${targetYear}\n• Удалено постов: ${count}\n• Пауза между удалениями: ${deletePause/1000} сек.`; alert(message); console.log(message); updateControlPanel(); } // Запускаем скрипт itit(); // КОМАНДЫ ДЛЯ УПРАВЛЕНИЯ: // - test = false // Остановить скрипт // - restartWithNewSettings() // Перезапуск с новыми настройками // - quickSettings() // Быстрые настройки паузы // - resetStopButton() // Сброс кнопки остановки
Как быстро удалить записи со стены «ВКонтакте»
Аватар автора комментария
Кирилл Тимонин3 минуты назад

0 / 0

22.11.2025 - новая версия скрипта для автоматического удаления постов со стены ВК, учитывающая все изменения алгоритма удаления постов и интерфейса ВК. У скрипта есть удобное меню для управления процессом. Пред запуском скрипта необходимо войти в режим просмотра сообщений стены с выбором по календарю (двойной клик по слову Сообщения). Далее - выбираете год и дату в календаре, с которой начинать удалять сообщения - например 31 декабря 2023 года. Сообщения будут удаляться в прошлое - весь декабрь, ноябрь, октябрь и так далее. В меню скрипта нужно выбрать год - это служит предохранителем от случайного удаления текущих постов этого года. Скорость удаления постов от 0.1 до 3 секунд. Настраивать в зависимости от скорости вашего интернета и мощности компьютера. Для максимально быстрой работы скрипта необходимо в настройках браузера отключить показ картинок и видео. Скрипт успешно тестировался в браузере Хром на любых скоростях. Удаляет без ошибок. var test = false, count = 0, targetYear = 2024, deletePause = 100; var controlElements = {}; // Объект для хранения элементов управления // Функция создания панели управления function createControlPanel() { var panel = document.createElement('div'); panel.style.cssText = ` position: fixed; top: 20px; right: 20px; z-index: 10000; background: rgba(0,0,0,0.8); color: white; border-radius: 10px; padding: 15px; font-family: Arial, sans-serif; min-width: 200px; backdrop-filter: blur(10px); `; var title = document.createElement('div'); title.innerHTML = '🎯 Управление удалением'; title.style.cssText = 'font-weight: bold; margin-bottom: 10px; font-size: 16px;'; panel.appendChild(title); var stats = document.createElement('div'); stats.id = 'controlStats'; stats.innerHTML = `Год: ${targetYear}Удалено: ${count}Пауза: ${deletePause/1000}сек`; stats.style.cssText = 'margin-bottom: 10px; font-size: 12px; line-height: 1.4;'; panel.appendChild(stats); // Кнопка остановки/продолжения controlElements.stopBtn = document.createElement('button'); controlElements.stopBtn.innerHTML = '🛑 Остановить'; controlElements.stopBtn.style.cssText = ` background: #ff4444; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; font-weight: bold; font-size: 12px; margin-right: 5px; margin-bottom: 5px; width: 100%; `; controlElements.stopBtn.onclick = function() { if (test) { // Останавливаем скрипт test = false; controlElements.stopBtn.innerHTML = '▶️ Продолжить'; controlElements.stopBtn.style.background = '#44aa44'; console.log('⏸️ Скрипт приостановлен пользователем'); } else { // Продолжаем скрипт test = true; controlElements.stopBtn.innerHTML = '🛑 Остановить'; controlElements.stopBtn.style.background = '#ff4444'; console.log('▶️ Скрипт продолжен пользователем'); // Запускаем процесс снова setTimeout(() => { processPostsContinuously(); }, 100); } updateControlPanel(); }; panel.appendChild(controlElements.stopBtn); // Кнопка перезапуска var restartBtn = document.createElement('button'); restartBtn.innerHTML = '🔄 Перезапустить'; restartBtn.style.cssText = ` background: #44aaff; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; font-weight: bold; font-size: 12px; margin-bottom: 5px; width: 100%; `; restartBtn.onclick = function() { test = false; console.log('🔄 Перезапуск скрипта...'); // Сбрасываем кнопку остановки к красному цвету if (controlElements.stopBtn) { controlElements.stopBtn.innerHTML = '🛑 Остановить'; controlElements.stopBtn.style.background = '#ff4444'; } setTimeout(() => { restartWithNewSettings(); }, 500); }; panel.appendChild(restartBtn); // Кнопка быстрых настроек var settingsBtn = document.createElement('button'); settingsBtn.innerHTML = '⚙️ Быстрые настройки'; settingsBtn.style.cssText = ` background: #ffaa00; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; font-weight: bold; font-size: 12px; width: 100%; `; settingsBtn.onclick = function() { quickSettings(); }; panel.appendChild(settingsBtn); document.body.appendChild(panel); return panel; } // Функция сброса кнопки остановки при перезапуске function resetStopButton() { if (controlElements.stopBtn) { controlElements.stopBtn.innerHTML = '🛑 Остановить'; controlElements.stopBtn.style.background = '#ff4444'; } } // Функция обновления панели управления function updateControlPanel() { var stats = document.getElementById('controlStats'); if (stats) { stats.innerHTML = `Год: ${targetYear}Удалено: ${count}Пауза: ${deletePause/1000}секСтатус: ${test ? 'активен' : 'пауза'}`; } } // Функция быстрых настроек function quickSettings() { if (test) { alert('Сначала остановите скрипт для изменения настроек!'); return; } var newPause = parseFloat(prompt('Новая пауза между удалениями (секунды):\n\n0.1-0.3 - Максимальная скорость\n0.5-1.0 - Баланс\n1.5-3.0 - Максимальная надежность', deletePause/1000)); if (!isNaN(newPause) && newPause >= 0.1 && newPause <= 3) { deletePause = newPause * 1000; console.log('⚙️ Пауза изменена: ' + newPause + ' сек.'); updateControlPanel(); } else { alert('Некорректное значение паузы!'); } } // Функция перезапуска с новыми настройками function restartWithNewSettings() { // Сбрасываем счетчик count = 0; // Запрос года для удаления var currentYear = new Date().getFullYear(); var newTargetYear = parseInt(prompt('Введите год, посты за который нужно удалить\n(например: 2024, 2023, 2022)', targetYear)); // Проверка корректности года if (isNaN(newTargetYear) || newTargetYear < 2000 || newTargetYear > currentYear) { alert('Некорректный год! Будет использован предыдущий год: ' + targetYear); } else { targetYear = newTargetYear; } // Настройка паузы между удалениями var pauseInput = parseFloat(prompt('Пауза между удалениями постов (секунды)\n\nРекомендации:\n• 0.1-0.3 - Максимальная скорость (риск ошибок)\n• 0.5-1.0 - Баланс скорости и надежности\n• 1.5-3.0 - Максимальная надежность', deletePause/1000)); // Проверка и ограничение паузы if (isNaN(pauseInput) || pauseInput < 0.1) { pauseInput = 0.1; } else if (pauseInput > 3) { pauseInput = 3; } deletePause = pauseInput * 1000; test = confirm("⚡ НОВЫЕ НАСТРОЙКИ УДАЛЕНИЯ:\n\n• Год: " + targetYear + "\n• Пауза между удалениями: " + pauseInput + " сек." + "\n• Медиа заблокированы: Да\n\nНачать удаление с новыми настройками?"); if (test) { console.log('🔄 ПЕРЕЗАПУСК С НОВЫМИ НАСТРОЙКАМИ'); console.log('🎯 Целевой год: ' + targetYear); console.log('⏱️ Пауза между удалениями: ' + pauseInput + ' сек.'); // Сбрасываем кнопку остановки к красному цвету resetStopButton(); updateControlPanel(); startContinuousDeletion(); } else { updateControlPanel(); } } // Остановка по клавише ESC document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && test) { test = false; if (controlElements.stopBtn) { controlElements.stopBtn.innerHTML = '▶️ Продолжить'; controlElements.stopBtn.style.background = '#44aa44'; } console.log('⏸️ Скрипт приостановлен по клавише ESC'); updateControlPanel(); } }); function disableMediaLoading() { document.querySelectorAll('img, video, iframe').forEach(el => { el.style.display = 'none'; }); const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { if (node.tagName === 'IMG' || node.tagName === 'VIDEO') { node.style.display = 'none'; } node.querySelectorAll?.('img, video').forEach(media => { media.style.display = 'none'; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); console.log('⚡ Медиа заблокированы'); } function itit() { disableMediaLoading(); // Запрос года для удаления var currentYear = new Date().getFullYear(); targetYear = parseInt(prompt('Введите год, посты за который нужно удалить\n(например: 2024, 2023, 2022)', currentYear)); // Проверка корректности года if (isNaN(targetYear) || targetYear < 2000 || targetYear > currentYear) { alert('Некорректный год! Будет использован текущий год: ' + currentYear); targetYear = currentYear; } // Точная настройка паузы между удалениями var pauseInput = parseFloat(prompt('Пауза между удалениями постов (секунды)\n\nРекомендации:\n• 0.1-0.3 - Максимальная скорость (риск ошибок)\n• 0.5-1.0 - Баланс скорости и надежности\n• 1.5-3.0 - Максимальная надежность', '0.5')); // Проверка и ограничение паузы if (isNaN(pauseInput) || pauseInput < 0.1) { pauseInput = 0.1; } else if (pauseInput > 3) { pauseInput = 3; } deletePause = pauseInput * 1000; test = confirm("⚡ НАСТРОЙКИ УДАЛЕНИЯ:\n\n• Год: " + targetYear + "\n• Пауза между удалениями: " + pauseInput + " сек." + "\n• Медиа заблокированы: Да\n\nНачать удаление?"); if (test) { console.log('⚡ ЗАПУСК С НАСТРОЕННЫМИ ПАРАМЕТРАМИ'); console.log('🎯 Целевой год: ' + targetYear); console.log('⏱️ Пауза между удалениями: ' + pauseInput + ' сек.'); createControlPanel(); startContinuousDeletion(); } } function startContinuousDeletion() { console.log('🔄 Начинаем непрерывное удаление...'); updateControlPanel(); processPostsContinuously(); } function processPostsContinuously() { if (!test) { console.log('⏸️ Скрипт на паузе'); return; } console.log(`\n=== ПОИСК ПОСТОВ ЗА ${targetYear} ГОД ===`); var posts = document.querySelectorAll('div._post'); console.log(`📊 На странице: ${posts.length} постов`); if (posts.length === 0) { console.log('📭 Постов не найдено, пытаемся загрузить...'); loadMorePosts().then((success) => { setTimeout(processPostsContinuously, 1000); }); return; } var postsToDelete = []; for (var i = 0; i < posts.length; i++) { var post = posts[i]; var postDate = extractDateFromPost(post); if (postDate && postDate.getFullYear() === targetYear) { postsToDelete.push({ element: post, date: postDate, index: i }); } } console.log(`🎯 Найдено постов за ${targetYear} год: ${postsToDelete.length}`); // Показываем информацию о найденных постах if (postsToDelete.length > 0) { console.log('📅 Даты найденных постов:'); postsToDelete.forEach(post => { console.log(' - ' + post.date.toLocaleDateString()); }); } if (postsToDelete.length > 0) { console.log('🔥 Начинаем удаление...'); deletePostsSequentially(postsToDelete, 0, () => { console.log(`✅ Удаление завершено. Всего удалено: ${count}`); updateControlPanel(); setTimeout(processPostsContinuously, 500); }); } else { console.log('📭 Постов за ' + targetYear + ' год не найдено, загружаем следующую страницу...'); loadMorePosts().then((success) => { setTimeout(processPostsContinuously, 1000); }); } } function loadMorePosts() { return new Promise((resolve) => { console.log('🔍 Поиск пагинации для загрузки следующей страницы...'); // Ищем кнопку "1" в пагинации (первая страница) var paginationButton = findPaginationButton(); if (paginationButton) { console.log('✅ Найдена кнопка пагинации, нажимаем...'); paginationButton.click(); console.log('⏳ Ждем загрузки новой страницы (3 секунды)...'); setTimeout(() => { // Прокручиваем немного для стимуляции загрузки window.scrollTo(0, 100); setTimeout(() => { console.log('✅ Новая страница загружена'); resolve(true); }, 1000); }, 3000); } else { console.log('❌ Кнопка пагинации не найдена, пробуем альтернативные методы...'); // Альтернативные методы загрузки var alternativeButtons = [ document.querySelector('#fw_load_more.pg_more_link'), document.querySelector('#wall_more_link'), document.querySelector('.wall_more_link'), document.querySelector('.pg_more_link'), findElementByText('к предыдущим постам') ]; var foundButton = alternativeButtons.find(btn => btn !== null); if (foundButton) { console.log('✅ Найдена альтернативная кнопка, нажимаем...'); foundButton.click(); console.log('⏳ Ждем загрузки постов (4 секунды)...'); setTimeout(() => { console.log('✅ Посты загружены через альтернативную кнопку'); resolve(true); }, 4000); } else { console.log('❌ Ни одна кнопка не найдена, используем прокрутку...'); var oldCount = document.querySelectorAll('div._post').length; window.scrollTo(0, 0); setTimeout(() => { window.scrollTo(0, document.body.scrollHeight); console.log('⏳ Ждем загрузки постов после прокрутки (5 секунд)...'); setTimeout(() => { var newCount = document.querySelectorAll('div._post').length; if (newCount > oldCount) { console.log(`✅ Загружено ${newCount - oldCount} постов через прокрутку`); resolve(true); } else { console.log('❌ Не удалось загрузить новые посты через прокрутку'); resolve(false); } }, 5000); }, 1000); } } }); } // Функция поиска кнопки пагинации "1" function findPaginationButton() { // Ищем все элементы пагинации var paginationContainers = [ document.querySelector('.pagination_page'), document.querySelector('.pagination_pages'), document.querySelector('.page_list'), document.querySelector('.pagination_list'), document.querySelector('[data-module="uiPagination"]'), document.querySelector('.ui_pagination') ]; // Ищем в контейнерах пагинации for (var container of paginationContainers) { if (container) { // Ищем кнопку с цифрой "1" var button = container.querySelector('a[href*="offset=0"], a[href*="page=1"], .pagination_page:first-child, .page:first-child'); if (button) return button; // Ищем по тексту "1" var buttons = container.querySelectorAll('a, span, .page, .pagination_page'); for (var btn of buttons) { if (btn.textContent && btn.textContent.trim() === '1') { return btn; } } } } // Ищем по всему документу ссылки с offset=0 var offsetLinks = document.querySelectorAll('a[href*="offset=0"]'); for (var link of offsetLinks) { if (link.textContent && link.textContent.trim() === '1') { return link; } } // Ищем любую кнопку с цифрой "1" в вероятных контейнерах пагинации var allButtons = document.querySelectorAll('a, span, .page, .pagination_page, .ui_pagination a'); for (var btn of allButtons) { if (btn.textContent && btn.textContent.trim() === '1' && (btn.href && btn.href.includes('wall') || btn.parentElement && btn.parentElement.className.includes('pagination'))) { return btn; } } return null; } function findElementByText(text) { var elements = document.querySelectorAll('a, span, div, button'); for (var i = 0; i < elements.length; i++) { var element = elements[i]; var elementText = element.textContent || element.innerText; if (elementText && elementText.trim() === text) { return element; } } return null; } function extractDateFromPost(postElement) { try { var dateElement = postElement.querySelector('.PostDateBlock__root'); if (dateElement) { var dateText = dateElement.textContent || dateElement.innerText; if (dateText) { return parseDateFromText(dateText); } } var likeWrap = postElement.querySelector('.like_wrap'); if (likeWrap) { var likeText = likeWrap.textContent || likeWrap.innerText; if (likeText) { return parseDateFromText(likeText); } } } catch (e) { return null; } return null; } function parseDateFromText(text) { if (!text) return null; text = text.replace(/\s+/g, ' ').trim(); var datePatterns = [ /(\d{1,2})\s+(янв|фев|мар|апр|май|июн|июл|авг|сен|окт|ноя|дек)\s+(\d{4})/i, /(\d{1,2})\s+(января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря)\s+(\d{4})/i ]; for (var pattern of datePatterns) { var match = text.match(pattern); if (match) { var day = parseInt(match[1]); var monthStr = match[2].toLowerCase(); var year = parseInt(match[3]); var months = { 'янв': 0, 'января': 0, 'фев': 1, 'февраля': 1, 'мар': 2, 'марта': 2, 'апр': 3, 'апреля': 3, 'май': 4, 'мая': 4, 'июн': 5, 'июня': 5, 'июл': 6, 'июля': 6, 'авг': 7, 'августа': 7, 'сен': 8, 'сентября': 8, 'окт': 9, 'октября': 9, 'ноя': 10, 'ноября': 10, 'дек': 11, 'декабря': 11 }; var month = months[monthStr]; if (month !== undefined) { return new Date(year, month, day); } } } return null; } function deletePostsSequentially(posts, currentIndex, callback) { if (currentIndex >= posts.length || test === false) { callback(); return; } var post = posts[currentIndex]; deleteSinglePost(post.element).then(() => { count++; console.log(`✅ Удален пост ${currentIndex + 1}/${posts.length}. Всего: ${count}`); // Используем настроенную пользователем паузу console.log(`⏱️ Ждем ${deletePause/1000} сек. перед следующим удалением...`); setTimeout(() => { deletePostsSequentially(posts, currentIndex + 1, callback); }, deletePause); }).catch((error) => { console.error('❌ Ошибка:', error); // При ошибке используем стандартную паузу 100мс setTimeout(() => { deletePostsSequentially(posts, currentIndex + 1, callback); }, 100); }); } function deleteSinglePost(postElement) { return new Promise((resolve, reject) => { try { var menuButton = postElement.querySelector('[data-testid="post_context_menu_toggle"]'); if (!menuButton) { reject('Кнопка меню не найдена'); return; } menuButton.click(); setTimeout(() => { var deleteButton = document.querySelector('[data-testid="post_context_menu_item_delete"]'); if (!deleteButton) { reject('Кнопка удаления не найдена'); return; } deleteButton.click(); setTimeout(() => { var confirmButton = document.querySelector('.vkuiButton--mode-primary'); if (confirmButton) { confirmButton.click(); } postElement.remove(); resolve(); }, 200); }, 200); } catch (error) { reject(error); } }); } function showFinalStats() { var message = `🎉 УДАЛЕНИЕ ЗАВЕРШЕНО!\n\n• Год: ${targetYear}\n• Удалено постов: ${count}\n• Пауза между удалениями: ${deletePause/1000} сек.`; alert(message); console.log(message); updateControlPanel(); } // Запускаем скрипт itit(); // КОМАНДЫ ДЛЯ УПРАВЛЕНИЯ: // - test = false // Остановить скрипт // - restartWithNewSettings() // Перезапуск с новыми настройками // - quickSettings() // Быстрые настройки паузы // - resetStopButton() // Сброс кнопки остановки
Как быстро удалить записи со стены «ВКонтакте»
Аватар автора комментария
David Simonyan2 часа назад

0 / 0

Пишете туманно и путанно. Можно расшифровку?
Падение Икара: астрофотограф запечатлел парашютиста, «подлетевшего» прямо к Солнцу
Аватар автора комментария
David Simonyan2 часа назад

0 / 0

Это лечится. Попробуй.
Падение Икара: астрофотограф запечатлел парашютиста, «подлетевшего» прямо к Солнцу
Задача — дойти до школы самому: как подготовить ребёнка и убедиться, что всё будет в порядке&nbsp;

Задача — дойти до школы самому: как подготовить ребёнка и убедиться, что всё будет в порядке  

Лайфхакер
Информация
О проектеРубрикиРекламаРедакцияВакансииДля начинающих авторовО компании
Подписка
TelegramВКонтактеTwitterViberYouTubeИнициалRSS
Правила
Пользовательское соглашениеПолитика обработки персональных данныхПравила применения рекомендательных технологийПравила сообществаСогласие на обработку персональных данныхСогласие для рекламных рассылокСогласие для информационной программы
18+Копирование материалов запрещено.
Издание может получать комиссию от покупки товаров, представленных в публикациях