Activity

Selenium을 활용한 동적 크롤링 자동화 프로젝트_네이버 블로그

짹짹체유 2025. 3. 2. 15:57

 

 

프로젝트 배경

네이버 블로그에 글을 약 4년간 작성하면서 이웃 관리 등이 필요한데 많은 시간을 투자하기는 어렵고

일부분은 자동화하면 좋겠다 싶어서 고민을 하다가 프로젝트를 시작하게 되었다.

 

주요 기능은 2가지로

1. 이웃 글에 좋아요 누르기

2. 이웃이 작성한 글을 보고 생성형 AI가 작성하면 좋을 댓글 5가지 추천해주기

 

기존에는 좋아요 자동화하는 기능만 생각했다가, 생성형 AI를 활용한 웹 개발 했던 경험을 바탕으로 제미나이를 활용해서 댓글 추천을 받는 기능도 구현해보았다.

두 기능은 한 번에 진행이 되고, 전체 플로우는 배치 파일 하나의 클릭으로 자동화했다.

 

 

Flow

 

 

 

Selenium을 활용한 Python code

몇 년 전만 해도 크롬 드라이버를 사용하려면 chromedriver.exe 파일을 다운로드 받아야 했고

크롬이 업데이트 되면 드라이버도 다시 업데이트를 해야해서 불편했다.

 

근데 이제는 드라이버 설치 필요 없이 라이브러리로 바로 활용이 가능하다.

 

 

0. 드라이버 설정

from selenium import webdriver

class MainView(View):
    def setup_driver():
        options = webdriver.ChromeOptions()
        options.add_argument('--headless=new')  # 창을 띄우지 않기
        options.add_argument('--disable-gpu')  # GPU 사용 비활성화 (리눅스 환경 호환성 개선)
        options.add_argument('--no-sandbox')  # 리눅스 환경에서 필요할 수 있음
        options.add_argument('--disable-dev-shm-usage')  # 리소스 부족 문제 방지
        driver = webdriver.Chrome(options=options)
        return driver
    
driver = MainView.setup_driver()

 

옵션 설정을 추가하면서 옵션 제어가 가능하다

  • add_argument('--headless=new'): 창 띄우지 않고 백단에서 자동으로 동작하기
  • add_argument('--disable-gpu'): gpu 사용 비활성화하기 -> 리눅스 환경 호환성을 개선하기 위함
  • add_argument('--no-sandbox'): 리눅스 환경에서 필요
  • add_argument('--disable-dev-shm-usage'): 리소스 부족 문제 방지

 

위 처럼 드라이버 설정 함수를 만들어서 관리를 하고

이후에는 driver.get 등으로 드라이버를 사용하면 된다.

 

 

 

1. 로그인

def login(driver, url):
        try:
            driver.get(url)
            time.sleep(2)

            login = driver.find_element(By.CSS_SELECTOR, '#container > div.layout_content > aside > div > div:nth-child(1) > div.area_signin > div > a')
            login.click()
            naver_id = settings.NAVER_ID
            naver_pw = settings.NAVER_PW
            time.sleep(1)

            elem_id = driver.find_element(By.ID, 'id')
            elem_id.click()
            pyperclip.copy(naver_id)
            elem_id.send_keys(Keys.CONTROL, 'v')
            time.sleep(1)

            elem_pw = driver.find_element(By.ID, 'pw')
            elem_pw.click()
            pyperclip.copy(naver_pw)
            elem_pw.send_keys(Keys.CONTROL, 'v')
            time.sleep(1)

            driver.find_element(By.ID, 'log.login').click()
            time.sleep(1)
            driver.find_element(By.ID, 'new.dontsave').click()
        except Exception as e:
            print(f"로그인 오류: {str(e)}")
            
MainView.login(driver, url)

 

 

1-1. 우선 로그인하기 위해, [ Naver 로그인 ] 버튼 element를 찾아서 클릭한다.

1-2. 아이디와 비밀번호 입력 칸에 해당하는 element를 찾아서 값들을 입력한다.

* 아이디와 비밀번호는 .env 파일에서 따로 관리

1-3. [ 로그인 ] 버튼을 클릭해서 자동으로 로그인을 완료한다.

 

 

for i in range(2, 10):
      url=f"https://section.blog.naver.com/BlogHome.naver?directoryNo=0&currentPage={i}&groupId=0"
      MainView.collect_info(driver, url)

 

 

For문을 통해서 여러 페이지를 접속할 수 있도록 하고

collect_info 함수를 통해서 좋아요 클릭도 하고 각 게시글의 정보들을 수집한다.

 

article_container = WebDriverWait(driver, 3).until(
        EC.presence_of_element_located((By.CLASS_NAME, "list_post_article.list_post_article_comments"))
)

items = article_container.find_elements(By.CLASS_NAME, "item.multi_pic")
total = 1

for item in items:
    time.sleep(1)
    try:
        off_button = item.find_elements(By.CSS_SELECTOR, ".u_likeit_list_module a.u_likeit_list_btn._button.off")
        if off_button:
            off_button[0].click()
        time.sleep(2)

    except Exception as e:
        print(f"아이템 클릭 중 오류 발생: {total} 번째")
        continue

 

 

article들이 있는 element를 찾고 해당 리스트에서 하나씩 좋아요 버튼에 접근을 하면서

"좋아요" 버튼이 off가 되어있을 경우에는 클릭을 하도록 구현했다.

 

 

 

이 과정에서 목적에 따라 링크나 글 내용 등을 추가적으로 수집 가능하다.

반응형