Python

Selenium 사용하여 웹 자동화하기2

왕초보코딩러 2024. 1. 16. 18:23
728x90

 

2024.01.15 - [Python] - Selenium 사용하여 웹 자동화하기1

 

Selenium 사용하여 웹 자동화하기1

셀레니움 설치 및 크롬 웹 드라이버 설치 https://chancoding.tistory.com/136 [파이썬] Selenium 셀레니움 설치하기 / 크롬 드라이버 설치하기 목차 1. Python Selenium 설치하기 다른 라이브러리를 설치하는 것과

dogfoot1.tistory.com

저는 셀레니움 버전 4를 사용하여

버전 4 문법으로 진행합니다

 


셀레니움 라이브러리 임포트

from selenium import webdriver
from selenium.webdriver.common.by import By	#selenium4에서 웹 요소 찾기 위해

 

 

크롬 드라이버 생성 및 사이트 접속

(변수명은 driver로 통일하겠습니다)

driver = webdriver.Chrome('webdriver.exe가 있는 경로')
driver.get('사이트 url')

 

 

https://kimflstudio.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC-selenium-4%EC%85%80%EB%A0%88%EB%8B%88%EC%9B%804-%EC%B5%9C%EC%8B%A0-%EB%B2%84%EC%A0%84-findelement-%EC%82%AC%EC%9A%A9%EB%B2%95-%EB%A7%88%EC%8A%A4%ED%84%B0

 

파이썬 selenium 4(셀레니움4) 최신 버전 find_element 사용법 마스터

파이썬 셀레니움(selenium)은 웹페이지 자동화, 동적 페이지 크롤링, 스크래핑을 할 때 주로 사용합니다. 이 강의에서는 selenium3에서 selenium4로 버전업되며 바뀐 find_element 문법에 대해 설명합니다.

kimflstudio.tistory.com

 


태그 추출 

하나 추출 : find_element()

여러 개 추출 : find_elements()

 

find_element(), find_elements()의 파라미터

By에 여러가지가 있지만 많이 사용할 것 같은 4개만 써두겠습니다.

By.CSS_SELECTOR CSS 선택자를 이용하여 추출
By.CLASS_NAME HTML 태그의 class를 이용하여 추출
By.ID HTML 태그의 id를 이용하여 추출
By.TAG_NAME HTML 태그의 태그명을 이용하여 추출

 

#CSS 선택자를 사용하여 id가 title이고, class가 list_title인 것을 추출
driver.find_elements(By.CSS_SELECTOR, '#title.list_title')

#class가 list_title인 것을 추출
driver.find_elements(By.CLASS_NAME, 'list_title')

#id가 title인 것을 추출
driver.find_elements(By.ID, 'title')

 

 

그 외 By.

https://pythonblog.co.kr/coding/23/

 

find_element By 사용

셀레늄 By 는 소스를 보다 유연하고 유지 관리하기 쉽게 만드는 데 사용할 수 있습니다. 저도 By를 주로 사용합니다. 엘리먼트를 찾는 방법은 find element 사용하기- naver 와 동일합니

python

 

blog.co.kr

 


기다리기

로딩이 될 때까지 시간이 걸릴 수 있기 때문에 다음 코드 작동 전 잠시 텀을 준다

 

1. implicitly_wait(초)

driver.implicitly_wait(sec)

driver 생성 코드 아래 한 번만 쓰면 된다

sec 동안 웹 요소가 있는 지 확인 

find_element(), find_elements()에 모두 적용된다

click(), send_keys()에는 적용이 안된다

 

2. time.sleep(초)

import time

time.sleep(sec)

추가적으로 시간이 더 걸리는 부분에 넣어준다

 

implicitly_wait, sleep 차이

implicitly_wait() : 로드 되면 기다리는 거 멈춤

sleep() : 로드 돼도 계속 기다림

https://balsamic-egg.tistory.com/16

 

[파이썬] driver.implicitly_wait 와 time.sleep 차이점

driver.implicitly_wait(10) 과 time.sleep(10) 의 차이점은 뭘까요? 결론부터 얘기하자면, driver.implicitly_wait(10) : 10초안에 웹페이지를 load 하면 바로 넘어가거나, 10초를 기다림. time.sleep(10) : 10초를 기다림.

balsamic-egg.tistory.com


찾은 HTML 요소에 사용자 입력 넣기

하나의 웹 요소에만 가능하기 때문에 find_elements()에는 사용할 수 없다

 

1. 키보드 입력: 값을 넣는다 : send_keys("값")

#CSS 선택자를 사용하여 class가 input_search인 것을 하나 추출하여 '날씨' 입력
driver.find_element(By.CSS_SELECTOR, '.input_search').send_keys("날씨")

 

 

2. 클릭 : click()

#CSS 선택자를 사용하여 class가 button_search 것을 하나 추출하여 클릭
driver.find_element(By.CSS_SELECTOR, '.button_search').click()

 

 


데이터 추출하기

하나의 웹 요소에만 가능하기 때문에 find_elements()에는 사용할 수 없다

 

1. 텍스트 추출하기: text

#하나면
driver.find_element(By. , '').text

#여러 개면 for문으로
for element in driver.find_elements(By. , ''):
	element.text

 

2. 속성 추출하기: get_attribute()

#하나면
driver.find_element(By. , '').get_attribute('속성')

#여러 개면 for문으로
for element in driver.find_elements(By. , ''):
	element.get_attribute('속성')

 

+

현재 로딩된 웹의 HTML 코드 받아오기

driver.page_source

 

받은 HTML 코드를 이용하여 BeautifulSoup()으로 추출할 수 있다

from bs4 import BeautifulSoup

html_code = driver.page_source

#BeautifulSoup을 이용하여 태그 추출
soup = BeautifulSoup(html_code, 'html.parser')
soup.select()

 


자바스크립트 기능을 이용하여 스크롤 하기

셀레니움에서 자바스크립트 기능 이용하기

driver.execute_script('JS 코드')

 

 

스크롤 해주는 JS 코드

window.scrollTo(x좌표, y좌표);	#가로 축, 세로 축

x좌표에는 0을 쓴다

 

https://developer.mozilla.org/ko/docs/Web/API/Window/scrollTo

 

Window.scrollTo() - Web API | MDN

문서의 지정된 위치로 스크롤합니다.

developer.mozilla.org

 

 

스크롤 길이를 알려주는 JS 코드

document.body.scrollHeight

 

 

JS 코드를 이용하여 끝까지 스크롤 하기

last_height = driver.execute_script('return document.body.scrollHeight')

while True:
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
    
    time.sleep(1)
    
    now_height = driver.execute_script('return document.body.scrollHeight')
    if last_height == now_height:
        break
    last_height = now_height

 


이미지 주소를 이용하여 이미지 다운받기

img_url은 이미지 주소입니다

 

1. open()

import requests

response = requests.get(img_url)
with open('저장할 경로.jpg', 'wb+') as f:
    f.write(response.content)

 

2. urllib.request.urlretrieve()

import urllib.request

urllib.request.urlretrieve(img_url, '저장할 경로.jpg')

 

+

스크린샷

driver.get_screenshot_as_file('저장할 경로')

 


콤보박스 누르기

select 태그를 이용하여 만든 콤보박스를 클릭한다

 

1. 라이브러리 임포트

from selenium.webdriver.support.ui import Select

 

 

2. select 태그 요소를 찾아서 넣어준다

sel_tag = Select(driver.find_element(By.CSS_SELECTOR, 'select 태그를 위한 css 선택자'))

 

 

3. select 태그 안 옵션들 중 선택할 옵션의 정보를 넣어준다

# 콤보박스 항목으로 선택 (웹에서 보이는 옵션 이름)
sel_tag.select_by_visible_text('콤보박스 항목')

# 콤보박스의 value로 선택 (HTML 코드에 보이는 option 태그의 value 속성 값)
sel_tag.select_by_value('value 값')

# 콤보박스의 인덱스로 선택 (0부터 시작)
sel_tag.select_by_index(인덱스번호)

 


+ 추가 기능

#뒤로 가기
driver.back()

#앞으로 가기
driver.forward()

#새로고침
driver.refresh()

#현재 url 가져오기
driver.current_url

 

#윈도우 창 최대화
driver.maximize_window()

#윈도우 창 최소화
driver.minimize_window()

#윈도우 창 크기 조절
driver.set_window_size(가로, 세로)

 


다른 탭으로 가기

링크를 눌러서 여러 탭이 켜져도, 현재 url은 driver.get()으로 받은 탭에 포커스 되어 있다 

 

탭 리스트

#탭 리스트
driver.window_handles

print(driver.window_handles)	#리스트로 리턴됨

driver.window_handles[i]로 원하는 탭을 얻을 수 있다

 

i번째 탭으로 가기(0부터 시작) : driver.switch_to.window()

driver.switch_to.window(driver.window_handles[i])

 

탭 닫기

driver.close()

 

 

네이버의 카페, 블로그, 쇼핑 탭 열고 닫기

driver = webdriver.Chrome()
driver.implicitly_wait(3)

driver.get('https://naver.com')	#main tab

#카페, 블로그, 쇼핑 탭
new_links = driver.find_elements(By.CSS_SELECTOR, 'li.shortcut_item')[1:4]  
for link in new_links:
    link.click()
    #다른 탭으로 이동
    driver.switch_to.window(driver.window_handles[1])
    time.sleep(2)

    #카페, 블로그, 쇼핑 순으로 사이트 url 출력
    print(driver.current_url)
    #탭 닫기
    driver.close()
    #main tab으로 이동
    driver.switch_to.window(driver.window_handles[0])

 

 

 

출력 결과: 카페->블로그->쇼핑 순의 url 출력 


크롬 드라이버 종료

driver.quit()