selenium : 웹 어플리케이션을 테스트하기 위해 고안된 프레임워크
requests 라이브러리로 웹 정보를 받고 BeautifulSoup를 사용해서 파싱하는 방식도 있지만, 로그인이나 클릭, 혹은 스크롤과 같은 동적인 웹 컨트롤이 필요한 경우 selenium을 사용한다.
하지만, selenium의 경우 시간과 비용이 많이 들기 때문에 동적인 웹 컨트롤이 필요하지 않은 경우에는 requests와 BeautifulSoup를 활용하는 것이 더 유리하다.
또한 selenium과 BeautifulSoup를 동시에 활용하는 것도 시간과 비용의 문제를 해결하기에 적합하다는 사실!
chromedriver : chrome 브라우저를 제어하기 위한 드라이버
selenium을 사용하기 위해서는 chrome driver을 다운받아서 사용해야 한다. https://chromedriver.chromium.org/downloads 에서 다운로드가 가능하지만 python 코드를 활용해서 이 과정을 자동화 할 수 있다.
!pip install selenium
!apt-get update
!apt install chromium-chromedriver
# !cp /usr/lib/chromium-browser/chromedriver '/content/drive/MyDrive/Colab Notebooks' # (최초 1회)
!pip install chromedriver-autoinstaller
from selenium import webdriver
driver = webdriver.Chrome() # driver 경로를 파일경로와 같은 곳에 둘 경우
driver = webdriver.Chrome('driver path') # driver 경로를 파일경로와 다른 곳에 둘 경우
url = 'https://www.google.com'
driver.get(url)
위와 같이 chrome browser을 화면에 직접 띄우고 눈으로 과정을 확인하면서 작업하는 방법도 있지만, 지금부터 작성할 코드는 화면을 띄우지 않고 진행할 것이라는 점을 명심하길 바란다.
from selenium import webdriver
import chromedriver_autoinstaller
import sys
# chrome_path를 시스템 경로에 추가
chrome_path = "/content/drive/MyDrive/Colab Notebooks/chromedriver"
sys.path.insert(0,chrome_path)
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless') # 창을 띄우지 않는 Headless 모드
chrome_options.add_argument('--no-sandbox') # 샌드박스 모드 비활성화
chrome_options.add_argument('--disable-dev-shm-usage') # 메모리 문제 제거
chrome_options.add_argument('lang=ko_KR') # 한국어
chrome_options.add_experimental_option("excludeSwitches", ["enable-logging"]) # 불필요한 에러메시지 노출 방지
...
chromedriver_autoinstaller.install() # Chromedriver 다운로드
driver = webdriver.Chrome(options=chrome_options)
url = 'https://www.google.com'
driver.get(url)
위와 같이 chromedriver의 기본적인 설정 및 준비가 끝나면 기존에 requests를 활용했던 것과 동일하게 크롤링이 가능하다. BeautifulSoup를 활용한 파싱 이후로는 requests를 활용했던 것과 동일하지만, response.text 대신에 driver.page_source를 파싱해야 한다는 사실!
from bs4 import BeautifulSoup
import re
html = driver.page_source # response.text와 같은 역할
soup = BeautifulSoup(html, 'html.parser') # BeautifulSoup를 활용한 파싱
div_list = soup.find_all("div", attrs={"class" : re.compile("className")})
...
버튼 클릭, 텍스트 입력, 로그인, 스크롤 등 다양한 동적 웹 컨트롤을 구현할 수 있다.
Example 1 : 버튼 클릭
from selenium.webdriver.common.by import By target = driver.find_element(By.XPATH, '//*[@id="content"]/div[2]/div/button') target.click()
Example 2 : 텍스트 입력
from selenium.webdriver.common.by import By target = driver.find_element(By.ID, 'loginForm') target.send_keys("abc123!")
Example 3 : 로그인
from selenium.webdriver.common.by import By url = "https://nid.naver.com/nidlogin.login?mode=form&url=https://www.naver.com/" driver.get(url) entry_ID = driver.find_element(By.XPATH, '//*[@id="id"]') entry_ID.send_keys("ID123") entry_PW = driver.find_element(By.XPATH, '//*[@id="pw"]') entry_PW.send_keys("pswd123!") btn = driver.find_element(By.XPATH, '//*[@id="log.login"]') btn.click()
Example 4 : 스크롤 움직이기
driver.execute_script("window.scrollTo(0, 700)")
- execute_script() : 자바스크립트 동작
그 외에 버튼 누르기, 특정 위치로 focus 이동하기 등 다양한 동적 웹 컨트롤이 가능하다.
+ By 활용법
from selenium.webdriver.common.by import By driver.find_element(By.XPATH, '//button') driver.find_element(By.ID, 'loginForm') driver.find_element(By.LINK_TEXT, 'Continue') driver.find_element(By.PARTIAL_LINK_TEXT, 'Conti') driver.find_element(By.NAME, 'username') driver.find_element(By.TAG_NAME, 'h1') driver.find_element(By.CLASS_NAME, 'content') driver.find_element(By.CSS_SELECTOR, 'p.content')