![[Java/Selenium] Crawling 시 reCAPTCHA 우회 시도 - 2 / Chrome이 자동화된 테스트 소프트웨어에 의해 제어되고 있습니다. 해결하기](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBC6hr%2Fbtsk0SaaMPZ%2F8nTavLDIZdA6wqgvZhMEs0%2Fimg.png)
이전 글과 이어집니다
[Java/Selenium] Crawling 시 reCAPTCHA 우회 시도 - 1
현재 Google에서 동작하는 Crawler을 제작 중인데 계속 reCAPTCHA에 막혀 고생.. 혹시 다음에도 Crawler를 만들 수도 있을까 하는 생각에 간략한 해결 방안과 노력의 여정을 남기는.. 기존 방법 reCAPTCHA를
mag1c.tistory.com
상황
Crawler 모니터링 중에, 간헐적으로 NoSuchElementException이 발생했고 빈도수가 점점 증가했다.
이상함을 느낀 나머지 해결을 위해 나섰다(?)
해결
코드 살펴보기
NoSuchElementException은 결국 파싱을 못하는 거니까 cssSelector이나 xpath등의 값을 잘못 입력했나 찾아봤지만 아무리 찾아봐도 보이지 않았음.
눈으로 직접 동작과정 살펴보기
직접 살펴보기위해 ChromeOptions의 headless설정을 꺼버렸다. 도대체 어떤 일이 있는건지 내 눈으로 똑똑히 봐야했다.
![](https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif)
결국 그놈의 reCAPTCHA가 또 발생해, 파싱을 할 수 없는 상황이 되어버렸다.
ChromeOptions 수정하기
아래와 같은 옵션을 추가해주었다.
//자동화된 테스트 소프트웨어에 의해 제어되고 있다는 메세지 제거
options.addArguments("--disable-automation");
처음엔 잘 동작한다고 생각했지만 뭔가 이상해서 Chat - GPT에게 물어봤다. 해당 옵션이 무엇을 뜻하냐고.
그랬더니 메세지를 제거 해 주는 옵션이라는데 단순 메세지 View만 지운다고 해서 웹 서버에서 내 Crawler에서 실행하는 Chrome을 인식을 다르게 할까? 라는 생각을 해봤다. 답은 간단했다. 다른 해결 방안이 필요했다.
최종 방안
Selenium을 사용하여 Chromedriver를 실행할 때, 테스트 모드로 실행되기 때문에 쿠키가 저장되지 않는 일회성 실행이 된다고 한다. 그렇기 때문에 웹 서버에서 이를 봇이라고 인식하고 걸러버린다. 그 때문에 reCAPTCHA 발생 주기가 점점 짧아지지 않나. 라고 생각을 했다. (물론 초초초초초대형 웹사이트를 크롤링하기 때문에, 이런 단편적인 방법으로는 힘들고, 벌써 원활한 크롤링을 위한 로직을 4개 짯는데 단발성 효과만 있음..)
이를 해결하기 위해, selenium에서 동작하는 chrome에도 쿠키를 저장하게 할 필요가 있었고, 아래의 코드로 해결했다.
private static ChromeDriver driverGet() throws IOException{
String chromePath = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe";
String userDataDir = "C:\\chromeCookie";
ProcessBuilder processBuilder = new ProcessBuilder(chromePath, "--remote-debugging-port=9222", "--user-data-dir=" + userDataDir);
processBuilder.start();
WebDriverManager.chromedriver().setup();
ChromeDriverService chromeService = new ChromeDriverService.Builder().usingAnyFreePort().build();
ChromeOptions options = new ChromeOptions();
options.setHeadless(false);
options.addArguments("--disable-notifications");
options.addArguments("--disable-popup-blocking");
options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
ChromeDriver driver = new ChromeDriver(chromeService, options);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
return driver;
}
드라이버 설정을 위한 메서드 전체를 긁어왔기 때문에 거를 부분은 거르고, 축약한 내용은 아래와 같다.
1. ProcessBuilder를 사용하여 Crawler 구동 서버의 원본 chrome의 포트설정을 위해 디버깅 포트 설정(selenium chromedriver 연동을 위해) 및 쿠키 경로를 설정하여 실행
2. ChromeDriverService를 통해 ChromeDriver에 임의의 포트 설정하여 build
3. setExperimentalOption을 통해 앞서 설정했던 포트 설정을 일치시켜 기 실행되어 있는 Chrome과 연동시킴
결론
해결은 정상적으로 되었다. 모니터링 결과, 자동화 된 소프트웨어가 없어진 것을 확인할 수 있으며, ChromeOptions을 조작해 View를 없앤 것이 아닌, 쿠키 설정을 했기 때문에 우선 자동화된 테스트 소프트웨어의 인식은 사라진 것으로 보인다.
웹 서버에서 User-Agent에 특정 제한을 걸어 Selenium과 같은 Crawling Library를 사용하여 접근할 경우 접근을 제한할 수 있게 보안을 강화하거나, IP를 기억해서 제한을 거는 둥 여러 방면으로의 과다 요청이나, 비정상적이라고 판단되는 요청을 제한할 수 있는 것은 알고 있다.
이를 컨트롤하기 위해 직접 NIC도 여러 대 두어 직접 Network Switching도 해보고, User-Agent 제어, 기타 등등 여러 작업을 많이 해 보았지만, 결국 초초초초초초초초초초초초대형 웹 사이트를 우회하는 길은 신입 개발자인 나에겐 너무 어렵지만 좋은 경험이 되고있고 재밌다.
관련 트러블 슈팅
[Java/Selenium] Selenium No Such Element Exception에 대하여. (WebDriverWait)
에러 메세지 및 원인 에러 메세지를 캡처를 못했다.. No Such Element Exception이 발생하며 해당 에러 뒤의 Crawling Data는 전부 Null이 들어왔다. 파싱한 페이지의 Element를 읽어오지 못하는 모양이다. Crawle
mag1c.tistory.com
[Java/Selenium] NoSuchElementException (iframe아님)
에러 메세지 selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method" : "css selector", "selector" : ".gs_citr"} (Session info: chrome=1.2.3.4); 원인 className = gs_citr의 요소를 찾을 수
mag1c.tistory.com
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!