웹 자동화

사람이 일반적으로 웹 브라우저를 이용해 수행하는 작업을 자동화 시킨 것.
->반복적인 작업을 자동화하여 생산성을 향상시킬 수 있다.
e.g.) 웹 개발, 데이터 수집, 테스트 자동화

동적 크롤링 & 정적 크롤링

정적 크롤링:

  • 웹 페이지의 소스 코드에 표시된 정적 데이터만을 수집
  • html 소스에서 원하는 데이터를 추출
    -> javascript로 생성되는 데이터는 수집 불가!

동적 크롤링:

  • javascript와 같은 동적 콘텐츠를 실행하고 해당 데이터를 가져오는 방식
  • 입력, 클릭, 로그인, 페이지 생성 등을 통해 데이터가 바뀌는 것 = 동적 데이터
    -> 정적 크롤링보다 느림

selenium

  • 웹 애플리케이션의 테스트를 자동화하거나, 웹 사이트에서 데이터를 크롤링할 때 사용되는 파이썬 라이브러리.
  • 사용자가 웹 브라우저를 조작하는 것과 유사한 방식으로 웹 페이지의 요소 클릭, 텍스트 입력, 페이지 간의 이동을 수행하며 결과를 확인할 수 있음.
  • 동적으로 html 소스가 생성되는 경우 requests를 사용할 수 없기 때문에 selenium으로 보완 가능.
    e.g. 스크롤했을 때 데이터가 생성되는 경우, URL 주소는 동일한데 데이터가 변경되는 경우

selenium의 사용

selenium의 설치:
(처음에만) pip install selenium

selenium 업그레이드:
(selenium이 이미 있다면) pip install --upgrade selenium

webdriver_manager 설치:
pip install webdriver_manager

selenium의 실행

chrome이나 Edge 브라우저로 열기
-> 해당 브라우저에 맞는 드라이버를 사용해야 한다!

<브라우저 별 드라이버 사용 예시 코드>

from selenium import webdriver

driver = webdriver.Chrome() # chrome 브라우저 실행
#driver = webdriver.Edge() # Edge 브라우저 실행

driver.get("https://naver.com") # URL로 이동

print(driver.title) #페이지 제목 출력
#driver.quit() # 브라우저 닫기
input("대기 : " ) # 브라우저가 자동으로 빨리 닫히는 걸 방지하기 위해 입력 대기

webdriver_manager의 활용
-> 브라우저 버전에 맞는 드라이버를 자동으로 다운 & 설정
-> 드라이버 경로를 수동으로 지정할 필요가 없음
-> 브라우저 업데이트 시, 적합한 최신 드라이버를 자동으로 가져옴

+) 문제는... 나의 경우 해당 코드를 실행했음에도 불구하고 크롬의 최신 드라이버가 자동으로 설정되지 않았다는 점이다. 때문에 나는 수동으로 직접 크롬 드라이버를 다운받고 경로를 지정해줘야 했다.

<예시 코드>

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
#Edge를 사용하는 경우
#from webdriver_manager.microsoft import EdgeChromiumDriverManager
#from selenium.webdriver.edge.service import Service

#ChromeDriver 자동 설치 및 설정
#service = Service(ChromeDriverManager().install())
#service = Service("C:/Users/HOME/Downloads/chromedriver-win64/chromedriver-win64/chromedriver.exe")
#-> 해당 코드가 실행되지 않아서 직접 다운받고 경로를 새로 지정해주었다
service = Service("C:/Users/HOME/Downloads/chromedriver-win64/chromedriver-win64/chromedriver.exe")
driver = webdriver.Chrome(service = service)

#EdgeDriver 자동 설치 및 설정
#service = Service(EdgeChromiumDriverManager().install())
#driver = webdriver.Edge(service = service)

#웹 페이지 열기
driver.get("https://www.google.com")

#브라우저 닫기
#driver.quit()

selenium 메서드

<브라우저 제어 메소드>

get(url): 지정된 URL로 브라우저를 이동
close(): 현재 탭을 닫음
quit(): 전체 브라우저를 종료
refresh(): 현재 페이지를 새로 고침
maximize_window(): 브라우저 창을 최대화
minimize_window(): 브라우저 창을 최소화
back(): 브라우저에서 이전 페이지로 이동
forward(): 브라우저에서 다음 페이지로 이동

<웹 요소 찾기>

find_element(by, value) : 지정된 위치에서 첫번째 요소를 찾음
find_elements(by, value) : 지정된 위치에서 모든 요소를 리스트로 반환

->요소 찾는 방식
By.ID: ID로 요소 찾기
By.NAME: Name 속성으로 찾기
By.CLASS_NAME: 클래스 이름으로 찾기
By.TAG_NAME: 태그 이름으로 찾기
By.CSS_SELECTOR: CSS 선택자로 찾기
By.XPATH: XPath로 찾기

<웹 요소 상호작용>

click(): 요소를 클릭
send_keys(keys): 입력 상자에 텍스트를 입력
clear(): 입력 상자의 기존 텍스트를 삭제
is_displayed(): 요소가 페이지에 표시되어있는지 여부 확인
is_enabled(): 요소가 활성화 되어있는지 여부 확인
is_selected(): 체크박스 또는 라디오 버튼이 선택되었는지 확인
get_attribute(attribute): 요소의 특정 속성 값을 반환
+) 이미지 등 정적인 것을 가져올 때. e.g. get_attribute("src")
get_property(property): 요소의 특정 속성(property)을 반환
+) 자바 스크립트로 된 동적인 것들
text: 요소 내부의 텍스트를 반환
submit(): 폼(form)을 제출

send_keys(키값)

Keys.ENTER: 엔터 키 (e.g. send_keys(Keys.ENTER))
Keys.RETURN: 리터 키 (e.g. send_keys(Keys.RETURN))
Keys.TAB: 탭 키 (e.g. send_keys(Keys.TAB))
Keys.ESCAPE: esc 키 (e.g. send_keys(Keys.ESCAPE))
Keys.BACKSPACE: 백스페이스 키 (e.g. send_keys(Keys.BACKSPACE))
Keys.DELETE: 삭제 키 (e.g. send_keys(Keys.DELETE))
Keys.SHIFT: 쉬프트 키 (e.g. send_keys(Keys.SHIFT + "A"))
Keys.CONTROL: 컨트롤 키 (e.g. send_keys(Keys.CONTROL + "a"))
Keys.ARROW_UP: 위 방향 화살표 키 (e.g. send_keys(Keys.ARROW_UP))
Keys.ARROW_DOWN: 아래 방향 화살표 키 (e.g. send_keys(Keys.ARROW_DOWN))
Keys.F1~F12: F1~F12 키 (e.g. send_keys(Keys.F5))
Keys.SPACE: 스페이스 키 (e.g. send_keys(Keys.F5))

브라우저 상태 및 정보

title: 현재 페이지의 제목(title)을 반환
current_url: 현재 url을 반환
page_source: 현재 페이지의 HTML 소스를 반환
window_handles: 열려 있는 모든 창(탭)의 handle ID를 리스트로 반환
current_window_handle: 현재 활성 탭의 handle ID를 반환

스크롤 및 뷰 제어

execute_script(자바 스크립트): 자바 스크립트를 실행
set_window_size(width, height): 브라우저 창 크기를 설정

프레임, 팝업 창, 또는 알림 창과 상호작용

switch_to.frame(프레임): 지정된 프레임으로 포커스 이동
switch_to.default_content(): 프레임에서 기본 컨텐츠로 포커스 이동
switch_to.alert: 알림창으로 포커스 이동

요소 로드나 특정 조건 충족까지 대기

implicitly_wait(시간): 모든 요소를 찾기 전까지 지정된 시간만큼 암시적으로 대기
WebDriverWait(driver, timeout): 특정 조건이 충족될 때까지 명시적으로 대기

스크린샷

save_screenshot(file_path): 현재 브라우저 화면을 이미지로 저장
get_screenshot_as_file(file_path): 특정 요소의 스크린샷을 이미지로 저장

ChromeOptions

-> add_argument 메서드를 활용하여 브라우저의 실행 동작을 설정

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

#ChromeOptions 객체 생성
chrome_options = Options()

# 옵션 추가
chrome_options.add_argument("--start-maximized")
chrome_options.add_argument("--disable-notifications")
chrome_options.add_argumet("--incognito")
chrome_options.add_argument("--headless")

# 드라이버에 옵션 전달
driver = webdriver.Chrome(options = chrome_options)
driver.get("https://www.google.com")
#driver.quit

자주 사용되는 옵션들

--start-maximized: 브라우저를 최대화 된 상태로 실행
--window-size = width, height: 브라우저 크기를 지정 (e.g. --window-size = 1920, 1080)
headless: 브라우저 GUI 없이 백그라운드에서 실행 (리소스 절약)
--disable-notifications: 알림창 비활성화
--incognito: 시크릿 모드 실행
--disable-gpu: GPU 렌더링 비활성화 (Linux에서 headless 모드에서 사용 권장)
--no-sandbox: 샌드박스 모드 비활성화 (권한 문제 해결에 유용)
--disable-extensions: 확장 프로그램 비활성화

EC 메서드

from selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.ui import WebDriverWait 이 두 가지 같이 활용

EC.title_is("title"): 현재 페이지의 제목이 지정된 문자열과 일치할 때
EC.presence_of_element_located((By.ID, "아이디값")): 값의 (태그=돔 요소)DOM이 존재할 때 (->아이디는 예시! 화면에 표시 안 되어도 됨.)
EC.visibility_of_element_located((By.CSS_SELECTOR, "선택자")): DOM이 존재할 때(화면에 표시)
EC.presence_of_all_elements_located((By.CSS_SELECTOR, "선택자")): DOM의 모든 요소가 존재할 때
EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "선택자")): DOM에 모든 요소가 존재할 때(화면에 표시)
EC.element_to_be_clickable((By.CSS_SELECTOR, "선택자")): 요소가 화면에 표시되고 클릭이 가능할 때
EC.element_to_be_selected((By.CSS_SELECTOR, "선택자")): 요소가 선택된 상태가 될 때

실습

실습1. github 크롤링

로그인 후 사용자 대시보드에서 사용자 이름이나 프로필 관련 정보를 크롤링

<내 코딩 예시>

#실습1. github 크롤링

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import time

#옵션 객체
options = Options()


options.binary_location = "C:/Program Files/Google/Chrome/Application/chrome.exe" 
#왜 나는 자동으로 크롬 드라이버가 다운이 안 될까... 결국 수동으로 다운 받고 직접 파일 경로를 지정해줬다.
service = Service(ChromeDriverManager(driver_version="134.0.6998.178").install())
#service = Service("C:/Users/HOME/Downloads/chromedriver-win64/chromedriver-win64/chromedriver.exe")
driver = webdriver.Chrome(service=service, options=options)
driver.maximize_window()

#옵션 추가
options.add_argument("--start-maximized")
#options.add_argument("--headless")
options.add_argument("--incognito") #로그인하기 위해 시크릿 모드 옵션 켜기

#웹사이트 지정 -나는 클릭이 안 먹혀서 로그인 페이지부터...
driver.get("https://github.com/login")
print(driver.title)
print(driver.current_url)

#이메일
emailadd = driver.find_element(By.XPATH, '//*[@id="login_field"]')
emailadd.send_keys("Sojung-Oh")

#password

passwd = driver.find_element(By.XPATH, '//*[@id="password"]')
passwd.send_keys("dhthfl545400")

button = driver.find_element(By.XPATH, '//*[@id="login"]/div[4]/form/div/input[13]')
button.click()

#finding profile
proftab1 = driver.find_element(By.XPATH, '/html/body/div[1]/div[1]/header/div/div[2]/div[4]/deferred-side-panel/include-fragment/react-partial-anchor/button/span/span/img')
proftab1.click()

time.sleep(10) #로딩이 느려 element가 활성화 안 된 경우도 있어 추가함

proftab2 = driver.find_element(By.XPATH, '//*[@id=":rl:--label"]')
proftab2.click()

#printing user profile info
time.sleep(5) #로딩이 느려 element가 활성화 안 된 경우도 있어 추가함
username = driver.find_element(By.XPATH, '/html/body/div[1]/div[5]/main/div/div/div[1]/div/div/div[1]/div[2]/h1/span[2]')
print("사용자명: ", username.text)

usermail = driver.find_element(By.XPATH,'/html/body/div[1]/div[5]/main/div/div/div[1]/div/div/div[3]/div[2]/ul/li/a')
print("사용자 이메일: ", usermail.text)

time.sleep(3)
input("대기")

# driver.quit()

<내 코드 실행 결과>
DevTools listening on ws://127.0.0.1:56540/devtools/browser/67675a12-c9ca-4d8d-b986-f67ee87e4a35
Sign in to GitHub · GitHub
https://github.com/login
[5880:24588:0408/195358.996:ERROR:page_load_metrics_update_dispatcher.cc(179)] Invalid first_paint (unset) for first_image_paint 1.678 s
Created TensorFlow Lite XNNPACK delegate for CPU.
사용자명: Sojung-Oh
사용자 이메일: ohsj19@ewhain.net

실습2. 쇼핑몰 크롤링 하기

-쇼핑몰에서 특정 검색어(예: "노트북")를 검색
-검색 결과에서 가격이 50만 원 이상인 상품의 이름과 가격을 추출

#실습2. 쇼핑몰 크롤링하기

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import time

#옵션 객체
options = Options()

options.binary_location = "C:/Program Files/Google/Chrome/Application/chrome.exe" 
service = Service(ChromeDriverManager(driver_version="134.0.6998.178").install())
# #왜 나는 자동으로 크롬 드라이버가 다운이 안 될까... 결국 수동으로 다운 받고 직접 파일 경로를 지정해줬다.
# service = Service("C:/Users/HOME/Downloads/chromedriver-win64/chromedriver-win64/chromedriver.exe")
driver = webdriver.Chrome(service=service, options=options)
driver.maximize_window()

#옵션 추가
options.add_argument("--start-maximized")
options.add_argument("--disable-notifications")

#웹사이트 지정 -온라인 쇼핑몰
driver.get("https://www.lge.co.kr/")
print(driver.title)
print(driver.current_url)
time.sleep(3)

#광고창 닫기
button_ad = driver.find_element(By.XPATH, '//*[@id="radix-:r9:"]/div/div[2]/button')
button_ad.click()
time.sleep(5)

#검색창에 노트북 입력
button1 = driver.find_element(By.XPATH, '/html/body/div[1]/header/section[1]/div/ul/li[1]/a')
button1.click()
time.sleep(1)

searchtab = driver.find_element(By.XPATH, '//*[@id="radix-:ri:"]')
searchtab.send_keys("노트북")
searchtab.send_keys(Keys.ENTER)

time.sleep(4)
#상품 정렬 순서 가격순으로 바꾸기
ordertab = driver.find_element(By.XPATH, '//*[@id="cusomtSelectbox_68_button"]/a')
ordertab.click()
time.sleep(1)
#가격 높은 순서대로 정렬
price_order = driver.find_element(By.XPATH, '//*[@id="cusomtSelectbox_68_menu"]/div[1]/ul/li[3]/a')
price_order.click()

time.sleep(5)

#가격 높은 순에서 첫번째 상품 선택
highest = driver.find_element(By.CLASS_NAME, 'result-list.item-card-wrap.more')
highest.click()

time.sleep(3)

#선택된 상품 페이지에서 상품 이름과 가격 추출하기

prod_name = driver.find_element(By.XPATH, '//*[@id="typeOrder"]/div[2]/div[2]/div[1]/div[1]/div[2]/h1')
print("상품명: ", prod_name.text)

original_price = driver.find_element(By.XPATH, '//*[@id="b2cPriceArea"]/ul/li[1]/dl/dd/div/small')
print("원가: ", original_price.text)

dis_price = driver.find_element(By.XPATH,'//*[@id="maxBenefitPopupSelector"]/span')
print("할인가: ", dis_price.text)

driver.quit()

<실행 결과>
DevTools listening on ws://127.0.0.1:51710/devtools/browser/59ab4e91-4aa9-4227-b2d4-22dcc92715a5
LGE.COM | LG전자
https://www.lge.co.kr/home
상품명: LG 그램 Pro 40.6cm 인텔® 코어™ Ultra 7 프로세서 255H
원가: 판매가
3,740,000원
할인가: 3,031,800원

<리더님 코딩 예시>


from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import time

#옵션 객체
options = Options()


#옵션 추가
options.add_argument("--start-maximized")
#options.add_argument("--headless")
options.add_argument("--incognito") #로그인하기 위해 시크릿 모드 옵션 켜기


options.binary_location = "C:/Program Files/Google/Chrome/Application/chrome.exe" 
# #왜 나는 자동으로 크롬 드라이버가 다운이 안 될까... 결국 수동으로 다운 받고 직접 파일 경로를 지정해줬다.
# service = Service("C:/Users/HOME/Downloads/chromedriver-win64/chromedriver-win64/chromedriver.exe")
service = Service(ChromeDriverManager(driver_version="134.0.6998.178").install())
driver = webdriver.Chrome(service=service, options=options)
driver.maximize_window()

#실습 2번 쇼핑몰 크롤링

driver.get("https://www.11st.co.kr/")

find = driver.find_element(By.XPATH, '//*[@id="tSearch"]/form/fieldset/input')
find.send_keys("노트북")
find.send_keys(Keys.ENTER)


time.sleep(5)

items = driver.find_elements(By.CSS_SELECTOR, ".c-search-list__item") #클래스명 

for item in items:
    name = item.find_element(By.CSS_SELECTOR, ".c-search-list__item > div .c-card-item__name > dd").text
    price = item.find_element(By.CSS_SELECTOR, ".c-search-list__item > div .c-card-item__price > span").text
    price = int(price.replace(',', ''))
    if price > 500000:
        print(f"상품명: {name}, 가격: {price}")
    #print(name)
    #print(price)
    
input("대기")

<리더님 코드 결과>
.
.
.
상품명: LG 그램 프로 17ZD90SP-EX59K 노트북 / 윈도우 11 설치 / RAM 32GB / NVMe SSD 512GB, 가격: 3000000
상품명: LG전자 그램 프로16 16ZD90SP-GX59K SSD 512GB+한컴+마우스+마우스 패드 - KW, 가격: 1772180
상품명: [최종205만+한컴] HP OMEN 16-wf1037TX 14세대 i7-14700HX/RTX4060/32GB/NVME 512GB/QHD/Win11/240Hz/게이, 가격: 2159070
대기

실습3. 여행사이트 크롤링하기

-여행 예약 사이트(예: Agoda 또는 Booking.com)에 접속
-특정 도시를 검색하고, 캘린더에서 출발 날짜와 도착 날짜를 선택한 후, 첫 번 째 검색 결과의 호텔 이름과 가격을 출력

#실습3. 여행사이트 크롤링하기 (부킹 닷컴)

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import time

#옵션 객체
options = Options()

#옵션 추가
options.add_argument("--start-maximized")
options.add_argument("--disable-notifications")
options.add_argument("--incognito")

options.binary_location = "C:/Program Files/Google/Chrome/Application/chrome.exe" 
service = Service(ChromeDriverManager(driver_version="134.0.6998.178").install())
driver = webdriver.Chrome(service=service, options=options)
driver.maximize_window()

#웹사이트 지정 -부킹 닷컴
driver.get("https://www.booking.com/")
print(driver.title)
print(driver.current_url)

time.sleep(2)
# driver.refresh()

#로그인 팝업창 닫기

#driver.find_element(By.XPATH, '//*[@id="b2indexPage"]/div[44]/div/div/div/div[1]/div[1]/div/button').click()

city = driver.find_element(By.XPATH, '//*[@id=":rh:"]')
city.send_keys("후쿠오카 공항")

time.sleep(2) 
#계속 서울로 검색되던 원인...미처 후쿠오카 공항을 사이트에 검색하기 전에 엔터가 입력되어서 그런듯
#시간 텀을 주니까 해결되었다.
city.send_keys(Keys.ENTER)

time.sleep(5)

#login_popup = driver.find_element(By.XPATH, '')
#if()

next_page = driver.find_element(By.XPATH, '//*[@id="calendar-searchboxdatepicker"]/div/div[1]/button')
next_page.click()

start_date = driver.find_element(By.XPATH, '//*[@id="calendar-searchboxdatepicker"]/div/div[1]/div/div[2]/table/tbody/tr[2]/td[4]')
start_date.click()

end_date = driver.find_element(By.XPATH, '//*[@id="calendar-searchboxdatepicker"]/div/div[1]/div/div[2]/table/tbody/tr[3]/td[2]/span')
end_date.click()


#검색 버튼 클릭
driver.find_element(By.XPATH, '//*[@id="bodyconstraint-inner"]/div/div/div[1]/div/form/div/div[4]/button/span').click()

time.sleep(3)

#hotels = driver.find_elements(By.CSS_SELECTOR, "div .d4924c9e74")

first_hotel = driver.find_element(By.CSS_SELECTOR, "div.d4924c9e74 > div:nth-child(4) > div.c066246e13.d8aec464ca")
hotel_name = driver.find_element(By.CSS_SELECTOR, 'div.c066246e13.d8aec464ca > div > div > div > div > div > div > div > h3 > a > div')
print(hotel_name.text)

input("대기")

<실행 결과>
DevTools listening on ws://127.0.0.1:64371/devtools/browser/3911117c-b863-497e-985a-11802c8cfc8e
Booking.com | 공식 사이트 | 최고의 호텔, 항공권, 렌터카, 숙소
https://www.booking.com/index.ko.html?label=gen173nr-1BCAEoggI46AdIM1gEaH2IAQGYARe4ARfIAQzYAQHoAQGIAgGoAgO4AvCl2b8GwAIB0gIkZTkzNGYwYzktZTVlMy00MWQyLTk0YzMtMjczZTQ0YmQ2NTdm2AIF4AIB&sid=3b586015c0bd700a4f62d6b234e568e5&keep_landing=1&sb_price_type=total&
Enzo Fukuoka
대기Created TensorFlow Lite XNNPACK delegate for CPU.

<리더님 예시 코드>

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import time

#옵션 객체
options = Options()


#옵션 추가
options.add_argument("--start-maximized")
#options.add_argument("--headless")
options.add_argument("--incognito") #로그인하기 위해 시크릿 모드 옵션 켜기


options.binary_location = "C:/Program Files/Google/Chrome/Application/chrome.exe" 
# #왜 나는 자동으로 크롬 드라이버가 다운이 안 될까... 결국 수동으로 다운 받고 직접 파일 경로를 지정해줬다.
# service = Service("C:/Users/HOME/Downloads/chromedriver-win64/chromedriver-win64/chromedriver.exe")
service = Service(ChromeDriverManager(driver_version="134.0.6998.178").install())
driver = webdriver.Chrome(service=service, options=options)
driver.maximize_window()

#실습3. 여행 사이트 크롤링 하기

from selenium.webdriver.support import expected_conditions as EC 

driver.get("https://www.agoda.com/ko-kr/")

WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.ID, 'textInput'))
) #10초는 최대 대기 시간

search = driver.find_element(By.ID, 'textInput')
search.click()
search.send_keys("도쿄")

time.sleep(3)

search.send_keys(Keys.ENTER)

driver.find_element(By.CSS_SELECTOR, '.Suggestion.Suggestion__categoryName').click()

WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.ID, "check-in-box"))
)
#checkin = driver.find_element(By.ID, 'check-in-box')
#checkin.click()
#driver.find_element(By.ID, 'check-in-box').click()

WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.CSS_SELECTOR, ".Popup__content.Popup__content_Occupancy"))
)

#input("대기")

#리더님 코드 참고해서 수정하기

#클릭 가능한 상태가 된다면 클릭한다! 10초 넘어가면 오류 발생시키고, 10초 넘어가기 전에 클릭할 수 있게 되면 넘어가기
#집 가서 슬립 쓰던 거 다 웹드라이버 웨잇으로 바꿔보기!

driver.find_element(By.XPATH, '//*[@id="DatePicker__AccessibleV2"]/div/div[2]/div[1]/div[3]/div[4]/div[2]/div/div/div').click() #20250422
driver.find_element(By.XPATH, '//*[@id="DatePicker__AccessibleV2"]/div/div[2]/div[1]/div[3]/div[4]/div[5]/div/div/div').click() #20250425

driver.find_element(By.ID, 'occupancy-box').click()

#driver.find_element(By.XPATH, '//*[@id="Tabs-Container"]/button').click()

tab = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, '//*[@id="Tabs-Container"]/button'))
)
tab.click()

time.sleep(7)


#마지막으로 열린 탭으로 전환
driver.switch_to.window(driver.window_handles[-1])

hotels = WebDriverWait(driver, 10).until(
    EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.hotel-list-container h3'))
)

#hotels = driver.find_elements(By.CSS_SELECTOR, ".hotel-list-container h3")
price = driver.find_elements(By.CSS_SELECTOR, ".hotel-list-container .PropertyCardPrice__Value")

print(f"호텔명: {hotels[0].text}, 가격: {price[0].text}")

for hotel in hotels:
    print(hotel.text)

<리더님 예시코드 실행 결과>
DevTools listening on ws://127.0.0.1:49836/devtools/browser/275efad8-7e77-436d-8b4d-f9b6bc11958e
Created TensorFlow Lite XNNPACK delegate for CPU.
호텔명: APA 호텔 앤 리조트 롯폰기 에키히가시 (APA Hotel & Resort Roppongi Ekihigashi), 가격: 227,746
APA 호텔 앤 리조트 롯폰기 에키히가시 (APA Hotel & Resort Roppongi Ekihigashi)
APA 호텔 앤 리조트 니시신주쿠-고초메-에키 타워 (APA Hotel & Resort Nishishinjuku-Gochome-Eki Tower)
APA 호텔 히가시 신주쿠 가부키초 타워 (APA Hotel Higashi Shinjuku Kabukicho Tower)
대기

실습4. 이미지 크롤링하기

-Google 이미지 검색에서 원하는 동물을 검색
-무한 스크롤을 통해 10개 이상의 이미지를 로드하고, 이미지를 다운로드하여 로컬 디렉토리에 저장

import os
import requests

driver.get("https://www.google.co.kr/imghp")

time.sleep(2)

search = driver.find_element(By.ID, 'APjFqb')
search.click()
search.send_keys("햄스터")
search.send_keys(Keys.ENTER)
time.sleep(2)

#스크롤 끝까지 내리기 3회
for i in range(3):
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(2)


images = driver.find_elements(By.CSS_SELECTOR, "img.YQ4gaf")

os.makedirs("./1205/images", exist_ok=True) #폴더 생성, 존재하면 무시

code = 1
for image in images[:150]:
    src = image.get_attribute("src")
    #print(src)
    if "https" in src:
        res = requests.get(src)
        print(res)
        print(res.content) # res.content 이미지, 동영상 값 반환
        #res.status_code: 응답 코드
        #res.headers: http 헤더의 정보 반환
        #res.url: 최종 url 반환
        with open(f"./1205/images/img_{code}.png", "wb") as file:
            file.write(res.content)
        code += 1




input("대기")

느낀 점:
아직 CSS 선택자와 태그의 활용이 자유롭지 못한 것 같다. 좀 더 여러 예시를 접하며 연습해보아야 할 것 같다.

0개의 댓글