В Selenium у меня встала задача сохранять cookies, чтобы не авторизоваться при каждом запуске скрипта. В принципе, авторизация не проблема, но на некоторых ресурсах есть ограничение на количество попыток авторизации в день, а на некоторых на авторизацию вводится капча.
Поэтому пришлось решать вопрос сохранения cookies в Selenium + NODE JS.
Выкладываю код в том порядке, в каком он должен исполняться в скрипте авторизации.
Первоначально нужно перейти на страницу авторизации, или хотя бы на страницу домена, потому что cookies можно загрузить на страницу только тогда, когда домен cookies соответствует домену страницы:
await driver.get('https://accounts.mydomain.com'); await driver.getPageSource(); //Ждем загрузки страницы
Далее считываем cookies из файла, имя файла указываем в переменной CookieFile:
//STEP READ COOKIES CookieFile = "u:/Oper/node/cookies.txt"; try { console.log("File:" + CookieFile); data = fs.readFileSync(CookieFile); strings = data.toString().split(os.EOL); for (string_i = 0; string_i < strings.length; string_i++) { tokens = strings[string_i].split(";"); try { await driver.manage().addCookie({name:tokens[0], value:tokens[1], domain:tokens[2], path:tokens[3]}); } catch (e) {console.log("Cookie " + tokens[0] + " not read:" + e );} } console.log('Cookies read OK'); } catch (e) { console.log('Cookies not read:' + e); }
Далее анализируем, есть ли на странице поля авторизации, т.е. требуется ли авторизация или сработали загруженные из файла cookies. В данном примере авторизация ручная, т.е. вводится пользователем, контролирующим работу скрипта:
try {el_login=driver.findElement(By.id("login_id")); //Element login not exist, this talks about that authorisation ok console.log('Authorisathion OK'); AuthorisationOK = true; } catch (e) { console.log('Authorisathion Failed'); AuthorisationOK = false; } if (AuthorisationOK == false) { //Manual autorization try {await driver.wait(until.titleIs('xxxxxxxxxxxxxxxxxxxxxx'), 20*1000);} catch (e) {} }
После авторизации нужно сохранять cookies:
//STEP SAVE COOKIES all_cookies = await driver.manage().getCookies(); console.log('Cookies read' + all_cookies); str_all = ""; // loop for getting the cookie information for(let ck of all_cookies) { str_all = str_all + ck.name + ";" + ck.value + ";" + ck.domain + ";" + ck.path + os.EOL; } console.log("Cookies = " + os.EOL + str_all); fs.writeFile(CookieFile, str_all, 'utf8', (err) => {if (err) throw err;}); console.log('Cookies saved OK');
Это прописано в документации на Селениум в /documentation/en/support_packages/working_with_cookies/
Нафига описывать очевидные вещи ?
Ты про это?
https://www.selenium.dev/documentation/en/support_packages/working_with_cookies/
Это я видел.
Дьявол в деталях, т.к. я мало времени работал с Java-Script, угробил часа 3-4, чтобы сохранять и восстанавливать кукис.
Я был бы благодарен, если бы нашел готовый код, но на просторах интернета его нет.
Вот и ответ — зачем. Затем, чтобы программист мог взять готовый код.
т.е. ты угробил 4 часа на чтение и запись текстового файла в node.js, мы тебя правильно поняли? и все равно сделал это криво.
во-первых, раз уж ты уже используешь await-ы, то мог бы и заюзать fs/promises API, и работать с файлами через await-ы для консистентности
во-вторых, если в readFile вторым параметром передать кодировку, то получишь сразу строку с данными
strings = fs.readFileSync(CookieFile, ‘utf8’);
тут забыл await
try {el_login=driver.findElement(By.id(«login_id»))
т.е. кому-то еще и с багами в твоем коде разбираться придется
ну и наконец, научись уже переменные инициализировать, а то однажды еще 4 часа потратишь на отладку, из-за того, что у тебя все переменные в глобальную область видимости уходят
Спасибо за критику. Моя цель была написать работающий код, причем я был ограничен бюджетом клиента.
Поэтому изучать все тонкости java не входило в мои задачи.
Возможно, Ваши замечания пригодятся тем, кто захочет использовать мой код в дальнейших разработках.
А 4 часа потому что я работаю в 1С, а не java, новое всегда дается долго.