파이썬 셀레니움 웹 크롤링 기초 움직이는 사이트도 긁어오는 자동화 비법
데이터 수집이나 업무 자동화에 관심 있는 분들이라면 ‘웹 크롤링’이라는 단어, 한 번쯤 들어보셨을 거예요. 보통 파이썬으로 크롤링을 처음 시작하면 뷰티풀숩(BeautifulSoup)이라는 라이브러리를 많이 접하게 되죠. 그런데 이걸로 열심히 코드를 짰는데, 막상 실행해보면 텅 빈 결과만 나와서 당황했던 경험 없으신가요? 분명 브라우저에서는 데이터가 보이는데 코드로 긁으면 안 나오는 그 상황, 저도 처음엔 정말 답답했거든요.
이게 다 요즘 웹사이트들이 사용자와 상호작용하기 위해 자바스크립트라는 기술을 많이 써서 그래요. 페이지가 로딩된 후에 데이터가 추가로 뜨거나, 버튼을 클릭해야만 정보가 나오는 동적인 사이트들이 많아졌거든요. 바로 이럴 때 필요한 강력한 도구가 오늘 소개할 ‘셀레니움(Selenium)’입니다. 정적인 페이지만 가져오는 뷰티풀숩과 달리, 셀레니움은 실제 브라우저를 띄워서 사람처럼 클릭도 하고 스크롤도 내리면서 데이터를 가져올 수 있는 마법 같은 도구죠.
셀레니움이 도대체 뭔가요
쉽게 말해 셀레니움은 ‘웹 브라우저 원격 제어기’라고 생각하면 이해가 빨라요. 우리가 크롬이나 엣지 브라우저를 켜서 마우스로 클릭하고 키보드로 검색어를 입력하는 과정을 파이썬 코드로 대신해주는 거죠. 원래는 웹사이트 개발자들이 버그가 없는지 테스트하기 위해 만든 도구인데, 이게 워낙 강력하다 보니 크롤링용으로 더 많이 쓰이고 있더라고요.
뷰티풀숩과 셀레니움은 각각 장단점이 뚜렷해요. 상황에 맞춰서 골라 쓰는 게 고수의 방법이죠. 아래 표를 보면 차이가 확 느껴질 거예요.
| 비교 항목 | 뷰티풀숩 (BeautifulSoup) | 셀레니움 (Selenium) |
|---|---|---|
| 작동 방식 | HTML 문서만 요청해서 분석 | 실제 브라우저를 실행해서 제어 |
| 속도 | 매우 빠름 | 브라우저 구동 때문에 상대적으로 느림 |
| 동적 페이지 | 처리 불가능 (자바스크립트 미실행) | 완벽 지원 (클릭, 스크롤 가능) |
| 난이도 | 쉬움 | 설정할 게 좀 있어서 중간 정도 |
| 주 용도 | 뉴스 기사, 단순 정보 수집 | 로그인 필요 사이트, 지도, 쇼핑몰 |
표를 보니까 감이 좀 오시나요? 단순히 텍스트만 있는 뉴스 사이트라면 뷰티풀숩이 낫지만, 인스타그램이나 네이버 지도처럼 뭔가 움직임이 많은 곳은 셀레니움이 필수입니다.
환경 설정과 설치부터 시작해요
자, 그럼 본격적으로 시작해볼까요? 일단 파이썬은 설치되어 있다고 가정할게요. 터미널이나 커맨드 프롬프트(CMD)를 열고 셀레니움 라이브러리를 설치해야 해요. 명령어는 아주 간단합니다.
pip install selenium
예전에는 브라우저 버전에 맞는 ‘드라이버’라는 걸 일일이 다운로드해서 경로 설정하고 난리도 아니었어요. 버전 안 맞으면 에러 나고 정말 골치 아팠거든요. 근데 최근 셀레니움 4 버전부터는 이런 과정이 획기적으로 줄어들었어요. 코드를 실행하면 알아서 적절한 드라이버를 찾아주니까 진짜 편해졌죠.
그리고 크롤링을 할 때 가장 많이 쓰는 브라우저가 크롬인데요, 코드를 짤 때 webdriver 모듈을 불러와서 브라우저를 여는 것부터가 시작이에요. 브라우저가 딱 켜지는 순간, 내가 코딩한 대로 컴퓨터가 움직이는 걸 보면 꽤 짜릿한 기분이 듭니다.
원하는 데이터 콕 집어내기
브라우저를 열었으면 이제 우리가 원하는 데이터가 어디에 있는지 파이썬에게 알려줘야겠죠? 이걸 ‘요소 찾기(Locating Elements)’라고 해요. 웹페이지는 HTML이라는 뼈대로 이루어져 있는데, 여기서 특정 버튼이나 텍스트를 찾아내는 방법은 여러 가지가 있어요.
가장 많이 쓰는 건 By.ID, By.CLASS_NAME, By.CSS_SELECTOR 같은 것들이에요. 예를 들어 로그인 버튼에 ‘login-btn’이라는 ID가 있다면, 셀레니움한테 “야, ID가 login-btn인 녀석 좀 찾아봐”라고 시키는 거죠. 요즘은 By.XPATH도 많이 쓰는데, 이건 문서 내의 정확한 주소를 찍어주는 거라 복잡한 구조에서 원하는 걸 찾아낼 때 정말 유용합니다.
데이터를 찾았다면 이제 액션을 취할 차례예요. .click()을 하면 클릭을 하고, .send_keys("검색어")를 하면 검색창에 글자를 입력해요. 심지어 .text를 쓰면 그 안의 글자만 쏙 뽑아올 수도 있죠. 이 기능들을 조합하면 로그인해서 메일함을 확인하거나, 쇼핑몰 장바구니에 물건을 담는 것까지 자동화할 수 있답니다.
기다림의 미학, 웨이트(Wait)가 핵심
여기서 초보자들이 제일 많이 하는 실수가 있어요. 바로 ‘기다려주지 않는 것’입니다. 사람은 인터넷이 좀 느리면 화면이 뜰 때까지 멍하니 기다리잖아요? 근데 컴퓨터는 성격이 엄청 급해요. 페이지 이동 명령을 내리자마자 바로 다음 줄에 있는 “데이터 가져와!” 명령을 실행해버리죠. 아직 페이지는 로딩 중인데 말이에요. 당연히 “그런 요소 없는데요?” 하면서 에러를 뱉어냅니다.
이걸 해결하려면 ‘웨이트(Wait)’ 기능을 써야 해요. 크게 두 가지 방법이 있는데, 하나는 time.sleep(3)처럼 무조건 3초를 기다리는 방법이에요. 쉽긴 한데, 1초 만에 로딩이 끝나도 3초를 다 채워서 기다리니까 시간이 아깝죠. 반대로 5초 걸리면 에러가 나고요.
그래서 전문가들은 ‘Explicit Wait(명시적 대기)’를 주로 씁니다. “특정 요소가 화면에 나타날 때까지만 기다려, 근데 최대 10초까지만 봐줄게”라고 똑똑하게 명령하는 방식이죠. 이게 코드 효율도 높이고 에러도 확 줄여주는 핵심 비법이에요. 저도 처음엔 귀찮아서 time.sleep만 쓰다가, 데이터 양이 많아지면서 속도 차이가 엄청나게 벌어지는 걸 보고 바로 갈아탔습니다.
마치며
셀레니움은 처음 세팅만 잘 해두면 정말 든든한 지원군이 되어줍니다. 매일 아침 경쟁사 가격 조사를 하거나, 보고서에 쓸 통계 자료를 모으는 단순 반복 업무에서 해방될 수 있거든요. 물론 사이트 구조가 바뀌면 코드도 수정해야 하는 번거로움은 있지만, 그만큼 얻는 시간적 여유가 크니까요. 오늘 알려드린 내용 바탕으로 작은 프로젝트부터 하나씩 시작해보세요. 내 손으로 만든 봇이 열심히 일하는 모습을 보면 꽤나 뿌듯하실 겁니다.



