Мне нужно спарсить данные со
страницы а именно телефон, но засекречен кнопкой "показать телефон" и reCAPTCHA V2
Я решил использовать Selenium, сначала я закрыл всплывающее окно новым гостям страницы, затем нажал кнопку "показать телефон", после чего отправил капчу на API 2Captcha он её решил, я всунул ответ, но телефон не показываеться и вообще капча не решаеться, я не знаю как решить эту проблему(
Вот код:
import lombok.extern.log4j.Log4j;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.stereotype.Component;
import ru.shmatov.telegramwebparser.utils.HttpUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Component
@Log4j
public class CaptchaSolver {
private final String twoCaptchaApiKey = "API_KEY";
private WebDriver driver;
public CaptchaSolver() {
System.setProperty("webdriver.chrome.driver",
System.getProperty("user.dir") + "/src/main/resources/chromedriver");
this.driver = new ChromeDriver();
}
public String solveCaptcha(String url) throws IOException, InterruptedException {
driver.get(url);
new WebDriverWait(driver, 15).until(
webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete")
);
log.debug("Страница загружена");
try {
WebElement closeButtonOne = new WebDriverWait(driver, 10)
.until(ExpectedConditions.elementToBeClickable(By.className("tutorial__close")));
closeButtonOne.click();
log.debug("Закрыто первое всплывающее окно");
} catch (TimeoutException e) {
log.debug("Первое всплывающее окно отсутствует.");
}
WebElement showPhoneButton = new WebDriverWait(driver, 10)
.until(ExpectedConditions.elementToBeClickable(By.className("show-phones")));
showPhoneButton.click();
log.debug("Нажали кнопку 'Показать телефон'");
//
WebElement captchaFrame = new WebDriverWait(driver, 15)
.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("iframe[src*='recaptcha/api2/anchor']")));
String siteKey = captchaFrame.getAttribute("src").split("k=")[1].split("&")[0];
log.debug("siteKey извлечен: " + siteKey);
String captchaResponse = sendCaptchaTo2Captcha(siteKey, url);
if (captchaResponse == null) {
throw new IllegalStateException("Не удалось получить ответ от 2Captcha.");
}
log.debug("Ответ от 2Captcha получен: " + captchaResponse);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementById('g-recaptcha-response').style.display = 'block';");
js.executeScript("document.getElementById('g-recaptcha-response').value = arguments[0];", captchaResponse);
js.executeScript("document.getElementById('g-recaptcha-response').dispatchEvent(new Event('change', {bubbles: true}));");
js.executeScript("document.getElementById('g-recaptcha-response').dispatchEvent(new Event('input', {bubbles: true}));");
js.executeScript("document.getElementById('g-recaptcha-response').dispatchEvent(new Event('blur', {bubbles: true}));");
log.debug("Решение капчи вставлено и события вызваны");
LogEntries logs = driver.manage().logs().get(LogType.BROWSER);
for (LogEntry entry : logs) {
log.error("JavaScript error: " + entry.getMessage());
}
try {
WebElement submitButton = driver.findElement(By.cssSelector("button[type='submit']"));
submitButton.click();
log.debug("Клик по кнопке подтверждения выполнен.");
} catch (NoSuchElementException e) {
log.debug("Кнопка подтверждения не найдена. Продолжаем.");
}
try {
WebElement phoneNumberElement = new WebDriverWait(driver, 30)
.until(ExpectedConditions.visibilityOfElementLocated(By.className("offer__contacts-phones")));
log.debug("Номер телефона получен: " + phoneNumberElement.getText());
return phoneNumberElement.getText();
} catch (TimeoutException e) {
log.error("Телефон не появился на странице. Возможно, капча была отклонена.");
throw new IllegalStateException("Телефон не отображается после решения капчи.");
}
}
private String sendCaptchaTo2Captcha(String siteKey, String url) throws IOException, InterruptedException {
Map<String, String> params = new HashMap<>();
params.put("key", twoCaptchaApiKey);
params.put("method", "userrecaptcha");
params.put("googlekey", siteKey);
params.put("pageurl", url);
// Отправляем запрос на 2Captcha
String response = HttpUtils.postForm("http://2captcha.com/in.php", params);
log.debug("Ответ от 2Captcha (создание задачи): " + response);
if (!response.startsWith("OK|")) {
throw new IllegalStateException("Ошибка 2Captcha при создании задачи: " + response);
}
// Извлекаем Task ID
String taskId = response.split("\\|")[1];
log.debug("Task ID: " + taskId);
// Ждем результат решения
Thread.sleep(5000);
while (true) {
response = HttpUtils.get("http://2captcha.com/res.php?key=" + twoCaptchaApiKey + "&action=get&id=" + taskId);
log.debug("Ответ от 2Captcha (проверка результата): " + response);
if (response.startsWith("OK|")) {
return response.split("\\|")[1]; // Возвращаем решение капчи
} else if (response.equals("CAPCHA_NOT_READY")) {
log.debug("Капча еще не готова, ждем...");
Thread.sleep(5000);
} else {
throw new IllegalStateException("Ошибка 2Captcha: " + response);
}
}
}
}
Вот код утилиты HttpUtils
import okhttp3.*;
import java.io.IOException;
import java.util.Map;
public class HttpUtils {
private static final OkHttpClient client = new OkHttpClient();
public static String postForm(String url, Map<String, String> params) throws IOException {
FormBody.Builder formBuilder = new FormBody.Builder();
for (Map.Entry<String, String> entry : params.entrySet()) {
formBuilder.add(entry.getKey(), entry.getValue());
}
Request request = new Request.Builder()
.url(url)
.post(formBuilder.build())
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Ошибка HTTP: " + response);
}
return response.body().string();
}
}
public static String get(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.get()
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Ошибка HTTP: " + response);
}
return response.body().string();
}
}
}
Код сервиса и кнотроллеры бота не кидаю, они стандартны и настроены правильно