SK shieldus Rookies 16기 (인프라 활용을 위한 파이썬 #04)

만두다섯개·2023년 10월 27일
0

SK 루키즈 16기

목록 보기
4/52

주요 정보

  • 교육 과정명 : 클라우드기반 스마트융합보안 과정 16기
  • 교육 회차 정보 : '23. 10. 26. 인프라 활용을 위한 파이썬 과정 #4
  • 웹 페이지 크롤링 (알라딘, 유튜브)

참고 정보

웹 페이지 크롤링

유튜브 크롤링

셀레니움 사용을 통한 유튜브 웹 페이지 크롤링의 기초 지식

  • 유튜브 : 웹 페이지 화면을 아래로 스크롤해서 크롤링한다.

  • 웹 페이지 화면을 아래로 내리려면, 브라우저 제어 메소드 필요

  • 해결 => execute_script 사용

  • 환경 :크롬 브라우저 사용

  • 해결 순서
    1. import webdriver.Chrome
    2. 해당 메소드 제어 목적 drv 객체 생성
    3. 브라우저 실행 및 URL주소로 GET 요청

  • execute_script 메소드 세부
    execute_script(‘스크립트’, ‘파라미터’)
    ‘스크립트’ : ‘return 스크립트’를 사용하면 리턴값을 받을 수 있다.
    ‘파라미터는 필요 없음’
    return 스크립트를 사용해야 한다.
    웹 페이지 끝까지 가기 위해 [document.documentElement.scrollHeight] 사용

  • scrollTo(x, y) 메소드 : 가로 x, 세로 y까지 스크롤을 이동시킨다

유튜브 크롤링 프로그램

유튜브 크롤링 프로그램 설정 ver_01
  • 기능 : 웹 페이지 아래로 스크롤 2회 후 종료
  • 왜 꺼짐 방지 옵션을 설정했는데도 scroll 함수를 실행하지 않을 때조차 브라우저가 종료될까?
    -> 크롬드라이버를 함수에서 실행시 함수 종료와 함께 셀레니움도 함께 종료되기 때문.
# 유튜브 크롤링 프로그램 ver_01 // 기능 : 웹 페이지 아래로 스크롤 2회 후 종료
from selenium import webdriver # webdriver.Chrome 메소드 사용 목적으로 import 
#from selenium.webdriver.common.by import By # selenium 사용 크롤링, XPATH 등을 사용하기 위해 import 
from selenium.webdriver.chrome.options import Options # 브라우저 자동 종료 방지옵션 사용 목적 import
from webdriver_manager.chrome import ChromeDriverManager #[셀레니움 사용 웹 브라우저]와 [사용자 크롬 브라우저] 버전 동기화 목적 import, 사용 전 at console, # pip install webdriver-manager

import random, time
from selenium.webdriver.chrome.service import Service

# 크롤링 실행 전 초기 환경 설정
chrome_options = Options() 
chrome_options.add_experimental_option("detach", True) # 브라우저 꺼짐 방지 옵션 
#chrome_options.add_argument('headless') # 브라우저가 안나오게 하는 옵션
#chrome_options.add_argument('window-size=1920x1080') # 브라우저 사이즈 설정 옵션
#service = Service(ChromeDriverManager().install()) # 셀레니움 사용 웹 브라우저와 실제 크롬 브라우저 맞추기 위해 사용

drv = webdriver.Chrome(options=chrome_options)  # webdriver.Chrome 메소드 : 크롬 브라우저 실행, 초기 환경 설정 적용
drv.implicitly_wait(3) #3초간 멈춰라
drv.get('https://youtube.com/') # 브라우저 실행 후, 해당 URL 주소로 GET 요청을 전송한다
drv.implicitly_wait(3) #3초간 멈춰라

def scroll(): # 스크롤 메소드
    last_page_height = drv.execute_script('return document.documentElement.scrollHeight')  # execute_script : 브라우저 제어 목적 메소드, 웹 페이지의 현재 높이를 scrollHeight 로 가져와 변수에 지정한다

    while True:
        pause_time = random.uniform(1,2)  #(a <= pase_time <= b)
        drv.execute_script('window.scrollTo(0, document.documentElement.scrollHeight);')  # 현재 페이지의 높이로 이동한다 : (가로0, 세로 맨 아래까지)이동 
        time.sleep(pause_time)
        drv.execute_script('window.scrollTo(0, document.documentElement.scrollHeight+50);') # 50 만큼 아래로 더 이동한다
        time.sleep(pause_time)
        new_page_height = drv.execute_script('return document.documentElement.scrollHeight') # 2회 만큼 아래로 더 내려간 후(이동 가능 여부 상관 없이) 현재 웹 페이지의 세로 길이를 변수에 지정

        if new_page_height == new_page_height: #만약, 반복문(웹 페이지 하단 스크롤) 1회 진행 후, 해당 조건문에서 웹 페이지의 세로 높이 2개(스크롤 전, 스크롤 후)를 비교해 서로 같다면, 한계까지 스크롤 한 것이다.
            print('scroll 종료되었습니다.')
            break #이게 없으면 무한 스크롤
        else:
            last_page_height = new_page_height  # 더 내려갈 수 있는 웹 페이지 세로 길이 존재하므로, 해당 값을 last_page_height 에 지정해 더 내려가게 한다.
    
scroll() 



# 실행시 두번 아래로 스크롤 내린 후 종료된다.
유튜브 크롤링 프로그램 설정 ver_02
  • 기능 : 사용자가 원하는 검색어, 스크롤 범위(추후 크롤링시 스크롤 범위가 스크롤 양 결정), 브라우저 생성 여부
# 유튜브 크롤링 프로그램 ver_02
from selenium import webdriver # webdriver.Chrome 메소드 사용 목적으로 import 
#from selenium.webdriver.common.by import By # selenium 사용 크롤링, XPATH 등을 사용하기 위해 import 
from selenium.webdriver.chrome.options import Options # 브라우저 자동 종료 방지옵션 사용 목적 import
from webdriver_manager.chrome import ChromeDriverManager #[셀레니움 사용 웹 브라우저]와 [사용자 크롬 브라우저] 버전 동기화 목적 import, 사용 전 at console, # pip install webdriver-manager

import random, time
from selenium.webdriver.chrome.service import Service
pause_time = random.uniform(1,2)  #(a <= pase_time <= b)
  

def scroll(drv, page_limit): # 스크롤 메소드
    try:
        last_page_height = drv.execute_script('return document.documentElement.scrollHeight')  # execute_script : 브라우저 제어 목적 메소드, 웹 페이지의 현재 높이를 scrollHeight 로 가져와 변수에 지정한다
        
        while True:
            while page_limit != 0:
                drv.execute_script('window.scrollTo(0, document.documentElement.scrollHeight);')  # 현재 페이지의 높이로 이동한다 : (가로0, 세로 맨 아래까지)이동 
                time.sleep(pause_time)
                drv.execute_script('window.scrollTo(0, document.documentElement.scrollHeight+10);') # 50 만큼 아래로 더 이동한다
                time.sleep(pause_time)
                new_page_height = drv.execute_script('return document.documentElement.scrollHeight') # 2회 만큼 아래로 더 내려간 후(이동 가능 여부 상관 없이) 현재 웹 페이지의 세로 길이를 변수에 지정

                if last_page_height == new_page_height: #만약, 반복문(웹 페이지 하단 스크롤) 1회 진행 후, 해당 조건문에서 웹 페이지의 세로 높이 2개(스크롤 전, 스크롤 후)를 비교해 서로 같다면, 한계까지 스크롤 한 것이다.
                    print('scroll 종료되었습니다.')
                    break #이게 없으면 무한 스크롤
                else:
                    last_page_height = new_page_height  # 더 내려갈 수 있는 웹 페이지 세로 길이 존재하므로, 해당 값을 last_page_height 에 지정해 더 내려가게 한다.
                page_limit -=1
    except:
        print("엥! 오류났어! 이거 안돼! 너 당장 고쳐 뚝!")

if __name__ == '__main__':
    print("안녕하세요. 유튜브 크롤링 프로그램을 시작합니다.")
    print("크롤링 목적으로 유튜브 검색창에 원하는 [검색단어]를 입력하세요.")
    search_word = input()
    print("크롤링 과정을 실시간으로 보고 싶으신가요? Yes면 [O], No면 [X] 입력.")
    watch_browser = input()
    print("크롤링 양을 스크롤 몇 회로 조절하시나요? [횟수] 입력.")
    page_limit = input()
    # 크롤링 실행 전 초기 환경 설정
    chrome_options = Options() 
    chrome_options.add_experimental_option("detach", True) # 브라우저 꺼짐 방지 옵션 
    if watch_browser == 'X':
        print("크롤링 안 보여주~~~~지!")
        chrome_options.add_argument('headless') # 브라우저가 안나오게 하는 옵션
    #chrome_options.add_argument('window-size=1920x1080') # 브라우저 사이즈 설정 옵션
    #service = Service(ChromeDriverManager().install()) # 셀레니움 사용 웹 브라우저와 실제 크롬 브라우저 맞추기 위해 사용
    drv = webdriver.Chrome(options=chrome_options)  # service=Servic 생략 drv  생성. 나는 이게 브라우저 버전 최신화 세팅중 하나 안 하면 오류 발생 가능..
    drv.implicitly_wait(3) #3초간 멈춰라
    drv.get('https://www.youtube.com/results?search_query={}'.format(search_word))  # 브라우저 실행 후, 해당 URL 주소로 GET 요청을 전송한다
    drv.implicitly_wait(3) #3초간 멈춰라

    scroll(drv, int(page_limit))
profile
磨斧爲針

0개의 댓글