Creative Code

Lunar-(10)비디오 기능추가(구글 웹 크롤링-Selenium) 본문

Projects

Lunar-(10)비디오 기능추가(구글 웹 크롤링-Selenium)

빛하루 2023. 12. 24. 23:36

pages/video.py

 

키워드 입력시 selenium으로 유튜브 웹크롤링을해 스크롤을 1번 한 뒤 동영상의 주소와 제목을 가져와 데이터 제공

+ 영상이 끝날 시 반복재생

 

다음엔 video.py 일부 기능 추가 + UI 수정, diary기능 시작

 

※pages/video.py 전체 코드

 

# lunar.state.home 모듈에서 필요한 State 및 HomeState를 가져옵니다.
import reflex as rx
from lunar.state.base import State
from lunar.state.home import HomeState

# 컴포넌트를 가져옵니다.
from ..components import container

color = "rgb(107,99,246)"
# 탭 버튼을 생성하는 함수
def tab_button(imagepath, href):
    """A tab switcher button."""
    return rx.link(
        rx.image(
            src=imagepath,
            height='40px',
            width='40px',
        ),
        display="inline-flex",
        align_items="center",
        py=3,
        px=2,
        href=href,  # 버튼 클릭 시 이동할 경로
    )

# 왼쪽에 표시되는 탭 스위처
def tabs():
    """The tab switcher displayed on the left."""
    return rx.box(
        rx.vstack(
            rx.container(
                rx.hstack(
                    rx.image(
                        src='/moon.png',
                        height='60px',
                        width='60px',         
                    ),
                    rx.text(
                        "Lunar", 
                        style={
                            "fontSize": "40px",
                            "fontWeight": "bolder",
                            "fontFamily": "Calibri, Calibri",
                            "background": "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
                            "-webkit-background-clip": "text",
                            "color": "transparent",
                        },
                        center_content=True,
                    ),  # 앱 이름
                ),
            ),
            rx.button(
                "Sign out",
                on_click=State.logout,
                bg="#212963",
                color="white",
                _hover={"bg": "blue.600"},
            ),
            rx.container(height='200px'),
            align_items="left",
            gap=4,
        ),
        py=4,
        overflow='auto',
    )

# 오른쪽에 표시되는 사이드바
def sidebar(HomeState):
    """The sidebar displayed on the right."""
    return rx.vstack(
        align_items="start",
        gap=4,
        h="100%",
        width = '100%',
        py=4,
        overflow='auto',
    )

# 피드의 헤더
def feed_header(HomeState):
    """The header of the feed."""
    return rx.hstack(
        rx.image(src='/find1.png',height='35px',width='35px'),
        rx.input(on_change=HomeState.set_search_video, placeholder="video search..!"),
        rx.button('search', on_click = HomeState.get_youtube_links),
        justify="space-between",
        p=4,
        border_bottom="3px solid #000000",
    )

def get_video(video):
    result = video.split(',')
    return rx.box(
        rx.vstack(
            rx.video(
                url = result[1],
                max_width = '800px',
                max_height = 'auto',
                playing = False,
                loop = True,
            ),
            rx.heading(result[0],Font_size = '25px'),
            rx.container(height='10px'),
            width = '100%'
        ),
    )

# 피드 영역
def feed(HomeState):
    """The feed."""
    return rx.box(
        feed_header(HomeState),
        rx.foreach(
            HomeState.youtube_results,
            get_video,
        ),
        border_x = '3px solid #000000',
        overflow='auto',
    )

# 홈 페이지
def video():
    State.check_login
    return rx.vstack(
        rx.grid(
            tabs(),
            feed(HomeState),
            sidebar(HomeState),
            grid_template_columns="2fr 5fr 2fr",
            width='97%',
            h="90vh",
            gap=4,
            
        ),
        rx.hstack(
            tab_button('/Home.png','/'),
            tab_button('/profile.png','/profile'),
            tab_button('/map.png','/map'),
            tab_button('/chat.png','/chat'),
            tab_button('/Aichat.png','/aichat'),
            tab_button('/diary.png','/diary'),
            tab_button('/video.png','/video'),
            tab_button('/game.png','/game'),
            tab_button('/setting.png','/setting'),
            margin_right='5px',
            border="1px solid #000000",
            border_radius="full",
        ),
        width='100%',
    )

 

※ state/home.py 의 유튜브 웹 크롤링 함수

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import datetime

# HomeState 클래스 이하생략

# youtube링크를 가져오는 함수
    def get_youtube_links(self):
        search_word = self.search_video
        url = f'https://www.youtube.com/results?search_query={search_word}' 
        service = Service(ChromeDriverManager().install())
        options = webdriver.ChromeOptions()
        options.add_argument('headless')
        driver = webdriver.Chrome(service=service,options=options)
        driver.get(url)
        driver.execute_script("window.scrollTo(0,document.documentElement.scrollHeight);")
        titles = driver.find_elements(By.CSS_SELECTOR,"#dismissible.style-scope.ytd-video-renderer")
        self.youtube_results = []
        for title in titles:
            result = ''
            main_title = title.find_element(By.CSS_SELECTOR,"#video-title").get_property("title")
            tube_url = title.find_element(By.CSS_SELECTOR,"#video-title").get_property("href")
            result += main_title
            result += ','
            result += tube_url
            self.youtube_results.append(result)