Оригинал: https://lwebapp.com/en/post/regular-expression-to-match-multiple-lines-of-text
Вопрос
В нашей повседневной работе для повышения эффективности труда мы можем писать скрипты для автоматизации задач. Поскольку некоторые веб-сайты требуют от пользователей входа в систему, функция автоматического входа в скрипт очень важна.
Однако, когда мы входим на сайт, мы часто видим проверочные коды. Цель проверочных кодов — предотвратить машинный вход в систему и автоматизировать работу скрипта. Есть ли способ для скриптов автоматически определять проверочные коды для достижения входа в систему?
Далее я использую сайт bilibili.com в качестве примера, чтобы объяснить вам, как решить наиболее критическую проблему верификационных кодов в скрипте автоматического входа.
Изучите
Прежде всего, вам необходимо ознакомиться с методом входа на этот сайт и понять тип его проверочного кода.
Откройте https://www.bilibili.com/, откройте консоль, нажмите login, затем в середине появится небольшое окно входа, обычно после ввода учетной записи и пароля появляется окно проверочного кода, мы предполагаем, что интерфейс проверочного кода был запрошен в это время.
Поскольку на английском языке код верификации называется captcha
, мы ищем captcha
в панели network
.
Интерфейс, связанный с проверочным кодом, найден
https://passport.bilibili.com/x/passport-login/captcha
Нажмите на интерфейс, чтобы увидеть результаты, и там есть некоторая полезная информация, мы обнаружили, что тип captcha — geetest
.
{
"code": 0,
"message": "0",
"ttl": 1,
"data": {
"type": "geetest",
"token": "b416c387953540608bb5da384b4e372b",
"geetest": {
"challenge": "aeb4653fb336f5dcd63baecb0d51a1f3",
"gt": "ac597a4506fee079629df5d8b66dd4fe"
},
"tencent": {
"appid": ""
}
}
}
В результате поиска я обнаружил, что сервис проверочного кода, используемый bilibili.com, предоставляется компанией geetest
, которая используется многими веб-сайтами. Особенностью проверочного кода geetest
является перемещение пазлов и выбор слов или цифр по порядку.
Итак, далее давайте найдем способ распознать проверочный код geetest
.
Я изучил решения для распознавания проверочного кода, представленные на рынке, и наиболее эффективные из них, по сути, являются поставщиками услуг OCR. После сравнения, я обнаружил, что сервис 2Captcha очень хорош, с быстрой скоростью декодирования, стабильным соединением сервера, поддержкой многоязычного API и разумной ценой, я решил попробовать 2Captcha
.
Официальный сайт 2Captcha
Далее мы покажем использование Nodejs
+ Playwright
+ 2Captcha
для решения проблемы кода проверки логина на сайте bilibili.com.
Если вы хотите использовать другие языки и фреймворки, например
Python
+Selenium
, вы также можете обратиться к этому руководству, идея решения проблемы та же.
Решение
- Как определить проверочный код
Сначала прочитайте официальный документ 2Captcha API Geetest, решение очень подробное, проще говоря
- Перехватив интерфейс сайта, получить два параметра кода проверки
gt
иchallenge
, запроситьhttp://2captcha.com/in.php
и получить код проверкиID
. - Запросите
http://2captcha.com/res.php
через некоторое время и получитеchallenge
,validate
,seccode
об успешной верификации.
- Как применять результаты верификации
После получения наиболее критического validate
, имитируем ввод пользователем учетной записи и пароля для входа в систему, перехватываем возвращаемые параметры интерфейса запроса кода верификации, заменяем их на параметры успешной верификации, а затем запускаем интерфейс входа в систему.
Далее мы проанализируем подробные шаги
Среда
Сначала создадим среду выполнения скрипта.
Мы используем Node.js
+ Playwright
для выполнения сценариев.
-
Убедитесь, что Nodejs установлен локально на вашем компьютере
-
Создайте новый пустой проект и установите
Playwright
.
mkdir bypass-captcha
cd bypass-captcha
npm init
npm i -D playwright
Мы используем библиотечный режим
Playwright
, подробная документация: Playwright
- Создайте новый файл скрипта
captcha.js
в корневом каталоге проекта, заполните его следующим содержанием, запуститеnode captcha.js
в командной строке, чтобы просто проверить, можно ли нормально запустить проект
const { chromium } = require("playwright");
(async () => {
const browser = await chromium.launch({
headless: false,
});
const page = await browser.newPage();
await page.goto("https://www.bilibili.com/");
await browser.close();
})();
При нормальных обстоятельствах появится интерфейс браузера Google, отображающий главную страницу сайта bilibili.com, после чего браузер автоматически закроется.
Запрос интерфейса in.php
- Сначала разберитесь с параметрами, необходимыми для запроса интерфейса
http://2captcha.com/in.php
. Вы можете увидеть список параметров. Мы обратим внимание на параметры, которые необходимо передать.
Параметр | Тип | Требуемый | Описание |
---|---|---|---|
ключ | Строка | Да | ваш ключ API |
метод | Строка | Да | geetest — определяет, что вы отправляете капчу Geetest |
gt | Строка | Да | Значение параметра gt, которое вы нашли на целевом сайте |
вызов | Строка | Да | Значение параметра challenge, найденное на целевом сайте |
api_server | Строка | Нет | Значение параметра api_server, найденного на целевом сайте |
pageurl | Строка | Да | Полный URL страницы, на которой вы видите капчу Geetest |
header_acao | IntegerПо умолчанию: 0 | Нет | 0 — отключено1 — включено.Если включено в.php будет включать заголовок Access-Control-Allow-Origin:* в ответ. Используется для междоменных AJAX-запросов в веб-приложениях. Также поддерживается res.php. |
pingback | Строка | Нет | URL для ответа pingback (обратный вызов), который будет отправлен, когда капча будет решена. URL должен быть зарегистрирован на сервере. Более подробная информация здесь. |
json | IntegerDefault: 0 | Нет | 0 — сервер будет отправлять ответ в виде обычного текста1 — указывает серверу отправлять ответ в виде JSON |
soft_id | Integer | Нет | Идентификатор разработчика программного обеспечения. Разработчики, интегрировавшие свои программы с 2captcha, получают вознаграждение: 10% от трат пользователей их программ. |
прокси | Строка | Нет | Формат: login:password@123.123.123.123:3128 Более подробную информацию о прокси вы можете найти здесь. |
proxytype | Строка | Нет | Тип вашего прокси-сервера: HTTP, HTTPS, SOCKS4, SOCKS5. |
userAgent | Строка | Нет | Ваш userAgent, который будет передан нашему работнику и использован для решения капчи. |
Таким образом, мы можем получить интерфейс запроса следующего вида
http://2captcha.com/in.php?key=1abc234de56fab7c89012d34e56fa7b8&method=geetest>=ac597a4506fee079629df5d8b66dd4fe&challenge=12345678abc90123d45678ef90123a456b&pageurl=https://www.bilibilicom/
- Далее решаем проблему получения нового значения
challenge
при каждом входе на главную страницу
Процесс имитации входа пользователя по щелчку мыши
-
Сначала запустите Google Chrome и откройте главную страницу сайта bilibili.com
-
Нажмите кнопку входа в систему в верхней части, появится окно входа в систему
-
В это время интерфейс верификационного кода был отправлен, и вы можете перехватить значения
gt
иchallenge
, прослушивая ответ, возвращаемый интерфейсом верификационного кода.
const { chromium } = require("playwright");
(async () => {
// Select the Chrome browser, set headless: false to see the browser interface
const browser = await chromium.launch({
headless: false,
});
const page = await browser.newPage();
// open bilibili.com
await page.goto("https://www.bilibili.com/");
const [response] = await Promise.all([
// request verification code interface
page.waitForResponse(
(response) =>
response.url().includes("/x/passport-login/captcha") &&
response.status() === 200
),
// Click the login button at the top
page.click(".header-login-entry"),
]);
// Get the interface response information
const responseJson = await response.body();
// Parse out gt and challenge
const json = JSON.parse(responseJson);
const gt = json.data.geetest.gt;
const challenge = json.data.geetest.challenge;
console.log("get gt", gt, "challenge", challenge);
// Pause for 5 seconds to prevent the browser from closing too fast to see the effect
sleep(5000);
// close the browser
await browser.close();
})();
/**
* Simulate the sleep function, delay for a number of milliseconds
*/
function sleep(delay) {
var start = new Date().getTime();
while (new Date().getTime() < start + delay);
}
- Используйте библиотеку
request
для отдельного запроса интерфейсаin.php
.
Сначала установите request
.
npm i request
Теперь пришло время запросить интерфейс http://2captcha.com/in.php
.
// request in.php interface
const inData = {
key: API_KEY,
method: METHOD,
gt: gt,
challenge: challenge,
pageurl: PAGE_URL,
json: 1,
};
request.post(
"http://2captcha.com/in.php",
{ json: inData },
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log("response", body);
}
}
);
При нормальных обстоятельствах в это время будет возвращен код проверки ID
, например {"status":1, "request": "2122988149"}
, просто возьмите поле request
.
Если интерфейс возвращает код
ERROR_ZERO_BALANCE
, это означает, что баланс вашего счета недостаточен и вам необходимо пополнить счет. Здесь я пополнил баланс на минимальную сумму для демонстрации, а вы можете сделать это в соответствии со своими потребностями.
Расширенное обучение
Для повышения безопасности мы обращаемся к API Key
в файле переменных окружения.
- Создайте новый файл переменной окружения
.env
в корневом каталоге и запишите значениеAPI Key
.
# .env file
API_KEY="d34y92u74en96yu6530t5p2i2oe3oqy9"
- Затем установите библиотеку
dotenv
для получения переменных окружения
npm i dotenv
- Используйте его в js
require("dotenv").config();
Таким образом, переменные в .env
могут быть получены через process.env.API_KEY
. Обычно файлы .env
не загружаются в хранилище кода для обеспечения безопасности личной информации.
- Если вы не хотите записывать информацию в файл, обеспечивая безопасность, вы также можете напрямую ввести переменную окружения Node.js в консоли, например
API_KEY=d34y92u74en96yu6530t5p2i2oe3oqy9 node captcha.js
Запрос интерфейса res.php
- Перед запросом интерфейса мы также отсортируем необходимые параметры
GET-параметр Тип Требуемый Описание ключ Строка Да ваш ключ API действие Строка Да get — получить ответ для вашей капчи id Целое число Да ID капчи, возвращаемой in.php. json IntegerПо умолчанию: 1 Нет Для капчи Geetest сервер всегда будет возвращать ответ в виде JSON.
- Через 20 секунд после последнего запроса запросите интерфейс
http://2captcha.com/res.php
, чтобы получить результат проверки.
request.get(
`http://2captcha.com/res.php?key=${API_KEY}&action=get&id=${ID}&json=1`,
function (error, response, body) {
if (!error && response.statusCode == 200) {
const data = JSON.parse(body);
if (data.status == 1) {
console.log(data.request);
}
}
}
);
Интерфейс вернет три значения challenge
, validate
и seccode
, каждый параметр представляет собой строку
{
"geetest_challenge": "aeb4653fb336f5dcd63baecb0d51a1f3",
"geetest_validate": "9f36e8f3a928a7d382dad8f6c1b10429",
"geetest_seccode": "9f36e8f3a928a7d382dad8f6c1b10429|jordan"
}
Среди них challenge
— это параметр, который мы перехватили ранее, validate
— идентификатор результата проверки, а содержание seccode
в основном такое же, как и у validate
, только с одним дополнительным словом. Нам нужно сохранить validate
для последующего использования.
Иногда код проверки не может быть проверен здесь. Вы можете попробовать несколько раз или обратиться на официальный сайт 2Captcha для устранения проблемы
На данном этапе получена информация о результате проверки проверочного кода, и следующим шагом будет вход в систему с результатом проверки.
Вход в систему
- Давайте сначала изучим процесс входа в систему после того, как обычный пользователь нажимает на проверочный код для подтверждения успеха.
Мы обнаружили три интерфейса.
Проанализировав эти интерфейсы, мы обнаружили две схемы входа в систему.
- Первое решение заключается в запросе интерфейса шифрования и интерфейса входа в среду
Node.js
для получения информации о cookie пользователя, и пользователь может войти в систему непосредственно с информацией о cookie. Сложность этой схемы заключается в том, что для шифрования пароля нужно отдельно разбираться с паролем, что не очень удобно для новичка. - Второе решение заключается в использовании
Playwright
для имитации ввода пользователем учетной записи и пароля для входа в систему, случайного нажатия проверочного кода для запуска входа в систему, перехвата параметра ответа интерфейса проверочного кода, замены его на успешный проверочный код, а затем запуска интерфейса входа в систему.
Мы принимаем второе решение.
Но я также столкнулся с трудностями, в среде Node.js
изображение проверочного кода не могло быть загружено. Затем я обнаружил, что интерфейс кода проверки https://api.geetest.com/ajax.php
также отвечает за извлечение изображения кода проверки и проверку кода проверки. Мы напрямую перехватываем запрос при извлечении изображения кода верификации и заменяем результат верификации для запуска входа в систему, не дожидаясь появления изображения кода верификации. Эта деталь очень важна.
Заключение
Выше приведены некоторые исследования распространенных функций автоматического входа в задачи автоматизированного тестирования. Объединив сильные стороны Node.js
, Playwright
, и 2Captcha
, реализовано распознавание кода верификации. Я загрузил полный код на GitHub.
https://github.com/openHacking/bypass-captcha
Возможно, есть много мест, которые нужно оптимизировать, и вы можете указать на них.
Отказ от ответственности: Этот скрипт используется только как тестовый и учебный пример, и риск оценивается самостоятельно.
Ссылка
- Playwright
- 2Captcha
-
Python автоматический вход Bilibili (платформа для кодирования 2captcha)
-
Python автоматический вход Bilibili (платформа для кодирования 2captcha)