Selenium으로 크롤링이나 테스트를 자동으로 돌릴 때, 매번 크롬 창이 눈앞에 뜨면 거슬리고 화면 없는 서버에서는 아예 못 돌립니다. 크롬 60 버전부터는 창을 띄우지 않고 백그라운드로만 실행하는 Headless 모드를 지원해서, ChromeOptions 에 인자 몇 개만 넣으면 됩니다.
Dim chromeOptions As New ChromeOptions()
chromeOptions.AddArgument("--headless") '// Headless모드
chromeOptions.AddArgument("--window-size=1920x1080")
chromeOptions.AddArgument("--disable-gpu") '// gpu(그래픽카드 가속)를 사용하지 않음
chromeOptions.AddArgument("--user-agent=" & USER_AGENT)
iWD = New ChromeDriver(service, chromeOptions, TimeSpan.FromSeconds(30))
인자 하나씩
--headless: 창 없이 실행합니다. 이게 Headless 모드를 켜는 핵심 인자입니다.--window-size=1920x1080: 가상 브라우저의 크기를 지정합니다. Headless에서 이걸 빼면 창 크기가 기본값(작게)으로 잡혀서, 반응형 페이지가 모바일 레이아웃으로 뜨거나 요소가 화면 밖에 있어 클릭이 안 되는 일이 생깁니다. 그래서 거의 필수로 넣습니다.--disable-gpu: GPU 가속을 끕니다. 예전 윈도우에서 Headless와 GPU가 같이 쓰일 때 오류가 나던 걸 피하려는 인자인데, 지금은 없어도 대부분 돌아갑니다. 관례처럼 같이 넣는 경우가 많습니다.--user-agent=...: User-Agent 문자열을 바꿉니다. Headless 크롬은 기본 User-Agent에HeadlessChrome이 들어가서 자동화인 게 티가 나는데, 일반 크롬 값으로 바꿔 두면 그 부분은 가려집니다.
마지막 줄에서 이 옵션과 드라이버 서비스, 타임아웃(30초)을 넘겨 ChromeDriver 를 만듭니다. 타임아웃은 명령 하나가 응답을 기다리는 한도입니다.
Headless인 걸 숨기는 문제
원문에도 언급돼 있듯이, Headless는 서버에서 크롤링·테스트를 돌릴 수 있게 해 주는 좋은 기능이지만 서버 쪽에서 Headless 여부를 감지하는 방법이 여럿 있습니다. User-Agent 외에도 navigator.webdriver 값이 true 인지, 플러그인·언어 목록이 비어 있는지, WebGL 렌더러 정보가 비정상인지 같은 걸로 자동화 브라우저를 구분합니다. User-Agent만 바꿔서는 다 가려지지 않는다는 뜻입니다.
쓸 때 참고
여기 쓰인 --headless 는 구형 플래그입니다. 크롬 109 이후로는 실제 크롬과 거의 같게 동작하는 새 모드가 들어와서, 요즘은 chromeOptions.AddArgument("--headless=new") 를 권장합니다. 구형 Headless는 일부 사이트에서 화면과 다르게 렌더링되거나 특정 기능이 빠져 있어서, 화면으로 볼 때는 되는데 Headless에서만 안 되는 증상이 나면 이 모드 차이를 먼저 의심해 보세요.
개발 중에는 --headless 를 빼고 창을 띄운 채로 돌리면서 동작을 눈으로 확인하고, 다 되면 그때 Headless를 켜는 순서가 디버깅에 편합니다. 그리고 서버에서 돌릴 때는 설치된 크롬 버전과 ChromeDriver 버전이 맞아야 하니, 드라이버를 버전에 맞춰 두거나 자동으로 맞춰 주는 방식을 같이 쓰는 게 좋습니다.