Selenium 크롤링 - Selenium keulolling

BeautifulSoup을 이용한 웹 크롤링을 했을 때, 잘 되지 않는 부분을 해결하기 위해

Selenium을 사용해 크롤링을 해보았다.

BeautifulSoup을 이용한 크롤링 링크 ▼

2022.01.12 - [Web/백엔드] - 웹 크롤링하기

from selenium import webdriver

search_url = "크롤링할 사이트 url"

browser = webdriver.Chrome('크롬드라이버 위치')  # chromedriver 다운받고, 다운 받은 경로 써주어야함
browser.get(search_url)

browser.implicitly_wait(2)

''' 크롤링 코드 '''

browser.close()

이 코드가 틀이되는 코드라고 할 수 있다.

크롬드라이버를 다운받고, 크롤링할 사이트 url를 붙여 넣으면 크롤링할 준비 완료다!

browser.find_element(속성, '속성값')
browser.find_elements(속성, '속성값')

앞으로 이 함수를 사용해 필요한 정보를 크롤링할 것이다.

첫번째는 하나를 찾는 함수고, 두번째는 여러개를 찾는 함수라고 생각하면 된다.

date = browser.find_elements(By.CLASS_NAME, "card_date__1kdC3")

이 코드는 "card_date__1kdC3"라는 클래스 이름을 가진 여러 element들을 찾겠다는 의미가 된다.

이 element들은 배열로 리턴된다. print()해보면 어떤 형식으로 반환되는지 알 수 있다.

클래스 이름 뿐 아니라 id, 태그명 등 다양한 속성이 있기 때문에 필요하면 찾아서 쓰면 될 것 같다!

< 사용 예시 >

Selenium 크롤링 - Selenium keulolling

https://game.naver.com/esports/schedule/lck?date=2022-01 

이 홈페이지에서는 lck의 일정과 결과를 보여준다.

여기서 날짜, 팀1, 팀2, 스코어를 뽑아내려고 한다.

코드를 작성하기 전에 먼저 필요한 데이터를 하나하나 뜯어보자.

Selenium 크롤링 - Selenium keulolling

위와 같은 방식으로 이 정보를 얻을 수 있었다.

날짜 -> div.card_date__1kdC3

팀명 -> span.row_name__IDFHz

스코어 -> span.row_score__2RmGQ

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


search_url = "https://game.naver.com/esports/schedule/lck?date=2022-01"

browser = webdriver.Chrome('c:/chromedriver/chromedriver.exe')  # chromedriver 다운받고, 다운 받은 경로 써주어야함
browser.get(search_url)

browser.implicitly_wait(2)

date = browser.find_elements(By.CLASS_NAME, "card_date__1kdC3")

for i in range(5):
    print(date[i].text)

browser.close()
Selenium 크롤링 - Selenium keulolling

얻은 정보들을 이용해 테스트로 프린트문을 몇개 작성해 보았다.

이런식으로 데이터를 얻을 수 있다는 것을 알았으니 이제 내가 원하는 데이터를 추출해보자

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


search_url = "https://game.naver.com/esports/schedule/lck?date=2022-01"

browser = webdriver.Chrome('c:/chromedriver/chromedriver.exe')  # chromedriver 다운받고, 다운 받은 경로 써주어야함
browser.get(search_url)

browser.implicitly_wait(2)

date = browser.find_elements(By.CLASS_NAME, "card_date__1kdC3")
name = browser.find_elements(By.CLASS_NAME, "row_name__IDFHz")
score = browser.find_elements(By.CLASS_NAME, "row_score__2RmGQ")

for i in range(len(date)):
    k = 4 * i
    for j in range(0,4,2):
        print(date[i].text, name[k + j].text, score[k+j].text, ':', score[k+j+1].text, name[k + j + 1].text)

browser.close()
Selenium 크롤링 - Selenium keulolling

이렇게 내가 원하는 데이터를 뽑았다.

하지만 처음에 그냥 대충 짜본 코드이기 때문에

만약 하루에 경기가 하나이거나 3개 이상이라면 오류가 날 것이다.

그래서 다른 방법을 이용해 크롤링을 하고자 코드를 변경했다.

Selenium 크롤링 - Selenium keulolling

계속 반복되기 때문에 조금 많은 for문을 이용해 데이터를 크롤링하고자했다.

홈페이지를 보면 빨간색 박스가 계속 반복되는 양상을 보이고,

빨간색 박스 안에는 날짜와 경기들이 포함되어 있다.

그리고 두번째 주황색 박스 안에는 각 경기가 있고,

그 각 경기 안에는 경기를 치루는 두 팀의 이름이 명시되어 있다.

그리고 박스의 클래스 명을 구했다.

빨간색 박스 -> card_item__3Covz

주황색 박스1 (날짜) -> card_date__1kdC3

주황색 박스2 (경기들) -> card_list__-eiJk

노랑색 박스 -> row_item__dbJjy

초록색 박스 -> row_name__IDFHz

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


search_url = "https://game.naver.com/esports/schedule/lck?date=2022-01"

browser = webdriver.Chrome('c:/chromedriver/chromedriver.exe')  # chromedriver 다운받고, 다운 받은 경로 써주어야함
browser.get(search_url)

browser.implicitly_wait(2)

oneday = browser.find_elements(By.CLASS_NAME, "card_item__3Covz")

for i in range(len(oneday)):
    date = oneday[i].find_element(By.CLASS_NAME, "card_date__1kdC3").text
    games = oneday[i].find_elements(By.CLASS_NAME, "card_list__-eiJk")

    for j in range(len(games)):
        teams = games[j].find_elements(By.CLASS_NAME, "row_item__dbJjy")

        for k in range(len(teams)):
            team1 = teams[k].find_elements(By.CLASS_NAME, "row_name__IDFHz")[0].text
            team2 = teams[k].find_elements(By.CLASS_NAME, "row_name__IDFHz")[1].text
            print(date, team1, team2)

browser.close()
Selenium 크롤링 - Selenium keulolling

for문을 3번이나 사용하면서 코드를 짜서 너무 복잡했지만,

비슷한 구조를 가졌지만 다른 데이터가 있는 홈페이지의 데이터를 크롤링해도 문제없이 잘 수행되었다.

Selenium 크롤링 - Selenium keulolling
Selenium 크롤링 - Selenium keulolling
2021.03.30 - [파이썬 패키지/웹 크롤링] - [Python/웹 크롤링] 파이썬 웹 크롤링 정적 수집 방법 개념 정리_find, find_all, select, select_one

2021.04.02 - [파이썬 패키지/웹 크롤링] - [Python/Requests/Beautifulsoup] 네이버 뉴스 기사 제목 크롤링을 통한 정적 수집 기초 정리

2021.04.06 - [파이썬 패키지/웹 크롤링] - [Python/Reuqests/Beautifulsoup] 파이썬 정적 웹크롤링 텍스트, 이미지, 하이퍼링크, 속성 가져오는 법

 

[동적 웹크롤링]

2021.04.03 - [분류 전체보기] - [코딩유치원] 네이버 뉴스 기사 제목 크롤링을 통한 동적 수집 기초 정리(selenium, beautifulsoup)

2021.06.21 - [파이썬 패키지/웹 크롤링] - [Python/Selenium] 파이썬 동적 웹크롤링 텍스트, 하이퍼링크, 이미지, 속성 가져오는 법

2021.05.22 - [파이썬 패키지/GUI 프로그램] - [파이썬 GUI 프로그래밍] 잡플래닛 리뷰 정보 크롤링 GUI 프로그램

 


오늘은 Selenium으로 원하는 화면 상태에 도달할 수 있도록 웹 브라우저를 조작 하는 법을 공부해보겠습니다.

 

예를 들어서, 네이버 메일을 확인하기 위해서 로그인 과정을 거쳐야 한다거나, 유튜브 댓글을 모두 크롤링하는데 스크롤을 내려야지 댓글이 추가적으로 업데이트 되는 상황이 있겠죠.

 

이런 상황에서 원하는 버튼을 클릭 하거나 문자를 입력하는 등의 컴퓨터가 해주어야 하는데 이를 Selenium 패키지가 대신 해줄 수 있습니다.

 

쉽게 말해서 웹 브라우저용 매크로랄까요?

 

Selenium으로 화면을 조작하는 전체적인 개념은 다음과 같습니다.


1) 조작을 원하는 버튼이나 입력창의 html을 파악

 

2) 아래의 두 함수에 html 정보를 입력해서 객체(버튼/입력창 등) 선택

  • find_element_by_css_selector( )
  • find_element_by_xpath( )

3) 기능 동작 관련 함수로 원하는 기능 조작

  • 클릭 : .click( )
  • 키 입력: .send_keys( )

원하는 키워드를 검색하는 아주 간단한 예제를 통해서 어떤 방식으로 사용하는지 보여드리겠습니다.

 

1단계. 원하는 버튼의 html 타겟팅

 

가장 먼저 해줄 일은 크롬을 실행해서 F12를 누르는 것 부터 시작합니다.

 

F12를 누르면 지난 강의에서 배우셨 듯이 웹 브라우저 우측에 '개발자 도구'가 나타날 거예요. 그러면 개발자 도구 상단의 화살표 버튼을 눌러서 조작을 원하는 부분을 클릭해주세요.

 

Selenium 크롤링 - Selenium keulolling

 

검색창에 원하는 키워드를 입력하고 앤터를 눌러주는 것이 이번 예제의 목적이므로 검색창을 타겟팅 할 수 있도록 'CSS Selector' 개념을 이용해보겠습니다. CSS Selector 개념을 모르신다면 아래의 글을 참고해주세요.

 

2021.03.27 - [파이썬 패키지/웹 크롤링] - [Python/웹 크롤링] 파이썬 웹 크롤링을 위한 속성 HTML, CSS 요약 정리

 

 

방금 전까지 잘 따라오셨다면 아마 개발자 도구에 '검색창'의 html 부분이 나타나 있을텐데요. 우선 빨간색으로 표시된 class 속성값 부분을 더블클릭해서 복사(Ctrl+c)를 해주세요.

<여기서 잠깐>

class명이 gLFyf gsfi인 input 태그를 선택하려면, input.gLFyf.gsfi라고 입력해주어야 합니다.

1) input 바로 뒤의 점(.)은 class를 나타냄 (id라면 . 대신 #이 들어감) 2) gLFyf 바로 뒤의 점(.)은 띄어쓰기를 의미하며, 띄어쓰기를 모르는 컴퓨터를 위한 것임

 

여기까지 따라오셨다면 이제 코딩창으로 넘어가서 원하는 조작을 수행해 보겠습니다.

 

 

2단계. Selenium으로 타겟팅한 html 찾기

 

그 다음으로 해줄 일은 Selenium의 find_elements_by_css_selector( ) 함수로 위에서 가져온 선택자(input.gLFyf.gsfi)를 ( ) 안에 넣어서 크롬 드라이버가 알아먹을 수 있게 변환해주는 것입니다.

 

그 전에 먼저 관련 모듈을 import 해주고, 구글 드라이버를 이용해 'Google'까지 접속해줍시다. 아래 코드에 주석을 달아두었으니 그리 어렵진 않으실거예요.

 

# selenium의 webdriver를 사용하기 위한 import
from selenium import webdriver

# selenium으로 무엇인가 입력하기 위한 import
from selenium.webdriver.common.keys import Keys

# 페이지 로딩을 기다리는데에 사용할 time 모듈 import
import time

# 크롬드라이버 실행  (경로 예: '/Users/Roy/Downloads/chromedriver')
driver = webdriver.Chrome('chromedriver의 경로를 입력할 것') 

#크롬 드라이버에 url 주소 넣고 실행
driver.get('https://www.google.co.kr/')

# 페이지가 완전히 로딩되도록 3초동안 기다림
time.sleep(3)

 

<여기서 잠깐>

혹시 아직 chromedriver를 설치 안하셨다면 아래의 글을 보시고 설치해주셔야 코드가 정상작동 합니다.

2021.03.23 - [파이썬 패키지/웹 크롤링] - [Python/웹 크롤링] 크롬드라이버 크롬 버전에 맞춰서 설치하는법

 

그리고 chromedriver의 경로를 어떻게 입력해야할지 모르시겠다면 아래의 글을 참고해주세요.

2021.06.05 - [파이썬 기초/기초 문법] - [Python 기초] 파이썬으로 경로와 디렉토리 다루기(feat. 절대 경로와 상대 경로)

 

 

자, 다시 본론으로 돌아와서 find_elements_by_css_selector( ) 함수로 chromedriver가 검색창을 찾을 수 있게 해봅시다.

 

# 검색어 창을 찾아 search 변수에 저장 (css_selector 이용방식)
search_box = driver.find_element_by_css_selector('input.gLFyf.gsfi')

# 검색어 창을 찾아 search 변수에 저장 (xpath 이용방식)
search_box = driver.find_element_by_xpath('//*[@id="google_search"]')

 

갑자기 xpath가 나와서 당황스러우시겠지만 둘 다 같은 결과를 수행하는 코드라는 것을 알아두세요.

 

참고로 xpath는 아까 찾으셨던 html 코드 위에서 '우클릭'을 하신 후, 아래 그림과 같이 'Copy Xpath'를 클릭하시면 클립보드에 //*[@id="google_search"] 라는 xpath가 저장되어 있을거예요. 이걸 위의 코드와 같이 넣어주시면 된답니다.

 

어렵지 않죠? html에 class나 id가 없어 타겟팅 하기 어려운 경우에 자주 사용하니 꼭 알아두시면 좋을 것 같아요!

 

Selenium 크롤링 - Selenium keulolling

 

 

3단계. 원하는 조작 수행

 

여기까지 하셨으면 Chromedriver가 Selenium 패키지의 find_element 함수를 이용해서 원하는 html을 찾은 상태입니다.

 

이제 남은 일은 원하는 조작을 수행하도록 명령 내리는 일입니다.

명령은 간단합니다. 클릭하거나 원하는 키를 입력해주는 것 2가지 입니다.

 

  • 클릭 : .click( )
  • 키 입력: .send_keys( )

<send_keys로 입력 가능한 키 목록>

명령어기능Kyes.ENTER
Keys.RETURN엔터Keys.SPACE스페이스Keys.ARROW_UP
Keys.ARROW_DOWN
Keys.ARROW_LEFT
Keys.ARROW_RIGHT방향키(상하좌우)Keys.BACK_SPACE
Keys.DELETE
지우기 (벡스페이스)
지우기 (딜리트)Keys.CONTROL
Keys.ALT
Keys.SHIFT
Keys.TAB
자주 사용하는 기능키(Ctrl, Alt, Shift, Tab)Keys.PAGE_UP
Keys.PAGE_DOWN스크롤 업
스크롤 다운Keys.F1~9F1 부터 F9 (F+숫자)Keys.EQUALS, Keys.ESCAPE, Keys.HOME, Keys.INSERT기타 등등

 

그럼 간단히 어떻게 코드로 적용할 수 있는지 알아보겠습니다.

 

search_box.send_keys('파이썬')
search_box.send_keys(Keys.RETURN)
time.sleep(1)

 

사용법 역시 정말 간단합니다.

아까 찾았던 검색창(search_box) 변수 다음에 .send_keys('검색어')를 넣어주면 아래와 같은 상태가 되겠죠?

Selenium 크롤링 - Selenium keulolling

 

그 다음에 search_box.send_keys(Keys.RETURN)을 입력해주면 우리가 검색어를 치고 '엔터키'를 입력해주는 것과 동일합니다.

 

참고로 그림에서 Google 검색 버튼을 우리가 했던 방식으로 타겟팅 해주고 .click( ) 함수로 '마우스 클릭' 해주어도 엔터키를 입력한 것과 동일한 결과를 얻을 수 있습니다.