• Как скачать содержимое сайта?

    Fzero0
    @Fzero0
    Вечный студент
    const puppeteer = require('puppeteer');
    const { KnownDevices } = require('puppeteer');
    const fs = require('fs');
    const path = require('path');
    const { PDFDocument } = require('pdf-lib');
    const { readFile } = require('fs/promises');
    
    function delay(time) {
        return new Promise(function(resolve) { 
            setTimeout(resolve, time)
        });
    }
    
    async function takeScreenshots(url) {
        const browser = await puppeteer.launch({ headless: true });
        const page = await browser.newPage();
    
        // Устанавливаем мобильный User-Agent и разрешение экрана для iPhone 15 Pro
        const iPhone = KnownDevices['iPhone 15 Pro'];
        await page.emulate(iPhone);
    
        await page.goto(url);
        await delay(5000); // Ждем 5 секунд, чтобы страница полностью загрузилась
    
        // Получаем общее количество страниц
        const numPages = await page.evaluate(() => window.originTotalPageCount);
        console.log(`Total pages: ${numPages}`);
    
        // Создаем папку для сохранения скриншотов, если ее нет
        const imagesDir = 'images';
        if (!fs.existsSync(imagesDir)) {
            fs.mkdirSync(imagesDir);
        }
    
        for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) {
            // Делаем скриншот всей страницы
            const screenshotPath = path.join(imagesDir, `page_${pageNumber}.png`);
            await page.screenshot({ path: screenshotPath, fullPage: true });
            console.log(`Screenshot saved to ${screenshotPath}`);
    
            // Свайп влево для перехода на следующую страницу
            if (pageNumber < numPages) {
                const { width, height } = await page.evaluate(() => ({
                    width: document.documentElement.clientWidth,
                    height: document.documentElement.clientHeight
                }));
    
                const startX = width - 10;
                const endX = 10;
                const swipeY = height / 2;
    
                // Имитация свайпа
                await page.touchscreen.touchStart(startX, swipeY);
                await delay(100);
                await page.touchscreen.touchMove(endX, swipeY);
                await delay(100);
                await page.touchscreen.touchEnd();
    
                await delay(1000); // Ждем 1 секунду, чтобы страница переключилась
            }
        }
    
        await browser.close();
    
        // Создаем папку для сохранения PDF, если ее нет
        const outputDir = 'output';
        if (!fs.existsSync(outputDir)) {
            fs.mkdirSync(outputDir);
        }
    
        // Создаем PDF из изображений
        const pdfDoc = await PDFDocument.create();
        const imageFiles = fs.readdirSync(imagesDir).sort((a, b) => {
            const numA = parseInt(a.match(/\d+/)[0]);
            const numB = parseInt(b.match(/\d+/)[0]);
            return numA - numB;
        });
    
        for (const imageFile of imageFiles) {
            const imagePath = path.join(imagesDir, imageFile);
            const imageBytes = await readFile(imagePath);
            const image = await pdfDoc.embedPng(imageBytes);
            const page = pdfDoc.addPage([image.width, image.height]);
            page.drawImage(image, {
                x: 0,
                y: 0,
                width: image.width,
                height: image.height,
            });
        }
    
        const pdfBytes = await pdfDoc.save();
        const pdfPath = path.join(outputDir, `book.pdf`);
        fs.writeFileSync(pdfPath, pdfBytes);
        console.log(`PDF saved to ${pdfPath}`);
    }
    
    const url = process.argv[2] || 'https://www.yunzhan365.com/book/12345.html'; // Replace with your URL
    takeScreenshots(url);

    Ставим зависимости
    Запускаем так
    node screenshot.js https://book.yunzhan365.com/klqn/xobm/mobile/index.html
    Ответ написан
    Комментировать
  • Распрекрасный Rutube и получение объекта видео через «fetch», почему ошибка?

    @maksam07
    Shimpanze,
    Какого его не может получить «fetch»?
    Через браузер вы обращаетесь от домена эндпоинта, от которого хотите получить информацию.
    У рутуба настроена политика CORS. Лучше обратиться к официальной документации, но если не хотите, то пользоваться чем-то подобным:

    const proxyUrl = 'https://api.allorigins.win/get?url=';
    const targetUrl = 'https://rutube.ru/api/video/37daa4e656174d04db06c5fca7548751';
    
    fetch(proxyUrl + encodeURIComponent(targetUrl))
        .then(response => {
            if (!response.ok) {
                throw new Error('Network response was not ok');
            }
            return response.json();
        })
        .then(data => {
            // данные могут быть внутри data.contents
            console.log('Data retrieved:', JSON.parse(data.contents));
        })
        .catch(error => {
            console.error('There was a problem with the fetch operation:', error);
        });
    Ответ написан
    1 комментарий
  • Как сделать кнопку такой фигурой?

    Get-Web
    @Get-Web Куратор тега CSS
    Front-End Developer
    clip-path. Как раз есть пример с анимацией:
    Ответ написан
    Комментировать
  • Создать тепловую карту времени, за которое можно добраться до точки?

    @SergeyMarkelov
    Такие линии равного времени доступа от точки — называются изохроны (isohrone).

    1) У Яндекса матрица расстояний — это коммерческий продукт API Яндекс.Карт https://yandex.ru/maps-api/products/distancematrix-api

    2) Есть бесплатный софт, но его надо настраивать см. https://github.com/urbica/galton

    3) Есть сервис с изохронами, построенными на открытых данным OpenStreetMap (только по графу дорог БЕЗ общественного транспорта). Но их сайт https://transmetrika.com/ — уже некоторое время закрыт, уж не знаю, на время или навсегда.

    4) На сервере RuMap есть бесплатная возможность построения изохрон с интервалом 5, 10, 15 и т.д. минут (областей, куда можно попасть из конкретной точки — пешком, на машине, либо на общественном транспорте). Вот как выглядит изохрона 10 минут на машине от точки Москва, Сеславинская улица, 24.

    65a556d3b3038156534514.jpeg
    Ответ написан
    Комментировать
  • Как реализовать авто-деплой nuxt приложения с SSR?

    @vitaly_il1
    DevOps Consulting
    Тут есть несколько вопросов:
    1) Как деплоить pm2 без опускания сервиса - смотреть здесь https://www.google.com/search?q=pm2+deploy+without...
    2) Как обеспечить работу сервиса если билд был неудачный? - иметь несколько серверов с лоадбалансером, отключать один, деплоить, тестировать, подключать если все ОК. Делать rollback если не ОК
    3) Как все это автоматизировать - если код на GitHub, проще всего с помощью GitHub Actions
    4) В AWS и других облаках 2 и 3 намного легче, так есть есть готовые сервисы которые умеют плавно деплоить
    Ответ написан
    Комментировать
  • Как сделать такую кнопку?

    SeaInside
    @SeaInside
    15 лет пилю все эти штуки
    Жму руку дизайнеру, молодец, не как у всех.

    Прямо так, как на скриншоте, на чистом CSS вряд ли получится, ибо левый нижний угол строго вертикальный, а вот правый... вообще с трудом такую фигуру представляю в реальности, поэтому вариант с трансформацией средствами браузера тут отпадает.

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



    Но когда заметил - понял, что так в принципе не выйдет сделать, на CSS нельзя "зафиксировать от трансформации" две стороны сразу.

    Так что остаётся вариант с фоновой SVG-шкой, что по сути "фоновая картинка", либо вариант со вставкой этой SVG напрямую в кнопку (прям инлайном) и дальнейшие манипуляции с ней, если требуется адекватный ховер.

    Делать лень, это нетрудно :)
    Ответ написан
    2 комментария
  • Почему в примере ниже правильный ответ 0, затем 1?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В документации MDN к for..in прямо пишут, что порядок детерминирован и одинаков во всех браузерах/движках:
    The traversal order, as of modern ECMAScript specification, is well-defined and consistent across implementations.

    Within each component of the prototype chain, all non-negative integer keys (those that can be array indices) will be traversed first in ascending order by value, then other string keys in ascending chronological order of property creation.

    Причем русскоязычная версия там же иначе описывает порядок обхода. Надо бы поправить перевод.

    На Русском языке лучше прочитать про порядок свойств на learn.javascript.ru
    Ответ написан
    Комментировать
  • Как называется этот эффект в поле ввода?

    hahenty
    @hahenty
    ('•')
    Ответ написан
    Комментировать
  • Какой-то скрипт или расширение подменяет или добавляет в код веб-приложения слова, что это может быть?

    У меня была похожая ситуация, для пользователей у которых был включён автоматический переводчик (Google Translate). И перевод с русского на русский был очень и очень странным иногда. Так же теги font добавляются при этом (Красный флаг). Что бы этого избежать можно указать:

    <meta name="google" content="notranslate">
    Ответ написан
    1 комментарий
  • Как сделать изменение цвета текста при скролле?

    RAX7
    @RAX7
    Ответ написан
    Комментировать
  • Какие есть паттерны для применения миграций в мультитенантном приложении?

    SilenceOfWinter
    @SilenceOfWinter Куратор тега PHP
    та еще зажигалка...
    не знаю как реализованы миграции в ларавел, но предполагаю что аналогично юи и симфони т.е. установленные миграции фиксируются в таблице бд. я бы сделал общий гит репозиторий из которого тенанты через апи получают нужные версии пакетов, при установке пакета накатываются миграции отсутствующие в таблице миграций.
    p.s. тенанты, а не тенаты
    Ответ написан
    2 комментария
  • В чем ошибка данного способа?

    vaxotivadze
    @vaxotivadze
    Full stack web developer
    const ul = document.querySelector('ul'),
          result = document.querySelector('h4');
    
    const showFn = (e) => {
      const curEl = e.target;
      if (curEl.tagName === 'LI') {
        result.textContent = curEl.textContent;
      }
    }
    
    ul.addEventListener('click', showFn);
    Ответ написан
    Комментировать
  • Есть ли способ красиво вызвать addeventlistener несколько раз?

    zkrvndm
    @zkrvndm
    Архитектор решений
    Обычно делают так:
    document.body.addEventListener('mouseenter', function(e) {
        console.log(e.target);
    });

    В переменной e.target будет лежать целевой элемент, проверяйте его на соответствие и если он соответствует...

    code.mu/ru/javascript/manual/dom/matches
    Ответ написан
    Комментировать
  • Как сделать градиентный прогресс бар?

    RAX7
    @RAX7
    Ответ написан
    Комментировать
  • Стоит ли покупать коленный стул?

    @PKmaster
    Всегда за компьютером
    Коленный стул, вред и польза.
    К сожалению, очень много рассуждающих теоретиков, и очень мало реально сидевших.
    Я сижу на этом стуле с 2018 года, и могу на собственном опыте все рассказать как есть, а не сказки из интернета. Есть реальные плюсы, и есть реальные минусы, у этой штуки.
    Но сначала пройдусь по писавшим ранее :-)))))

    - "Смартсул" хорошие вещи делает, но дорого. Я сижу на Богатыре, он принципиально ничем не хуже, а дешевле в 2 раза

    - "Повышенная нагрузка на колени" - нет такого, при правильной позе. Но у нас же блин все умные, никто инструкций, прилагаемых к стулу, не читает, все ставят максимально высоко сиденье, сползают на колени и привет. А всего то надо настроить стул под свой рост, чтобы 80% веса приходилось на попу.

    - "Не на стандартную высоту стола рассчитаны" - неправда. Стандартная высота стола или школьной парты 75 см. У меня дома стол 78. И мне удобно. И всем, кто сидит, а таких знакомых у меня уже штук пять. И все сидят за обычными столами. Конечно, в идеале нужен еще и стол с наклоном, но это блин 30 000р+, я пока не готов.

    - "Нагрузка со спины распределяется, но за счет колен" - ага, 20 раз. В реальности нагрузка на этом стуле на спину по ощущениям БОЛЬШЕ, чем при сидении на обычном стуле!! Потому что вес падает на мышцы, а не на позвоночник. Причем и на мышцы поясницы, и в целом спины, и на бедра и т.п. Посидите сами, не 5 минут "на примерке", а реальных 2-3 часа. Сразу все мышцы спины прочувствуете, особенно, когда их нет :-)))) как у меня было, когда сел. На позвоночник нагрузка на этом стуле меньше (в чем и прикол и польза), а на мышцы - больше!! И устают они будь здоров. Для этого ксати я стул со спинкой и купил, откидываюсь, отдыхаю, иначе по 8 часов не просидишь....

    - "От него болит спина" - спина болит, когда чем-то заболели, грыжу когда насидели, и т.п. Мышцы - да, испытывают повышенные нагрузки, держат Вашу спину. Да, сразу Вы 8 часов не просидите, я привыкал месяц, пока мышцы более-менее в тонус пришли и стали спину держать. И что в этом плохого? По-моему, наоборот хорошо, когда мышцы спины тренируются.

    - "Нет подлокотников" - так они нафиг не нужны, иначе смысл пропадает!! На подлокотник опираешься, спину изгибаешь, вес переносишь на локоть, позвоночник искривляешь и сидишь так часами. Типа. И смысл тогда коленный стул ставить?? Такой буквой зю можно и на обычном стуле сидеть...
    Если уж хочется опереться на что-то, я локти на стол кладу (очень удобно, кстати, и все дети, наблюдал, также делают), или на спинку откидываюсь. В последнем случае это чисто поза отдыха, работать невозможно, кстати...

    Итог:
    Реальные плюсы коленного стула:
    - спина стала ровнее;
    - не так устаю за компом;
    - чаще встаю (что тоже плюс, считаю);
    - мышцы спины натренировались, без проблем держу осанку;
    - стул не дает "развалиться" телу, как на обычном кресле, тело всегда в тонусе;
    - по истечении полугода так привык, что уже на обычных стульях долго сидеть неудобно, хочется правильной позы.
    - у родни, подростка 19 лет, сколиоз приостановился. Не исчез, конечно, но сам факт. Т.к. больше пацан ничего не делает, в плане здоровья. Т.е. название "ортопедический коленный стул" имеет за собой основание.

    Минусы коленного стула:
    - топорная конструкция. Кто бы что не говорил, это блин больше агрегат, чем дизайнерская мебель. Рядом с моим бывшим компьютерным креслом смотрится как полный отстой. :-)))) Но оно не для красоты придумано, я так понимаю. Если придумают "красивый" и не хуже, и недорогой - сразу заменю. :-)))
    - залезать-вылезать в джинсах удобно, в юбке, жена сказала, не очень :-)))
    - если неправильно настроить стул (слишком высоко поднять сиденье и т.п.) - будете сползать на колени. А это нехорошо. Поэтому тут надо четко подобрать свое, удобное положение. Чтобы сидеть на заднице, а не на коленях. Так что не надо отсебятины, просто читаем настройки и регулируем коленный стул под свой рост (благо все регулируется).
    - привыкать надо, 100%, и к этому надо быть готовым. У меня ушел месяц, пока более-менее привык. В первую неделю сидения обнаружил у себя мышцы, о которых не подозревал. :-))) Некоторым из моих знакомых так и "не зашло", хотя пробовали. Дети привыкают за 2-3 дня, у них организм гибкий, подстраивается легче.
    - по-первости просидеть 8 часов кряду не получится. Отдых телу давать придется, вставать, ноги вытягивать, на спинку откидываться... У меня так и было. Хотя, еще раз повторю, что некоторые садятся и сидят часами, сразу, но это исключение, как мне кажется.

    Короче плюсов больше, чем минусов
    Ответ написан
    3 комментария
  • Кто проходил курсы от Otus? Отзывы? Мнения?

    @eiv_tm
    Я пытался учиться на Kotlin в Otus, отзывы судя по-всему пишут их сотрудники, такого дна я еще не видел. Преподаватели опаздывают, не готовятся к лекции, несут такую ахинею волосы дыбом. Но есть и плюс, я прослушал три лекции, пришло понимание, что я не готов за это платить и мне вернули сумму полностью, так как вовремя пришло осознание, если бы позже, то высчитали бы. За это им спасибо, а если в интернете почитать отзывы, то это у них не на одном курсе такое, системность прослеживается.
    Ответ написан
    Комментировать
  • Как сделать чтобы цвет текста при скролле переходил из градиента в белый?

    RAX7
    @RAX7
    Режимы наложения тут вряд ли помогут, проще продублировать текст и скрывать лишнее через clip-path
    Ответ написан
    Комментировать
  • Чему учит Марк Лутц?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    Ответ написан
    Комментировать