jjinyeok 성장일지

웹크롤링 # 4 Selenium - 2022/08/03~2022/08/05 본문

[KT AIVLE School]

웹크롤링 # 4 Selenium - 2022/08/03~2022/08/05

jjinyeok 2022. 8. 14. 21:49

1. Selenium이란?

  브라우저 자동화 목적으로 만들어진 다양한 브라우저와 프로그래밍 언어를 지원하는 라이브러리이다. 브라우저를 파이썬 코드로 직접 컨트롤해서 브라우저에 있는 데이터를 수집하는 방식으로 크롤링을 진행할 수 있다. requests 패키지를 이용하여 서버에 요청을 보낼때 그 요청은 당연하게도 브라우저에서 보내는 요청이 아니다. 경우에 따라 이런 요청은 서버에서 거절하기도 한다. 그러나 Selenium은 직접 브라우저를 컨트롤하기 때문에 이러한 경우를 방지할 수 있다. 그러나 브라우저를 직접 컨트롤하는 만큼 속도가 느리기 때문에 requests 패키지를 이용하여 크롤링이 가능하다면 requests를 패키지를 이용하는 것이 속도적으로 더 좋은 방법이다.

Selenium

2. 환경설정

  크롬 브라우저를 통해 Selenium 크롤링을 진행하기 위해서 선행작업이 필요하다.

  1. 크롬 브라우저 설치

  2. 사용하는 크롬 브라우저 버전에 맞는 크롬 드라이버 다운로드
  https://chromedriver.chromium.org/downloads 

  위 URL에서 본인이 사용하는 OS와 크롬 브라우저 버전에 맞는 크롬 드라이버를 다운로드하고 크롬 드라이버를 파이썬 실행 파일과 같은 위치에 놓는다.

 

ChromeDriver - WebDriver for Chrome - Downloads

Current Releases If you are using Chrome version 105, please download ChromeDriver 105.0.5195.19 If you are using Chrome version 104, please download ChromeDriver 104.0.5112.79 If you are using Chrome version 103, please download ChromeDriver 103.0.5060.13

chromedriver.chromium.org

  3. Selenium 패키지 설치

pip install selenium

 

3. Selenium 메서드

  Selenium으로 크롤링을 진행하기 전에 간단한 메서드를 정리하겠다. 메서드를 사용하기 앞서 webdriver 모듈과 Selector를 위한 By 클래스를 import한다.

from selenium import webdriver
from selenium.webdriver.common.by import By

  브라우저 띄우기

  webdriver의 Chrome 클래스를 선언하여 브라우저를 띄울 수 있다. 크롬 뿐만 아니라 엣지, 사파리, 파이어폭스 등 다른 브라우저도 띄울 수 있다.

# 브라우저 띄우기
driver = webdriver.Chrome()

  페이지 이동하기

  선언한 드라이버 객체에 get() 메서드에 url을 입력하여 페이지를 이동할 수 있다.

# 페이지 이동하기
driver.get('https://google.com')

  브라우저 사이즈 조정하기

  드라이버 객체에 set_window_size() 메서드를 사용해 띄워진 브라우저의 사이즈를 조절하는 것이 가능하다. 메서드 내부의 파라미터는 width와 height로 너비와 높이를 조정한다.

# 브라우저 사이즈 조정
driver.set_window_size(200, 600)

  JavaScript 코드 실행하기

  드라이버 객체에 execute_script() 메서드를 사용해 자동으로 JS 코드를 실행하는 것 또한 가능하다. 내부 파라미터로 JS 코드 형식의 문자열을 입력하면 브라우저에서 JS 코드가 실행된다. execute_script() 메서드를 이용해서 브라우저의 스크롤을 조절하거나 경고창을 다룰 수 있다.

# 브라우저 스크롤 조절
driver.execute_script('window.scrollTo(200, 300)')

# alert창 다루기
driver.execute_script('alert("hello selenium")')

  Element에 Event 실행하기

  브라우저의 페이지에 있는 Element를 CSS Selector를 활용하여 선택하고 선택한 Element에 클릭과 글자 입력과 같은 Event를 실행할 수 있다. 구글 개발자 콘솔을 이용하여 Element의 CSS Selector 값을 알아낸 후 사용하면 간단하다. CSS Selector 뿐만 아니라 By.XPATH, By.ID와 같은 By 클래스의 다른 변수들을 통해 활용해 XPath, id 등을 통한 Element 선택도 가능하다. Element를 추출하는 방법은 find_element() 메서드를 통해 가장 앞에 있는 Element 하나를 추출하는 방법과 find_elements() 메서드를 통해 Selector 조건과 일치하는 Element들을 모두 추출하는 방법이 존재한다.

# 검색어 입력창에 문자열 입력하기
driver.find_element(By.CSS_SELECTOR, 'input.gLFyf').send_keys('파이썬')
# 검색 버튼 클릭하기
driver.find_element(By.CSS_SELECTOR, 'div.FPdoLc.lJ9FBc input.gNO89b').click()

  브라우저 종료하기

  driver 객체에 quit() 메서드를 사용해서 브라우저를 종료할 수 있다.

# 브라우저 종료하기
driver.quit()

 

  4. Selenium을 통해 데이터 크롤링하기

  TED 사이트의 데이터를 Selenium을 통해 크롤링하는 예시로 정리하겠다. 추가적으로 라우저 내에서 클릭 이벤트 발생 이후 새로운 데이터를 가져오는 과정이 존재한다. 이때 sleep() 함수를 통해 대기하지 않는다면 브라우저는 아직 새로운 데이터를 응답받지 못한 상황이 된다. 따라서 일치하는 Element들을 찾지 못하고 빈 리스트를 반환하는 에러가 날 수 있음에 유의하자.

from selenium import webdriver
from selenium.webdriver.common.by import By
import pandas as pd
from time import sleep

# 브라우저 띄우기
driver = webdriver.Chrome()

# Ted 페이지로 이동
driver.get('https://ted.com/talks')

# 언어 select Element에서 한국어 select Element 선택 -> 클릭
driver.find_element(By.CSS_SELECTOR, '#languages [lang="ko"]').click()

# 클릭 후 새로운 데이터를 가져오는데 시간이 필요함 -> sleep 함수를 사용해 대기
sleep(1)

# class가 media__message인 Element들을 가져와 저장
elements = driver.find_elements(By.CSS_SELECTOR, '.media__message')

# Element들에서 title과 link를 꺼내 딕셔너리의 리스트 형태로 저장
data = []
for element in elements:
    data.append({
        'title': element.find_element(By.CSS_SELECTOR, 'h4 .ga-link').text,
        'link': element.find_element(By.CSS_SELECTOR, 'h4 .ga-link').get_attribute('href'),
    })

# data를 DataFrame 형식으로 변환
df = pd.DataFrame(data)

# DataFrame 출력
print(df.head())
#                                              title                                               link
# 0                 스페인어의 역사 - 일란 스타반스(Ilan Stavans)  https://www.ted.com/talks/ilan_stavans_a_brief...
# 1                             암흑 물질의 수수께끼를 해결하는 방법  https://www.ted.com/talks/chanda_prescod_weins...
# 2                              알코올은 어떻게 숙취를 일으킬까요?  https://www.ted.com/talks/judy_grisel_how_does...
# 3                               가장 살기 좋은 나라는 어디일까?  https://www.ted.com/talks/ted_ed_what_s_the_be...
# 4  높은 고도가 당신의 몸에 미치는 영향 - 앤드류 러버링(Andrew Lovering)  https://www.ted.com/talks/andrew_lovering_how_...

# 브라우저 종료
driver.quit()

 

  5. Headless

  AWS를 통해 리눅스에 서버를 띄우다 보면 리눅스 서버는 화면이 없다는 것을 알 수 있다. 이럴 때는 Selenium을 어떻게 써야할까? 이때 Headless 방법을 이용한다. Headless란 브라우저를 화면에 띄우지 않고 메모리 상에서만 실행하여 크롤링하는 방법이다. 화면이 지원되지 않는 리눅스 서버 환경과 같은 곳에서 사용하기 유용하다. 다만 크롬에서는 60 이상의 버전에서만 지원한다는 것에 유의하자. ChromeOptions 객체를 통해 headless argument를 주고  브라우저를 띄우는 과정에 options parameter로 ChromeOptions 객체를 입력하는 방식이다. 과정은 아래와 같다. 화면 상에는 브라우저가 띄워지지 않지만 메모리 상에서는 브라우저를 실행하고 있다. 따라서 크롤링에 걸리는 시간은 똑같다. Headless는 시간을 줄이기 위해 사용하는 방법이 아님에 유의하자.

from selenium import webdriver
from selenium.webdriver.common.by import By

# ChromeOptions 클래스 선언
options = webdriver.ChromeOptions()
# options 객체에 headless argument 추가
options.add_argument('headless')

# 브라우저를 띄울 때 옵션 parameter에 headless를 추가한 ChromeOptions 객체 입력
driver = webdriver.Chrome(options=options)

driver.get('https://ted.com/talks')
sub_title = driver.find_element(By.CSS_SELECTOR, '#banner-secondary').text
driver.quit()

print(sub_title)
# Join TED Recommends to get the best ideas, selected just for you

 

  사실 졸업 프로젝트를 진행하는 과정에서 공부했었던 내용이지만 강의를 통해서 Selenium을 배우니 정신 없이 알고 있던 내용이 하나로 정리되는 느낌을 받았다. 시간 관계상 강의에서 많은 시간이 할애된 부분은 아니었지만 Selenium으로 할 수 있는게 무궁무진하다는 것을 알고 있었기 때문에 더 집중해서 들을 수 있었다. 어서 프로젝트를 진행하며 배운 크롤링 기법들을 사용하고 싶다. 기대가 된다.

Comments