파이썬 웹 크롤링이용 텔레그램 챗봇3

임재성·2024년 1월 7일
0

개선점

  • 현재 chrome 드라이버를 사용하여 프로그램을 실행시키면 실행 후 크롬 브라우저가 띄워졌다가 꺼지면서 코드가 실행되고 있음.
  • 만약 해당 프로그램을 현재 상태로 리눅스에 배포한다고 한다면 X서버가 실행되어 있어야 한다는 단점이 존재한다.
  • 때문에 해당 코드를 수정할 필요성을 느낌.

개선하기

  • 해당 내용에 대해 구글에 검색하면서 찾은 내용들은

    • phantomJS
    • chrome, edge(headless 옵션 사용)
    • 크롤링시 헤더 내용을 추가하여 실행.
  • 우선 위의 방법들은 모두 실패 하였음.

  • PhantomJS

    • 현 시점에서 phantomJS는 업데이트가 되지 않고 있으며, 최신 selenium 모듈에서 phantomJS는 지원하지 않기 때문에 selenium 버전을 낮춰 진행하였음.

    • 진행하면서 처음 아래와 같은 오류 발생.

    • 해당 오류는

      pip3 install webdriver-manager
      
      # selenium 3
      from selenium import webdriver
      from webdriver_manager.chrome import ChromeDriverManager
      
      driver = webdriver.Chrome(ChromeDriverManager().install())
      
      # selenium 4
      from selenium import webdriver
      from selenium.webdriver.chrome.service import Service as ChromeService
      from webdriver_manager.chrome import ChromeDriverManager
      
      driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))```
    • 위와 같이 따라하면 정상 작동
      그러나 Javascript가 동작한 후의 내용이 보이지 않음.

  • Edge

    • edge도 마찬가지로 동작안함.
    • 웹 크롤링을 인식하여 막는 사이트가 있다고 하여, 아래와 같은 옵션으로 크롤링인 것을 감추어 실행해보라 했지만 실패...
    options.add_argument("--enable-javascript")
    options.add_argument('--headless')
    options.add_argument('--window-size=1920x1080')
    options.add_argument('--start-maximized')
    options.add_argument("--disable-notifications")
    options.add_argument('--no-sandbox')    
    options.add_argument('--disable-software-rasterizer')
    options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")    
    options.add_argument("--disable-blink-features=AutomationControlled")```
    
  • Firefox

    • 마지막으로 Firefox 드라이버를 설치하여 해봤는데 성공하였음.

    • 아래는 코드 전체

      url = 'http://www.cgv.co.kr/theaters/?areacode=01&theaterCode=0013&date=20240104'
      
      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.support import expected_conditions as EC
      from bs4 import BeautifulSoup
      from webdriver_manager.chrome import ChromeDriverManager
      from webdriver_manager.microsoft import EdgeChromiumDriverManager
      from selenium.webdriver.edge.options import Options
      
      import telegram
      import asyncio
      import secret
      from msedge.selenium_tools import EdgeOptions
      from msedge.selenium_tools import Edge
      
      from apscheduler.schedulers.blocking import BlockingScheduler
      from selenium.webdriver.firefox.options import Options as FirefoxOptions
      
      asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
      async def send(text, bot) :    
        await bot.sendMessage(chat_id=secret.chat_id, text=text)
      
      def job_function() :
        bot = telegram.Bot(token=secret.token)
      
        options = FirefoxOptions()
        options.add_argument("--headless")
        driver = webdriver.Firefox(options=options)    
        
        # 대상 웹 페이지로 이동합니다.
      
        driver.get(url)
      
        # iframe의 XPath를 찾아서 해당 iframe으로 전환합니다.
        iframe_xpath = '//iframe[@id="ifrm_movie_time_table"]'  # 실제 웹 페이지의 iframe ID에 맞게 수정
        iframe = WebDriverWait(driver, 15).until(
            EC.presence_of_element_located((By.XPATH, iframe_xpath))
        )
        
        driver.switch_to.frame(iframe)
      
        # iframe 내용이 로드될 때까지 대기합니다.
        iframe_content_xpath = '//body'  # 실제 웹 페이지의 iframe 내용에 맞게 수정
        iframe_content = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.XPATH, iframe_content_xpath))
        ).get_attribute("outerHTML")
      
        # iframe에서 벗어나 원래의 상위 레벨로 돌아갑니다.
        driver.switch_to.default_content()
      
        # WebDriver를 종료합니다.
        driver.quit()
      
        soup = BeautifulSoup(iframe_content, 'html.parser')
        print(soup)
        is_imax_list = soup.select('span.imax')
        imax_name_lst= []
        if len(is_imax_list) > 0 :
            for i in is_imax_list :
                imax = i.find_parent('div', class_='col-times')
                imax_name_lst.append(imax.select_one('div.info-movie > a > strong').text.strip())
      
            asyncio.run(send(str(imax_name_lst) + " IMAX가 열렸습니다." , bot))
            # sched.pause()
        else :
            asyncio.run(send("열린 IMAX가 없습니다." , bot))
            
        job_function()
        
      
  • chrome, firefox, edge 모두 같을 것이라 생각했지만 아니었다.

  • 스태오버플로 답변에 크롬사용하지말고 파이어폭스 사용하라는 내용이 있었는데 진작 시도해볼걸 그랬음.

  • 이 다음 내용은 url 부분에 대해 동적으로 변화하도록 수정해 보려고 한다.

profile
조금씩 앞으로

0개의 댓글