Задать вопрос
  • В чем разница между selenium, playwright и puppeteer?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    - В 15 годах писал похожий парсер, используя node, fetch и axios, но сейчас часть сайтов возвращает html без таблиц с ценами, почему?

    - Для чего нужны selenium, playwright и puppeteer, если я могу через fetch и axios все получить?

    Скорее всего проблема в динамическом формировании этих данных на странице. Тут сразу 2 правильных ответа, можете и не можете единовременно:
    - Можете - в инструментах разработчика браузера смотрите, с какого адреса приходят данные и затем дергайте данные напрямую, минуя сам сайт, в таком случае можно продолжать использовать fetch.
    - Не можете - если вариант выше сложен, то вам нужен инструмент, который сможет выполнять js на странице. fetch/axios возвращают первый ответ сервера, т.е. js на тот момент еще не выполнился на странице, соответственно данные не были подгружены. Вопрос рендера js на странице решают инструменты по типу selenium, playwright и puppeteer.
    - Если все же использовать selenium, playwright и puppeteer, что из них лучше на данный момент?

    Вначале нужно определить, что понимается под "лучше":
    - Можно использовать критерий современности, тогда puppeteer отпадает (playwright написала команда puppeteer).
    - Можно использовать критерий производительности, тогда selenium проигрывает playwright сразу по 2 пунктам, по прожорливости и отклику на действия.
    - Можно использовать критерий обнаружения анти-бот системами, тогда selenium (с учетом undetected_chromedriver) проигрывает playwright тем, что имеет явную дополнительную задержку в ~100-300мс при выполнении CDP команд, что прям заметно. Playwright такой задержки либо не имеет вообще, либо она в рамках погрешности.
    Можно ли их с nodejs использовать?

    Selenium написан на java, но так же имеется возможность использования его с nodejs. Playwright вообще написан на ts, все примеры документации и сопутствующие библиотеки с большей вероятность будут писаться под ts по умолчанию.
    - Часто вижу о упоминание CDP в контексте парсинга, это зачем и для чего нужно?

    CDP (Chrome DevTools Protocol) грубо говоря - это некие "низкоуровневые" команды для "chromium based" браузеров, который позволяют этим браузером управлять. В playwright так реализованы большинство "высокоуровневых" команд, например: при использовании playwright мы пишем await locator.getAttribute(name), а playwright использует аналогичную команду из CDP DOM.getAttributes или DOM.describeNode.
    - Что использовать для отправки сообщений в телегу?

    Если речь идет об nodejs, то Telegraf.
    Ответ написан
    1 комментарий
  • NODE.JS – парсинг контента. При скачивании изображений получаю битые файлы. Как поправить?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    const https = require('https');
    const fs = require('fs');
    const path = require('path');
    const { URL } = require('url');
    
    async function downloadFile(url, outputPath) {
        // Парсим URL для получения компонентов
        const parsedUrl = new URL(url);
        
        // Если путь для сохранения не указан, используем имя файла из URL
        if (!outputPath) {
            outputPath = path.basename(parsedUrl.pathname);
        }
    
        return new Promise((resolve, reject) => {
            const file = fs.createWriteStream(outputPath);
            
            https.get(url, (response) => {
                // Проверяем статус код ответа
                if (response.statusCode !== 200) {
                    reject(new Error(`Ошибка загрузки: ${response.statusCode}`));
                    return;
                }
    
                // Получаем общий размер файла для прогресса
                const totalSize = parseInt(response.headers['content-length'], 10);
                let downloadedSize = 0;
                
                response.pipe(file);
    
                // Опционально: отслеживание прогресса загрузки
                response.on('data', (chunk) => {
                    downloadedSize += chunk.length;
                    if (totalSize) {
                        const percent = (downloadedSize / totalSize * 100).toFixed(2);
                        console.log(`Загружено: ${percent}%`);
                    }
                });
    
                file.on('finish', () => {
                    file.close();
                    resolve({ path: outputPath, size: downloadedSize });
                });
            }).on('error', (err) => {
                fs.unlink(outputPath, () => reject(err));
            });
    
            file.on('error', (err) => {
                fs.unlink(outputPath, () => reject(err));
            });
        });
    }
    
    // Пример использования
    downloadFile('https://example.com/file.zip', './downloaded-file.zip')
        .then((result) => console.log(`Файл сохранен: ${result.path} (${result.size} байт)`))
        .catch((err) => console.error('Ошибка загрузки:', err));
    Ответ написан
    1 комментарий
  • Как найти радиореле (НЕ выключатель с пультом)?

    @Refguser
    Решения для бизнеса: корп.сайты, ИМ, боты и пр.
    Первое что приходит в голову - беспроводной выключатель на батарейке + простая релюха вместо клавиши.
    Но учитывай нагрузку/ток в точке Б.
    Ответ написан
    Комментировать
  • 1С EDT: можно ли в качестве удаленного репозитория использовать расшаренную по локальной сети папку?

    1. Не надо использовать расшаренную папку в качестве репозитория
    2. Не обязательно использовать apache для работы с git.
    3. У git в принципе нет понятия "сервер", так как это распределённая система контроля версий.
    В качестве origin может выступать любой сервер на linux, к которому можно подключиться по ssh.
    Но самостоятельно управлять таким "сервером" будет не удобно, так как нужно будет руками создавать репозитории в нём и руками же добавлять публичные ключи.

    Попробуйте Forgejo - это форк gitea, он жрёт очень мало ресурсов, его легко развернуть по инструкции, при этом там есть в принципе всё необходимое (пользователи, организации, возможность создавать репозитории, искать по ним, MR-ы, Issues, даже есть подобие Github Actions)
    Ответ написан
    6 комментариев
  • Чем отличается XEN от OpenVZ?

    @rPman
    Вот популярные системы в порядке понижения функционала:
    Xen — на порядок сложнее и функциональнее, имеет помимо режима паравиртуализации (как openvz) режим полной виртуализации (в т.ч. поддержка соответствующих фич процессоров), есть механизмы переброса железа внутрь виртуалки (например, поддержка не самых слабых intel видеокарт), снапшоты, миграция,… много много вкусных фич.

    VMWare — как и xen, сложен, наворочен, приправлен соответствующей инфраструктурой и хорошими забористыми ценами :) режима полноценной паравиртуализации не имеет

    kvm/qemu — полная эмуляция процессора (а так же виртуализация через поддержку процессорами), есть вкусности от 'старших братьев' вида миграция запущенной виртуалки по сети, переброса железа (сильно хуже поддержка чем xen/vmware) и т.п. можно считать бакэндом, так как GUI в идеалогии не имеет, оно пилится желающим

    VirtualBox — эмуляция процессора, в т.ч. использование поддержки виртуализации процессоров, идеален как отдельное десктопное приложение, миграции по сети нет, есть снапшоты, некоторые вкусности скрыты от GUI в коммандной строке

    OpenVZ — это работа всех машин на одном ядре (патчи к нему так и зовутся openvz), нет виртуализации, максимальная скорость (так как фактически это расширенный chroot с изоляцией). Для запуска модуля ядра на поклон нужно идти к хост системе и ее администратору (например tun/tap адаптер у firstvds дают по запросу)
    Снапшотов нет (но их реализуют через lvm), миграция есть, есть сброс состояния контейнера на диск и возобновление работы…

    Lxc — еще проще чем openVZ, нет даже грамотной изоляции (если подсуетиться, можно, имея рут в контейнере, выйти в хост систему с рутовым доступом), прямой аналог jail во freebsd, имеет смысл для хитрых сетевых конфигураций, тестов и т.п.

    Chroot — это даже не виртуалка, это просто простейшая изоляция в пределах файловой системы, подмена путей в вызовах функций работы с файлами.
    p.s. lxc называют еще 'chroot на стероидах'

    OpenVZ/lxc/chroot поддерживают почти полноценное каскадирование виртуалок (т.е. к примеру можно внутри контейнера openvz запустить kvm/virtualbox при наличии модулей, даже с поддержкой аппаратного ускорения)
    Ответ написан
    6 комментариев
  • Почему input в состоянии webkit-autofill искажает бордер?

    delphinpro
    @delphinpro Куратор тега CSS
    frontend developer
    у меня не отображает.

    вывод: по усмотрению браузера, и ничего с этим сделать нельзя.
    Ответ написан
    Комментировать
  • Почему один регэксп работает, а второй нет?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    ЕМНИП, в basic и extended режимах внутри квадратных скобок символы не эскейпятся и бэкслэш рассматривается как обычный символ. В первом случае получаем интервал от бэкслэша до бэкслэша (то есть, бэкслэш) и точку. Во втором - бэкслэш (дважды), точку и тире.
    Эскейпятся только в PCRE (ключ -P).
    Ответ написан
    Комментировать
  • Почему Laravel 9 врет про ошибки?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега Laravel
    Blade в этом плане сложен - он "компилируется" в настоящий php и кэшируется, поэтому реальный стек сложно сопоставить с исходником.

    Поэтому надо писать в нём минимум логики, а всю работу производить в контроллере. В шаблоне у вас не должно быть никаких $_GET и уж конечно никаких
    $cats=$site->qa("select * from categories where catid=0  order by name asc");
    Тогда они будут простыми и ошибку будет сложнее совершить и гораздо легче найти. А если она случится в контроллере, то там уже трейс будет нормальный.
    Использовать нормальный фреймворк, но при этом писать в нём код так, как будто на дворе до сих пор PHP 5.2 - это странно.
    Ответ написан
    2 комментария
  • В школьном вай фае заблокирован порт 9. Как обойти блокировку?

    Никак. Перестать заниматься ерундой и строить из себя школьного хацкера.
    Ответ написан
    12 комментариев
  • Возможность использования анонимного адреса @MAIL.RU для скрипта рассылки?

    @dim5x
    ЗИ, ИБ. Помогли? Поблагодарите. Отметьте ответом.
    import smtplib
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    
    
    def send_email_mail_ru():
        smtp_server = "smtp.mail.ru"
        smtp_port = 587  # или 465 для SSL.
        username = "*****@mail.ru" # Анонимный ящик.
        password = "****************"  # Пароль от приложения.
    
        # Создаем сообщение:
        msg = MIMEMultipart()
        msg['From'] = username
        msg['To'] = "************@mail.ru"
        msg['Subject'] = "Тестовое письмо с Mail.ru"
    
        # Текст письма:
        body = """тест"""
        msg.attach(MIMEText(body, 'plain', 'utf-8'))
    
        try:
            # Подключаемся к серверу:
            server = smtplib.SMTP(smtp_server, smtp_port)
            server.starttls()
            server.login(username, password)
    
            # Отправляем письмо:
            server.sendmail(username, "*********@yahoo.com", msg.as_string())
            print("Письмо успешно отправлено через Mail.ru!")
    
        except Exception as e:
            print(f"Ошибка при отправке: {e}")
        finally:
            server.quit()
    
    send_email_mail_ru()
    Ответ написан
    8 комментариев
  • Как работает ленивость в регулярных выражениях?

    Alexandroppolus
    @Alexandroppolus
    кодир
    https://regex101.com/r/HOpNtj/1

    (?:[^/]|(?<!/)/(?!/))*МОСКВА(?:[^/]|(?<!/)/(?!/))*

    прикол в том, что номера домов могут содержать дробь, потому вокруг слова "МОСКВА" недостаточно просто написать [^\/]*

    PS: по ссылке все слеши без экранирования. Добавь сам при необходимости (зависит от ЯП)
    Ответ написан
    3 комментария
  • Как сделать нажатие кнопки при парсинге в python?

    @Everything_is_bad
    Начни с чтения доков requests
    Ответ написан
    Комментировать
  • Как исправить ощибку Uncaught TypeError: $.getJSON(...).success is not a function?

    Daemon23RUS
    @Daemon23RUS
    API jQuery - jQuery.getJSON()
    The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callback methods are removed as of jQuery 3.0. You can use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.

    А "обсуждений много по этой ошибке, но решения нет нигде" потому как все разжевано в официальной документации.
    Ответ написан
    Комментировать
  • Как смонтировать сетевую папку из Windows на чтение и запись без рута в Debian 13?

    @Drno
    Да команда mount потребует рут, это нормально
    про монтирование на этапе загрузки уже подсказали, про fstab
    Ответ написан
    Комментировать
  • Как убедиться, что одностраничный сайт (SPA) корректно индексируется поисковыми системами Google и Яндекс?

    Mike_Ro
    @Mike_Ro Куратор тега Поисковая оптимизация
    Python, JS, WordPress, SEO, Bots, Adversting
    Основной контент загружается динамически через JavaScript. Появились сомнения, что поисковые системы (Googlebot и робот Яндекса) корректно видят и индексируют такой сайт.

    По моим наблюдениям, чем позже загружается динамический контент (относительно первого ответа сервера), тем меньше шансов у него попасть в индексацию.
    Какими актуальными методами можно проверить это технически?

    Самый простой вариант, оператор фиксирующий количество слов в ключевой фразе - "ключевая фраза", затем копируем строку текста из динамики и вставляет ее в поисковик, если сайт найдется, то именно этот блок текста индексируется.
    Нужно ли делать SSR или пререндеринг, или современные поисковики уже справляются с рендерингом?

    С рендерингом динамики они справляются давно, а вот ранжирование такого контента оставляет желать лучшего. Я считаю, что на 2025 год SSR/SSG обязателен, для успешной конкуренции в поисковой выдаче.
    Ответ написан
    3 комментария
  • Как установить grafana на Ubuntu?

    Wispik
    @Wispik
    Ответ написан
    Комментировать
  • Оцените сборку ПК?

    yakovlev_13
    @yakovlev_13
    Шаманство, экзорцизм и некромантия.
    В целом ок.
    Но то что корпус дороже БП это странно.
    Если сборка по низу прайса, то в корпус надо закладывать самую малую сумму.
    Ответ написан
    3 комментария
  • Syntaxerror invaild syntax Что я делаю не так?

    @utsiye
    import time в первой строке должно быть, а не iNport time

    В будущем, читайте и разбирайте ошибку - там часто есть указание на строку. Если всеравно не исправили ошибку - прикрепляйте ее в вопрос.
    Ответ написан
    1 комментарий
  • Загрузка файлов блокируется браузером, почему?

    @kira_clover
    Чтобы браузер доверял https соединению нужно:
    1) использовать ssl сертификат с цепочкой из корневого и промежуточного центров сертификации. Через openssl это тоже можно сделать
    2) чтобы цепочка сертификатов была доверенной на устройстве или в самом браузере. Для этого нужно установить и корневой и промежуточный сертификаты в доверенные
    3) чтобы веб-сервер был настроен на шифрование по tls версии не ниже 1.3
    Ответ написан
    Комментировать