Алексей
Подскажите пож как дефолтные 30 сек загрузки поменять на 60 - 90 сек..
Тарас
await page.goto('https://example.com', { timeout: 60_000 }); или page.setDefaultTimeout(60_000);
Алексей
await page.goto('https://example.com', { timeout: 60_000 }); или page.setDefaultTimeout(60_000);
Пробовал, js перестал успевать отработать и спа сайт подгружал только хтмл без динамики через js. Потому сюда и написал
Алексей
А ну я первый вариант пробовал . попробую второй
Тарас
Тогда с waitUntil бы еще поиграть, типа await page.goto('https://example.com', { timeout: 60_000, waitUntil: 'networkidle2' });
Alex
ребят подскажите как обойти защиту ozon на парсинг. это не великая тайна?
Alex
просто любую страничку товара открыть
Shivam
Hello everyone, I'm looking for some help. I've built a powerful Puppeteer-based automation tool that applies to jobs across multiple platforms like LinkedIn, Dice, ZipRecruiter, Naukri, Monster, Indeed, etc. Everything works perfectly in my local environment in headless mode. However, after deploying the backend to an EC2 instance, I'm facing an issue specifically with LinkedIn login. It prompts for an OTP sent to my email, which I can't currently handle through Puppeteer automation in headless mode. If anyone has experience with this and can help, please DM me . I'm happy to pay for your time and support.
Алексей
〘 Желтушка Ворон 〙
Ребят, уже несколько часов гуглю, помогите, пожалуйста, как исправить это? Не даёт скачивать расширения ни в какую. if (!string.IsNullOrEmpty(user_agent)) { args.Add($"--user-agent=\"{user_agent}\""); } if (proxy != null && proxy.is_use) args.Add($"--proxy-server={proxy._full}"); var options = new LaunchOptions() { Headless = false, Args = args.ToArray(), // Также добавляю --user-data-dir IgnoredDefaultArgs = new[] { "--enable-automation", "--disable-extensions", "--disable-extensions-except" }, DefaultViewport = null, ExecutablePath = Spider._path_chrome, ProtocolTimeout = 0, Timeout = 0, }; this.browser = await Puppeteer.LaunchAsync(options); P.s. очень прошу мне помочь, если вы сталкивались с этим.
Null
Ребят, уже несколько часов гуглю, помогите, пожалуйста, как исправить это? Не даёт скачивать расширения ни в какую. if (!string.IsNullOrEmpty(user_agent)) { args.Add($"--user-agent=\"{user_agent}\""); } if (proxy != null && proxy.is_use) args.Add($"--proxy-server={proxy._full}"); var options = new LaunchOptions() { Headless = false, Args = args.ToArray(), // Также добавляю --user-data-dir IgnoredDefaultArgs = new[] { "--enable-automation", "--disable-extensions", "--disable-extensions-except" }, DefaultViewport = null, ExecutablePath = Spider._path_chrome, ProtocolTimeout = 0, Timeout = 0, }; this.browser = await Puppeteer.LaunchAsync(options); P.s. очень прошу мне помочь, если вы сталкивались с этим.
Вот такой простой пример прекрасно работает. Так что проблема у тебя в чём-то другом: import puppeteer from 'puppeteer'; const browser = await puppeteer.launch({ headless: false, userDataDir: "./data", args: [ `--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36`, ], ignoreDefaultArgs: ["--disable-extensions"], }); const [page] = await browser.pages(); await page.setViewport({ width: 1366, height: 768 }); await page.goto('https://chromewebstore.google.com/detail/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh');
Null
Ребят, уже несколько часов гуглю, помогите, пожалуйста, как исправить это? Не даёт скачивать расширения ни в какую. if (!string.IsNullOrEmpty(user_agent)) { args.Add($"--user-agent=\"{user_agent}\""); } if (proxy != null && proxy.is_use) args.Add($"--proxy-server={proxy._full}"); var options = new LaunchOptions() { Headless = false, Args = args.ToArray(), // Также добавляю --user-data-dir IgnoredDefaultArgs = new[] { "--enable-automation", "--disable-extensions", "--disable-extensions-except" }, DefaultViewport = null, ExecutablePath = Spider._path_chrome, ProtocolTimeout = 0, Timeout = 0, }; this.browser = await Puppeteer.LaunchAsync(options); P.s. очень прошу мне помочь, если вы сталкивались с этим.
Мне кажется ты юзерагент неправильно выставляешь. Справа от равно не нужны кавычки.
〘 Желтушка Ворон 〙
Null
Я попробовал и так и так, у меня работает, что с кавычками что без. Но в ноде если кавычки поставить то они будут частью юзерагента. P.S. Наверное шарпы иначе обрабатывают аргументы. Но в любом случае проблема в чём-то другом.
〘 Желтушка Ворон 〙
Вот такие у меня аргументы: List<string> args = new List<string>(){ "--no-sandbox", "--mute-audio", "--disable-gpu", "--disable-infobars", "--disable-translate", "--disable-default-apps", "--disable-web-security", "--disable-dev-shm-usage", //"--disable-notifications", "--disable-setuid-sandbox", "--enable-remote-extensions", "--disable-renderer-backgrounding", "--extensions-install-verification", "--safebrowsing-disable-auto-update", "--allow-legacy-extension-manifests", "--disable-background-timer-throttling", // Для таймеров "--enable-chrome-browser-cloud-management", "--enable-easy-off-store-extension-install", "--disable-blink-features=AutomationControlled", "--disable-features=IsolateOrigins,site-per-process", "--disable-component-extensions-with-background-pages", "--disable-site-isolation-trials", "--ignore-certificate-errors", "--ignore-ssl-errors", "--start-maximized", $"--user-data-dir=\"{path_to_dir}\"", $"--load-extension={this.extns} --disable-extensions-except={this.extns}", };
〘 Желтушка Ворон 〙
Попробуй для начала только такой вариант. Оставь только самый минимум как у меня. Если работает, тогда уже будешь искать какой аргумент мешает.
Так и делал. Понял ошибку: дело в $"--load-extension={this.extns} --disable-extensions-except={this.extns}", думаю по отдельности сначала их включить, а не в одной строке (хотя это не влияет), а потом поубирать аккуратно
〘 Желтушка Ворон 〙
Приложу сюда решение: нужно было удалить строчку --disable-extensions-except={this.extns}, т.к. она разрешала только одно расширение, а остальные блокировала. Спасибо всем за помощь!
Алексей
Привет. Подскажите пож как задержку на получение страницы выставить? По умолчанию она 30 сек. Ниже кидаю код
Алексей
import http from 'http'; import { URL } from 'url'; import puppeteer from 'puppeteer'; // Запуск браузера и создание скриншота const browser = await puppeteer.launch(); const page = await browser.newPage(); const server = http.createServer(async (req, res) => { if (req.method === 'GET') { // Создаем объект URL для анализа var url = new URL(req.url, "http://${req.headers.host}"); // Получаем значение параметра 'name' var name = url.searchParams.get('name') || 'Гость'; var name = url.searchParams.get('name'); var html = "Пусто!" if (name) { console.log(name); // Выведите его в консоль для проверки await page.goto(name, { waitUntil: 'networkidle2' }); var html = await page.content(); } // Установка заголовков и отправка res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); //res.end(name); res.end(html); } else { // Ответ для других URL res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('Not Found'); } }); // Запуск сервера на порту 3000 server.listen(3000, () => { console.log('Server is running on http://localhost:3000'); });
Raso
import http from 'http'; import { URL } from 'url'; import puppeteer from 'puppeteer'; // Запуск браузера и создание скриншота const browser = await puppeteer.launch(); const page = await browser.newPage(); const server = http.createServer(async (req, res) => { if (req.method === 'GET') { // Создаем объект URL для анализа var url = new URL(req.url, "http://${req.headers.host}"); // Получаем значение параметра 'name' var name = url.searchParams.get('name') || 'Гость'; var name = url.searchParams.get('name'); var html = "Пусто!" if (name) { console.log(name); // Выведите его в консоль для проверки await page.goto(name, { waitUntil: 'networkidle2' }); var html = await page.content(); } // Установка заголовков и отправка res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); //res.end(name); res.end(html); } else { // Ответ для других URL res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('Not Found'); } }); // Запуск сервера на порту 3000 server.listen(3000, () => { console.log('Server is running on http://localhost:3000'); });
what error you take?
Алексей
Raso
is there a issue on code?
Алексей
No
Null
import http from 'http'; import { URL } from 'url'; import puppeteer from 'puppeteer'; // Запуск браузера и создание скриншота const browser = await puppeteer.launch(); const page = await browser.newPage(); const server = http.createServer(async (req, res) => { if (req.method === 'GET') { // Создаем объект URL для анализа var url = new URL(req.url, "http://${req.headers.host}"); // Получаем значение параметра 'name' var name = url.searchParams.get('name') || 'Гость'; var name = url.searchParams.get('name'); var html = "Пусто!" if (name) { console.log(name); // Выведите его в консоль для проверки await page.goto(name, { waitUntil: 'networkidle2' }); var html = await page.content(); } // Установка заголовков и отправка res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); //res.end(name); res.end(html); } else { // Ответ для других URL res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('Not Found'); } }); // Запуск сервера на порту 3000 server.listen(3000, () => { console.log('Server is running on http://localhost:3000'); });
Странные вещи делаешь, которые не дадут нужного результата: var name = url.searchParams.get('name') || 'Гость'; Тут ты получаешь какое-то имя из name, если его нет то присваиваешь значение "Гость", а потом по этому значению пытаешься перейти как по URL (await page.goto(name))? Интерполяция строк работает только внутри бэктиков (обратная кавычка): // Было var url = new URL(req.url, "http://${req.headers.host}"); // Стало var url = new URL(req.url, `http://${req.headers.host}`); Не понятно зачем это. Если тебе нужно получить какой-то URL из параметра, просто извлеки его, проще использовать url.parse(req.url, true). Насчёт твоего вопроса: await page.goto("<URL>", { timeout: 60000 }); P.S. На будущее, оформляй код нормально, через следующую конструкцию: ```js code ```
Null
import http from 'node:http'; import url from 'node:url'; import puppeteer from 'puppeteer'; const browser = await puppeteer.launch({ headless: false, userDataDir: "./data", args: [ `--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36`, ], }); const [page] = await browser.pages(); // Example: timeout - 5 sec, target - https://example.com/ // http://localhost:3000/?timeout=5000&target=https://example.com/ const server = http.createServer(async (req, res) => { if (req.method !== 'GET') { res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end('Not Found'); return; } const parsedUrl = url.parse(req.url, true); const query = parsedUrl.query; let html = ""; if (query.target) { try { await page.goto(query.target, { timeout: query.timeout || 60000 }); html = await page.content(); console.log(`[OK] ${query.target} [${html.length} bytes]`); } catch (err) { console.log(`[FAILED] ${query.target}`); console.error("[ERROR]", err.stack); } } res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end(html); }); server.listen(3000, () => { console.log('Server is running on http://localhost:3000'); });
Null
Если у вас возникла какая-то ошибка, указывайте версию ОС, версию Node.js и версию Puppeteer, например: OS: Linux Debian 11 Node: 22.16.0 Puppeteer: 24.14.0 Для оформления кода используйте следующую конструкцию: ```js code ``` Не забывайте заглядывать в ишьюсы на гитхабе, возможно у кого-то уже была подобная проблема. Некоторые вопросы так же можете задавать в чате Playwright (@playwright).
Алексей
Странные вещи делаешь, которые не дадут нужного результата: var name = url.searchParams.get('name') || 'Гость'; Тут ты получаешь какое-то имя из name, если его нет то присваиваешь значение "Гость", а потом по этому значению пытаешься перейти как по URL (await page.goto(name))? Интерполяция строк работает только внутри бэктиков (обратная кавычка): // Было var url = new URL(req.url, "http://${req.headers.host}"); // Стало var url = new URL(req.url, `http://${req.headers.host}`); Не понятно зачем это. Если тебе нужно получить какой-то URL из параметра, просто извлеки его, проще использовать url.parse(req.url, true). Насчёт твоего вопроса: await page.goto("<URL>", { timeout: 60000 }); P.S. На будущее, оформляй код нормально, через следующую конструкцию: ```js code ```
В наме приходит урл что парсить, парсит спа сайт на js и отдает в ответ весть отработанный js с хтмл. Все работает. У меня скрипт падал когда сайт дольше 30 сек отрабатывал. Я разобрался как таймаут поднять до 90 сек. Щас все ок. У меня сайт и парсер адаптирован под сайт он парстит и наполняет и работает на пхп. Потому ноду поднял отдельно и таким образом их соединил. Все заработало как часы.
Алексей
Там я куски с гпт выдернул. Гость не пишет. Пишет пусто если не отправить урл и открыть страницу скрипта
Алексей
Я ноду и js не знаю толком, накидал за пару дней что смог. Мне это не для тестов, для работы. Каталог товаров парсю
Алексей
Подскажите пож как заполнить строку на работу с сокс5 по авторизации логин и пароль, гпт что то не то пишет
Алексей
вроде
Алексей
args: [--proxy-server=${proxyUrl}]
〘 Желтушка Ворон 〙
🅰️nimeCoder
args: [--proxy-server=${proxyUrl}]
это будет работать с HTTP прокси
Алексей
это будет работать с HTTP прокси
А как сокс5 прописать верно?
〘 Желтушка Ворон 〙
?
Нуу, с аутентификацией не работает такой способ
Алексей
Я заметил
Алексей
Можно пример если не сложно?
Алексей
Я разные варианты пробовал, но скрипт падает(
Алексей
Гпт чат лажу выдает, хотя утверждает что вариант под сокс5, еще и без кавычек часто код дает
🅰️nimeCoder
А как сокс5 прописать верно?
насколько знаю - никак делай http сервер прокси что юзает для запросов апстрим сокс
Алексей
У меня прокся США IP, хотя я вроде в лк могу протокол сменить
🅰️nimeCoder
Есть вроде готовые решения типа 3proxy что поддерживают апстрим, как пример для референса, я юзаю для создания HTTP прокси с авторизацией, которая под капотом обращается через другую HTTP прокси без авторизации
Алексей
Странно , а чего только http и https та?
🅰️nimeCoder
Странно , а чего только http и https та?
потому что в браузере вроде и не нужно ничего кроме http / https, видимо нет нужды :)
🅰️nimeCoder
ну или альтернатива, делать запросы с ноды через request интерцептор браузера
Алексей
Как все сложно
Алексей
Блин
Алексей
Проще тогда впн поставить
Алексей
На локалке дело
Алексей
Алексей
Для использования SOCKS5 прокси с авторизацией по логину и паролю в Puppeteer, вам нужно будет установить прокси-сервер, который поддерживает SOCKS5. К сожалению, Puppeteer не поддерживает встроенную аутентификацию для SOCKS5 напрямую через аргументы командной строки. Однако вы можете использовать специальный подход с помощью библиотеки socks-proxy-agent. Вот пример, как это можно сделать: 1. Установите необходимые пакеты: npm install puppeteer socks-proxy-agent 2. Используйте следующий код для запуска Puppeteer с SOCKS5 прокси и авторизацией: const puppeteer = require('puppeteer'); const { SocksProxyAgent } = require('socks-proxy-agent'); (async () => { const proxyUrl = 'socks5://username:password@proxy-host:proxy-port'; // Замените на ваши данные const agent = new SocksProxyAgent(proxyUrl); const browser = await puppeteer.launch({ args: [ --proxy-server=${proxyUrl} ], ignoreDefaultArgs: ['--enable-automation'], headless: true, // Установите agent для использования с Puppeteer defaultViewport: null, executablePath: puppeteer.executablePath(), // Важно: используйте agent в контексте страницы }); const page = await browser.newPage(); // Установите прокси-агент для страницы await page.setRequestInterception(true); page.on('request', (request) => { request.continue({ agent }); }); await page.goto('https://example.com'); // Замените на нужный URL // Ваши действия на странице... await browser.close(); })(); ▎Объяснение кода: • socks-proxy-agent: Это библиотека, которая позволяет вам использовать SOCKS5 прокси с аутентификацией. • proxyUrl: Это строка, содержащая информацию о прокси, включая логин и пароль. • page.setRequestInterception: Этот метод позволяет перехватывать запросы и использовать прокси-агент для каждого запроса. Этот подход позволяет вам использовать SOCKS5 прокси с аутентификацией в Puppeteer. Убедитесь, что вы заменили username, password, proxy-host и proxy-port на свои реальные данные.
Алексей
Врет что ли?
🅰️nimeCoder
кто знает
Алексей
кто знает
А ну я прочитал этот пост. Правда не умеет , тут библиотека дополнительная и надстройка для работы с сокс5
Алексей
Сокс5 меньше палится на сколько я знаю
Алексей
Да мне пару буржуйских сайтов проверить нужно, проще на пару минут протокол сменить
Null
Для использования SOCKS5 прокси с авторизацией по логину и паролю в Puppeteer, вам нужно будет установить прокси-сервер, который поддерживает SOCKS5. К сожалению, Puppeteer не поддерживает встроенную аутентификацию для SOCKS5 напрямую через аргументы командной строки. Однако вы можете использовать специальный подход с помощью библиотеки socks-proxy-agent. Вот пример, как это можно сделать: 1. Установите необходимые пакеты: npm install puppeteer socks-proxy-agent 2. Используйте следующий код для запуска Puppeteer с SOCKS5 прокси и авторизацией: const puppeteer = require('puppeteer'); const { SocksProxyAgent } = require('socks-proxy-agent'); (async () => { const proxyUrl = 'socks5://username:password@proxy-host:proxy-port'; // Замените на ваши данные const agent = new SocksProxyAgent(proxyUrl); const browser = await puppeteer.launch({ args: [ --proxy-server=${proxyUrl} ], ignoreDefaultArgs: ['--enable-automation'], headless: true, // Установите agent для использования с Puppeteer defaultViewport: null, executablePath: puppeteer.executablePath(), // Важно: используйте agent в контексте страницы }); const page = await browser.newPage(); // Установите прокси-агент для страницы await page.setRequestInterception(true); page.on('request', (request) => { request.continue({ agent }); }); await page.goto('https://example.com'); // Замените на нужный URL // Ваши действия на странице... await browser.close(); })(); ▎Объяснение кода: • socks-proxy-agent: Это библиотека, которая позволяет вам использовать SOCKS5 прокси с аутентификацией. • proxyUrl: Это строка, содержащая информацию о прокси, включая логин и пароль. • page.setRequestInterception: Этот метод позволяет перехватывать запросы и использовать прокси-агент для каждого запроса. Этот подход позволяет вам использовать SOCKS5 прокси с аутентификацией в Puppeteer. Убедитесь, что вы заменили username, password, proxy-host и proxy-port на свои реальные данные.
С агентом сложно выглядит, проще поставить proxy-chain.
Null
Для использования SOCKS5 прокси с авторизацией по логину и паролю в Puppeteer, вам нужно будет установить прокси-сервер, который поддерживает SOCKS5. К сожалению, Puppeteer не поддерживает встроенную аутентификацию для SOCKS5 напрямую через аргументы командной строки. Однако вы можете использовать специальный подход с помощью библиотеки socks-proxy-agent. Вот пример, как это можно сделать: 1. Установите необходимые пакеты: npm install puppeteer socks-proxy-agent 2. Используйте следующий код для запуска Puppeteer с SOCKS5 прокси и авторизацией: const puppeteer = require('puppeteer'); const { SocksProxyAgent } = require('socks-proxy-agent'); (async () => { const proxyUrl = 'socks5://username:password@proxy-host:proxy-port'; // Замените на ваши данные const agent = new SocksProxyAgent(proxyUrl); const browser = await puppeteer.launch({ args: [ --proxy-server=${proxyUrl} ], ignoreDefaultArgs: ['--enable-automation'], headless: true, // Установите agent для использования с Puppeteer defaultViewport: null, executablePath: puppeteer.executablePath(), // Важно: используйте agent в контексте страницы }); const page = await browser.newPage(); // Установите прокси-агент для страницы await page.setRequestInterception(true); page.on('request', (request) => { request.continue({ agent }); }); await page.goto('https://example.com'); // Замените на нужный URL // Ваши действия на странице... await browser.close(); })(); ▎Объяснение кода: • socks-proxy-agent: Это библиотека, которая позволяет вам использовать SOCKS5 прокси с аутентификацией. • proxyUrl: Это строка, содержащая информацию о прокси, включая логин и пароль. • page.setRequestInterception: Этот метод позволяет перехватывать запросы и использовать прокси-агент для каждого запроса. Этот подход позволяет вам использовать SOCKS5 прокси с аутентификацией в Puppeteer. Убедитесь, что вы заменили username, password, proxy-host и proxy-port на свои реальные данные.
https://t.me/puppeteer_ru/14229
Null
Он поднимает локальный http-прокси, и создаёт апстрим на реальный прокси.
Alexander
подскажите такой момент. в non-headless на Ubuntu на ноуте прекрасно работает скрипт. на линукс сервере с виртуализацией дисплея xvfb-run или с xvfb-run --auto-servernum --server-args='-screen 0 1920x1080x24' сайт засекает, что компьютер ненормальный. что можно сделать?
Alexander
Alexander
вариант ip рассматривал?
Проблема не в IP (пока что). На также на ноутбуке на Ubuntu пробовал этот скрипт. через XVFB натыкается на защиту. сейчас буду пробовать другие дисплеи помио xvfb
Alexander
Без xvfb нормально. но нужно будет скрипт запускать на сервере.
Alexander
а там без дисплея ошибку даёт
Alexander
Ошибка такая. session not created: probably user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir
ZDev | Разработчик
Ошибка такая. session not created: probably user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir
Так тут же все ясно, ты используешь кем-то уже испрльзуемую папку профиля, либо не исрользуй, либо используй уникальную
Alexander
Так тут же все ясно, ты используешь кем-то уже испрльзуемую папку профиля, либо не исрользуй, либо используй уникальную
то есть всё таки в докере должен в headed режиме работать браузер без проблем? я ещё раз попробую конечно. я естественно пробовал до этого указывать уникальную папку профиля и т.д. использовал вообще selenium. может из за него баги. но через puppeteer не удавалось пройти cloudflare
Alexander
на puppeteer такая ошибка если без headless в docker [561:576:0818/094903.457092:ERROR:dbus/bus.cc:408] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory [561:561:0818/094903.458937:ERROR:ui/ozone/platform/x11/ozone_platform_x11.cc:249] Missing X server or $DISPLAY [561:561:0818/094903.458962:ERROR:ui/aura/env.cc:257] The platform failed to initialize. Exiting. ну ошибка с отсутвием дисплея
Raso
DM for cloudflare bypass.