카테고리 없음

[Python] 웹페이지와 작업표시줄 같이 캡처하기 (image, selenium)

갈룩시노테7 2024. 6. 10. 23:08
반응형

(캡처 예제 사이트는 이삭토스트 공식 홈페이지입니다.)

 

https://www.isaac-toast.co.kr/

 

이삭토스트

이삭토스트와 함께한 달콤한 기억이 있나요? 한 손에 담긴 든든한 한 끼, 한 입에 퍼지는 미소! 오늘도 한 손에 담긴 따듯한 토스트로 마음을 전하고 나누며 고객님을 맞이할 준비를 합니다. 어

www.isaac-toast.co.kr

 

 

팝업창을 끄고 드래그해야만 웹페이지의 끝 지점에 도달하는 사이트를 캡쳐해보겠습니다.

 

 

pip install pyautogui
pip install Image
pip install selenium

 

먼저 필요 라이브러리인 pyautogui, Image, selenium 을 설치해줍니다.

 

import time  # time 모듈을 임포트하여 sleep 기능을 사용.
import os # os 모듈을 임포트하여 파일 경로를 사용.
import pyautogui # pyautogui 모듈을 임포트하여 스크린샷 기능을 사용.
from PIL import Image # Image 모듈을 임포트하여 이미지 처리 기능을 사용.
from selenium import webdriver  # Selenium 패키지에서 webdriver 모듈을 임포트.
from selenium.webdriver.chrome.options import Options  # Chrome 옵션을 설정하기 위해 Options 모듈을 임포트.
from selenium.webdriver.common.by import By # By.XPATH 사용

 

다음은 캡처 프로그램 제작 시 사용에 필요한 라이브러리들을 import 시킵니다.

url = input("저장할 웹페이지 URL을 입력하세요: ")
now_image_name = str(time.localtime().tm_hour) + str(time.localtime().tm_min) + str(time.localtime().tm_sec)

 

먼저 셀레니움을 통한 전체 웹페이지 내용을 캡처하기 위하여 캡쳐할 사이트 주소와,

다른 사진들과의 구분을 위해 사진 찍은 시간 값을 변수로 받아옵니다.

 

option = Options()
option.add_argument("headless") # 브라우저를 띄우지 않는 headless chrome 옵션 적용 (해당 옵션을 처리해야만 전체 페이지 캡처가 가능)
option.add_argument('--no-sandbox') # 크롬 드라이버가 리눅스에서 실행될 때 필요한 옵션
option.add_argument('window-size=1920x1080') # 전체 웹페이지 촬영을 위한 화면 최대화
option.add_argument('--disable-gpu') # gpu 사용 안함
option.add_argument('log-level=3') # 로그 레벨 수준을 낮춤으로써 생략가능한 오류 경고 무시

 

셀레니움 사용을 위한 기본 옵션을 설정해줍니다.

각 옵션의 기능은 주석 내용과 동일하며 하나라도 없을 경우에는 정상적인 촬영이 불가능합니다.

 

waittime = 5 # 대기 시간
driver = webdriver.Chrome(options=option)
driver.set_page_load_timeout(20) # 페이지 로드 시 대기시간
driver.get(url)

 

기본 대기시간과 웹페이지 최대 대기시간을 설정한 후, 웹드라이버를 실행하여 해당 홈페이지를 불러옵니다.

 

# 공지 팝업 있는지 확인

close_buttons = driver.find_elements(By.XPATH, '//*[@id="wrap"]/div[5]/article/ul/li[2]/input')

if len(close_buttons) > 0:
    close_buttons[0].click()
else:
    print("닫을 팝업창이 없습니다.")

 

먼저 팝업창이 존재할 경우 해당 팝업창의 닫기를 눌러주는 코드를 작성합니다.

해당 XPATH 경로는 크롬의 개발자 도구에서 조회가 가능합니다.

 

F12 - 찾는 위치 선택 - 우클릭 후 XPath 복사

 

total_height = driver.execute_script("return document.body.parentNode.scrollHeight") 
# 자바스크립트를 실행하여 웹페이지의 총 높이를 가져오기.
driver.execute_script("window.scrollTo(0, document.body.parentNode.scrollHeight);")
# 브라우저 창을 페이지 하단으로 스크롤 하기.
driver.set_window_size("1920", total_height)
# 창의 크기를 설정하여 전체 웹페이지를 캡처 (너비: 1920 픽셀, 높이: total_height 픽셀)
time.sleep(waittime)
driver.save_screenshot(now_image_name + '.png')  # 스크린샷을 지정된 출력 경로에 저장.
driver.quit()

 

먼저 웹페이지에서 자바스크립트를 실행하여 웹페이지의 총 스크롤 크기를 가져옵니다.

이후 스크롤 바를 맨 밑까지 이동시키는데, 이는 일부 홈페이지에서는 스크롤 애니메이션이 적용되어 있기 때문입니다.

스크롤 애니메이션을 생략할 경우

 

그 다음 윈도우 창의 크기를 전체 페이지가 들어갈 수 있도록 조정해준 다음

해당 웹페이지를 캡처하여 png 파일로 저장 후 사용이 끝난 selenium 드라이버를 종료합니다.

 

#-------------------------------- 작업표시줄 캡쳐

screen_width, screen_height = pyautogui.size()
taskbar_box = (0, screen_height - 40, screen_width, screen_height)

# 작업 표시줄 캡처
taskbar_screenshot = pyautogui.screenshot('taskbar.png', region=taskbar_box)

 

다음은 작업표시줄 캡처 방법입니다.

pyautogui를 이용하여 현재 창의 가로, 세로 길이를 받아옵니다.

taskbar_box를 사용해 시작 꼭짓점과 끝 꼭짓점을 조절하여 작업표시줄 위치에 사각형 박스를 만들도록 설정합니다.

(화면마다 크기가 다르니 직접 확인하시면서 조절하시는 걸 추천드립니다.)

마지막으로 설정한 사각형 박스 내부의 작업표시줄을 캡처합니다.

# -------------------------------- 이미지 합치기

# 웹페이지와 작업 표시줄 이미지 합치기
image1 = Image.open(str(now_image_name) + '.png')
image2 = taskbar_screenshot

image1.resize((total_height, 1920))

image1_size = image1.size

 

이전에 찍었던 웹페이지의 전체 사진과 작업표시줄 사진을 image1과 image2로 불러옵니다.

특히 image1의 경우 처음 작업 시 사이즈를 지정했음에도 불구하고,

가로 길이에 딱 맞지 않는 경우가 있기 때문에 다시 한번 크기를 조정합니다.

조정한 이미지의 크기는 image1_size에 리스트로 한번 더 저장해줍니다.

 

new_image = Image.new('RGB',(image1_size[0], image1_size[1]+40), (250,250,250)) # 40은 작업표시줄 높이

new_image.paste(image1,(0,0)) # 웹페이지 이미지 붙이기
new_image.paste(image2,(0,image1_size[1])) # 작업표시줄 이미지 붙이기
new_image.save('C:\\Users\\user\\Desktop\\full_screenshot_' + now_image_name + '.png') # 합친 이미지 저장
#new_image.show() # 합친 이미지 보여주기

print('이미지 합치기 완료, 바탕화면 저장')

os.remove(now_image_name + '.png') # 웹페이지 이미지 삭제
os.remove('taskbar.png') # 작업표시줄 이미지 삭제

 

두 이미지를 합치기 위해 새 이미지 객체를 만들어서, 가로 크기는 image1과 동일하게, 세로 크기는 image1의 세로 크기에서 작업표시줄의 높이만큼 더한 값으로 설정해줍니다.

이후 시작지점을 지정하여 웹페이지와 작업표시줄의 사진을 합쳐준 뒤 현재 시각을 제목으로 넣어 바탕화면에 사진을 저장해줍니다.

 

마지막으로 완료되었다는 출력과 함께 작업 중 생성되었던 두 그림 파일을 삭제해주면 완료입니다.

 

캡쳐가 완료된 사진입니다.

 

더보기
import time  # time 모듈을 임포트하여 sleep 기능을 사용.
import os # os 모듈을 임포트하여 파일 경로를 사용.
import pyautogui # pyautogui 모듈을 임포트하여 스크린샷 기능을 사용.
from PIL import Image # Image 모듈을 임포트하여 이미지 처리 기능을 사용.
from selenium import webdriver  # Selenium 패키지에서 webdriver 모듈을 임포트.
from selenium.webdriver.chrome.options import Options  # Chrome 옵션을 설정하기 위해 Options 모듈을 임포트.
from selenium.webdriver.common.by import By # By.XPATH 사용

url = input("저장할 웹페이지 URL을 입력하세요: ")
now_image_name = str(time.localtime().tm_hour) + str(time.localtime().tm_min) + str(time.localtime().tm_sec)

option = Options()
option.add_argument("headless") # 브라우저를 띄우지 않는 headless chrome 옵션 적용 (해당 옵션을 처리해야만 전체 페이지 캡처가 가능)
option.add_argument('--no-sandbox') # 크롬 드라이버가 리눅스에서 실행될 때 필요한 옵션
option.add_argument('window-size=1920x1080') # 전체 웹페이지 촬영을 위한 화면 최대화
option.add_argument('--disable-gpu') # gpu 사용 안함
option.add_argument('log-level=3') # 로그 레벨 수준을 낮춤으로써 생략가능한 오류 경고 무시

waittime = 5
driver = webdriver.Chrome(options=option)
driver.set_page_load_timeout(20)
driver.get(url)

# 공지 팝업 있는지 확인

close_buttons = driver.find_elements(By.XPATH, '//*[@id="wrap"]/div[5]/article/ul/li[2]/input')

if len(close_buttons) > 0:
    close_buttons[0].click()
else:
    print("닫을 팝업창이 없습니다.")

total_height = driver.execute_script("return document.body.parentNode.scrollHeight") # 자바스크립트를 실행하여 웹페이지의 총 높이를 가져오기.
driver.execute_script("window.scrollTo(0, document.body.parentNode.scrollHeight);") # 브라우저 창을 페이지 하단으로 스크롤 하기.
driver.set_window_size("1920", total_height) # 창의 크기를 설정하여 전체 웹페이지를 캡처 (너비: 1920 픽셀, 높이: total_height 픽셀)
time.sleep(waittime)
driver.save_screenshot(now_image_name + '.png')  # 스크린샷을 지정된 출력 경로에 저장.
driver.quit()

#-------------------------------- 작업표시줄 캡쳐

print('작업표시줄 캡처 중...')

screen_width, screen_height = pyautogui.size()
taskbar_box = (0, screen_height - 40, screen_width, screen_height)

# 작업 표시줄 캡처 후 사이즈 수정
taskbar_screenshot = pyautogui.screenshot('taskbar.png', region=taskbar_box)

# -------------------------------- 이미지 합치기

print('이미지 합치기 중...')

# 웹페이지와 작업 표시줄 이미지 합치기
image1 = Image.open(str(now_image_name) + '.png')
image2 = taskbar_screenshot
#image2 = Image.open('taskbar.png')

image1.resize((total_height, 1920))

image1_size = image1.size

print("웹페이지 크기 출력 : ", end='')
print(image1_size)

new_image = Image.new('RGB',(image1_size[0], image1_size[1]+40), (250,250,250)) # 40은 작업표시줄 높이

new_image.paste(image1,(0,0)) # 웹페이지 이미지 붙이기
new_image.paste(image2,(0,image1_size[1])) # 작업표시줄 이미지 붙이기
new_image.save('C:\\Users\\user\\Desktop\\full_screenshot_' + now_image_name + '.png') # 합친 이미지 저장
#new_image.show() # 합친 이미지 보여주기

print('이미지 합치기 완료, 바탕화면 저장')

os.remove(now_image_name + '.png') # 웹페이지 이미지 삭제
os.remove('taskbar.png') # 작업표시줄 이미지 삭제
반응형