구글 로그인을 자동화시키기 위해 접근하면 보안상 구글은 자동화를 막아요ㅠ
Python의 경우 undetected_chromedriver 기능을 제공하지만 JAVA는 없습니다..
검색을 해봐도 Python보다는 정보가 적어서 포스팅하게 됐습니다!
마지막의 최종 코드를 첨부해두었으니 급하신 분들은 제일 아래로 내려가주세요!
1. 크롬 디버깅 모드
보통은 아래 코드로 원하는 페이지에 접속하실 거에요.
적용 이전 코드
@SpringBootApplication
public class SeleniumApplication {
public static void main(String[] args) {
SpringApplication.run(SeleniumApplication.class, args).getBean(SeleniumApplication.class).test();
}
public void test(){
ChromeOptions options = new ChromeOptions(); // 세션 시작
options.setPageLoadStrategy(PageLoadStrategy.NORMAL); // Normal : 로드 이벤트 실행이 반환될 때까지 대기
WebDriver driver = new ChromeDriver(options);
try{
driver.get("접근할 URL");
}
}
}
PageLoadStrategy는 3가지 방법이 있어요.
제가 사용한 NORMAL 외에도
- EAGER : 페이지가 완전히 로드되기 전에도 접근하여 속도 향상이 가능하지만 접근 할 Element가 로드되었는지 확인이 필요
- NONE
이 있습니다.
위와 같은 방식은 구글이 아닌 다른 곳에서는 접근이 가능할테지만
구글은 막혀있어서 우회해서 접근해야해요.
크롤링 디버깅모드는 크롤링에 필요한 단계를 줄여주기도 하고, 봇으로 감지가 안된다고 합니다.
위 코드를 아래와 같이 변경해주었어요.
적용 후 코드
@SpringBootApplication
public class SeleniumApplication {
public static void main(String[] args) {
SpringApplication.run(SeleniumApplication.class, args).getBean(SeleniumApplication.class).test();
}
public void test(){
Runtime.getRuntime().exec("C:/Program Files/Google/Chrome/Application/chrome.exe --remote-debugging-port=9222 --user-data-dir=\"C:/Selenium/ChromeData\""); // 크롬 디버깅 모드
ChromeOptions options = new ChromeOptions();
options.setPageLoadStrategy(PageLoadStrategy.NORMAL);
options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222"); // 해당 포트로 selenium 열기
WebDriver driver = new ChromeDriver(options);
try{
driver.get("접근할 URL");
}
}
}
구글링을 통해 2줄의 코드를 추가해주었습니다!
크롬이 어디에 설치되어있냐에 따라 Runtime.getRuntime().exec("이 부분이 다를거에요");
- C:\Program Files\Google\Chrome\Application\
- C:\Program Files (x86)\Google\Chrome\Application\
위 두 경로 중에서는 설치되어있을테니 각자 환경에 맞추어 코드 작성해주세요!
크롬 디버깅 모드로 창이 열리긴 하지만 원하는 URL에 접근하지 못하고 403 error가 나왔어요..
403 error는 접근 거부 에러 코드에요.
selenium을 사용해보면서 여러 에러들이 나오고 이에 대해 구글링할 때마다 만능 해결사처럼 나오는 코드가 있었습니다. 바로바로,
options.addArguments("--remote-allow-origins=*");
하지만 전 이걸 추가해도 해결이 안됐습니다..
2. 2차 인증 없는 구글 로그인 우회 URL
먼저 위 URL에 접근해서 구글 로그인을 진행하고 원하는 URL에 접속해주세요!
위 URL은 2차 인증을 안해도 구글 로그인이 가능한 곳이더라고요!
하지만...
아이디 입력까지는 되는데 비밀번호 입력까지는 넘어가지 않았어요..
존재하지 않는 Element로 나왔었습니다ㅠ
그래서 아이디 입력 후 비밀번호 Element로 넘어가는 사이에 텀을 주었어요!
아래 코드를 추가해서요!
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
텀을 주는 방법은 제가 사용한 암시적 대기와 명시적 대기가 있어요.
암시적 대기는 예외를 throw하기 전에 일정 시간 기다립니다.
전 10초 기다리게 코드를 작성한거고
SECONDS, MINUTES, MILISECOND, DAYS, HOURS 등의 단위가 있습니다.
명시적 대기는 예외를 throw하기 전에
특정 조건 또는 최대 시간을 초과할 때까지 기다립니다.
간단하게는 Thread.Sleep()으로 대기를 주는데
내가 기다려야하는 Element에만 대기를 주는게 속도 향상이 되어 좋아요
그래서 권장하는 방법은
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.util(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#inBtn")));
와 같이 작성해줍니다.
그래도 403 에러가 나왔어요...
영어에 약해서 stackoverflow를 잘 안보는데 결국 봤습니다.
그 결과, 성공!!!
최종 코드와 함께 보여드릴게요!
3. Selenium Http Jdk Client
관련 공식 문서
https://www.selenium.dev/blog/2022/using-java11-httpclient/
최종 코드
gradle에 이것저것 import할 때 mvnrepository 사이트 참고하시면 좋습니다 :)
// build.gradle 파일에 아래 코드를 추가해주세요.
// https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-http-jdk-client
implementation 'org.seleniumhq.selenium:selenium-http-jdk-client:4.9.1'
@SpringBootApplication
public class SeleniumApplication {
public static void main(String[] args) throws IOException {
SpringApplication.run(SeleniumApplication.class, args).getBean(SeleniumApplication.class).test();
}
public void test() throws IOException {
Runtime.getRuntime().exec("C:/Program Files/Google/Chrome/Application/chrome.exe --remote-debugging-port=9222 --user-data-dir=\"C:/Selenium/ChromeData\"");
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
options.setPageLoadStrategy(PageLoadStrategy.NORMAL);
options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
System.setProperty("webdriver.http.factory", "jdk-http-client"); // 추가 코드
WebDriver driver = new ChromeDriver(options);
try{
driver.get("https://accounts.google.com/o/oauth2/v2/auth/identifier?redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&prompt=consent&response_type=code&client_id=407408718192.apps.googleusercontent.com&scope=email&access_type=offline&flowName=GeneralOAuthFlow&service=lso&o2v=2");
// id 입력
driver.findElement(By.xpath("//*[@id=\"identifierId\"]")).sendKeys("구글 아이디 입력해주세요!");
// 버튼 클릭
driver.findElement(By.xpath("//*[@id=\"identifierNext\"]/div/button")).click();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
// pw 입력
driver.findElement(By.xpath("//*[@id=\"password\"]/div[1]/div/div[1]/input")).sendKeys("구글 비밀번호 입력해주세요!");
// 버튼 클릭
driver.findElement(By.xpath("//*[@id=\"passwordNext\"]/div/button")).click();
System.out.println("구글 로그인 성공 = " + driver.getCurrentUrl());
} finally {
driver.quit();
}
}
}
저는 Element에 접근할 때 xpath로 접근했지만
cssSelector, className, id 등 다양한 방법이 있습니다.
이렇게 구글 로그인 자동화 성공!!
이 다음에 구글 플레이스토어로 이동해봤는데
구글 로그인된게 사라져있더라고요..
성공했지만 성공하지 못했어...
'JAVA > [개인프로젝트] GooGoo' 카테고리의 다른 글
JDBC, JPA, Spring Data JPA 차이 그리고 Hibernate와 ORM (0) | 2023.10.13 |
---|---|
CSR VS SSR (0) | 2023.09.10 |
[Spring Security] 일반 로그인과 소셜 로그인 (oauth2) 그리고 JWT (0) | 2023.09.06 |
[외부 API 호출] RestTemplate, WebFlux (WebClient) 그리고 WebSocket (0) | 2023.09.02 |
[Spring Boot] 최고의 프로젝트 구조는 무엇일까? (0) | 2023.08.30 |