파이썬 셀레니움으로 잡플래닛 리뷰 데이터 크롤링하기

2026. 1. 18. 20:35·Python
반응형

우선, 잡플래닛 리뷰에 접근 가능한 아이디가 필요합니다.

USER_EMAIL = "___" : ID 입력하기
USER_PW = "___" : PW 입력하기
COMPANY_ID = "___" : 수집하고자하는 회사의 URL ID 확인하기

 

네이버를 예시로 들자면 해당 부분이 COMPNAY_ID이다

 

수집하는 데이터는 위 이미지에서 빨강 테두리에 해당하는 부분들을 수집

 

import time
import pandas as pd
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager

def scrape_jobplanet_perfect():
    USER_EMAIL = "___"
    USER_PW = "___"
    COMPANY_ID = "___"

    options = webdriver.ChromeOptions()
    options.add_argument("--disable-blink-features=AutomationControlled")
    driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
    wait = WebDriverWait(driver, 15)
    
    data = []

    try:
        # 1. 로그인
        driver.get("https://www.jobplanet.co.kr/user-session/sign-in")
        wait.until(EC.presence_of_element_located((By.NAME, "email"))).send_keys(USER_EMAIL)
        driver.find_element(By.NAME, "password").send_keys(USER_PW)
        driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()
        time.sleep(3)

        page = 1
        while True:
            print(f"🚀 페이지 {page} 수집 시도 중...")
            url = f"https://www.jobplanet.co.kr/companies/{COMPANY_ID}/reviews?page={page}"
            driver.get(url)
            time.sleep(4)

            # 팝업 제거
            try:
                popups = driver.find_elements(By.CSS_SELECTOR, "button[data-testid='close-button']")
                if popups:
                    popups[0].click()
                    time.sleep(1)
            except: pass

            soup = BeautifulSoup(driver.page_source, "html.parser")
            reviews = soup.select("section[id^='review_']")

            if not reviews:
                print("🏁 수집할 데이터가 없습니다. 종료합니다.")
                break

            for review in reviews:
                try:
                    # --- 1. 제목 추출 ---
                    title = review.select_one("h2.text-h7").get_text(strip=True) if review.select_one("h2.text-h7") else ""

                    # --- 2. 상단 정보 (직무, 상태, 지역, 작성일시) ---
                    # 이미지 3(image_25d140.png) 기준: span.text-body2 리스트에서 인덱스별로 추출
                    info_spans = review.select("div.flex.items-center span.text-body2")
                    job = info_spans[0].get_text(strip=True) if len(info_spans) > 0 else ""
                    status = info_spans[1].get_text(strip=True) if len(info_spans) > 1 else ""
                    location = info_spans[2].get_text(strip=True) if len(info_spans) > 2 else ""
                    
                    # 작성일시: 보통 4번째(인덱스 3) span에 위치
                    date_val = info_spans[3].get_text(strip=True) if len(info_spans) > 3 else ""
                    date_val = date_val.replace("작성", "").strip()

                    # --- 3. 평점 ---
                    # 수정 코드 (숫자형으로 변환)
                    rating_elem = review.select_one("span.text-h5")
                    if rating_elem:
                        try:
                            total_rating = float(rating_elem.get_text(strip=True)) # "3.0" -> 3.0 (실수 변환)
                        except ValueError:
                            total_rating = 0.0 # 변환 실패 시 기본값
                    else:
                        total_rating = 0.0

                    # --- 4. 장점/단점/경영진 바라는 점 (핵심 수정 부분) ---
                    pros, cons, wishes = "", "", ""
                    
                    # [해결!] mt-[20px]에 의존하지 않고, 'whitespace-pre-wrap' 클래스를 가진 모든 div를 찾음
                    content_blocks = review.select("div.whitespace-pre-wrap")
                    
                    for block in content_blocks:
                        label_elem = block.select_one("div.mr-\[8px\]")
                        if label_elem:
                            label_text = label_elem.get_text(strip=True)
                            # 레이블("장점" 등)을 제외한 실제 본문 텍스트만 추출
                            full_text = block.get_text(strip=True)
                            content_text = full_text.replace(label_text, "").strip()
                            
                            if "장점" in label_text:
                                pros = content_text
                            elif "단점" in label_text:
                                cons = content_text
                            elif "경영진" in label_text:
                                wishes = content_text

                    data.append({
                        "제목": title if title else None,
                        "직무": job if job else None,
                        "현/전 여부": status if status else None,
                        "지역": location if location else None,
                        "작성일시": date_val if date_val else None,
                        "평점": float(total_rating) if total_rating else None, # 숫자로 변환하며 null 처리
                        "장점": pros if pros else None,
                        "단점": cons if cons else None,
                        "경영진에게 바라는 점": wishes if wishes else None
                    })
                except Exception as e:
                    print(f"⚠️ 개별 리뷰 파싱 오류: {e}")
                    continue

            print(f"✅ {page}페이지 완료 (누적 {len(data)}건)")
            page += 1
            if page > 30: break 

    finally:
        if data:
            df = pd.DataFrame(data)
            # 수집된 열 순서 고정 (제목을 가장 앞으로)
            cols = ["제목", "직무", "현/전 여부", "지역", "작성일시", "평점", "장점", "단점", "경영진에게 바라는 점"]
            df = df[cols]
            file_name = f"jobplanet_final_result_{time.strftime('%Y%m%d_%H%M')}.xlsx"
            df.to_excel(file_name, index=False)
            print(f"📊 최종 수집 완료! 파일 저장됨: {file_name}")
        driver.quit()

if __name__ == "__main__":
    scrape_jobplanet_perfect()

 

if page >30: break -> 여기서 숫자를 조절하면서 수집할 페이지 숫자에 따라 조절하면 됩니다.

추가로 사용한 라이브러리들이 없다면 설치하고 진행하면 무리없이 동작할거라 생각합니다.

반응형
저작자표시 비영리 변경금지 (새창열림)

'Python' 카테고리의 다른 글

파이썬 ,(콤마) 빼기  (2) 2024.09.03
'Python' 카테고리의 다른 글
  • 파이썬 ,(콤마) 빼기
kimmalgu
kimmalgu
DA(데이터 분석가) 블로그
  • kimmalgu
    kimmalgu의 블로그
    kimmalgu
  • 전체
    오늘
    어제
    • 분류 전체보기 (56)
      • 📊통계 (3)
      • [패캠] 데이터분석 부트캠프 (10)
        • 프로젝트 (2)
        • 수업 정리 (8)
      • Python (9)
        • 통계전산처리 (7)
      • SQL (27)
        • 프로그래머스 (20)
        • HackerRank (5)
        • LeetCode (1)
      • 코테 (0)
      • 📖독후감 (7)
  • 블로그 메뉴

    • 글쓰기
    • 홈
    • 태그
    • 방명록
  • hELLO· Designed By정상우.v4.10.0
kimmalgu
파이썬 셀레니움으로 잡플래닛 리뷰 데이터 크롤링하기
상단으로

티스토리툴바