import pandas as pd from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options # 필요 시 헤드리스 모드에서 사용 from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time # Chrome 드라이버 설정 driver = webdriver.Chrome() # URL에 접속 driver.get("https://www.bobaedream.co.kr/mycar/mycar_list.php?gubun=K") # 데이터를 저장할 리스트 data = [] try: # 1. 제조사 정보 추출 # 제조사 목록 가져오기 manufacturer_elements = driver.find_elements(By.CSS_SELECTOR, ".area-maker .group-list dd") manufacturer_count = len(manufacturer_elements) print(f"총 {manufacturer_count}개의 제조사를 찾았습니다.") for m_index in range(manufacturer_count): # 이전 클릭으로 인해 DOM이 변경될 수 있으므로 제조사 요소를 다시 가져옵니다. manufacturer_elements = driver.find_elements(By.CSS_SELECTOR, ".area-maker .group-list dd") manufacturer_element = manufacturer_elements[m_index] try: manufacturer_button = manufacturer_element.find_element(By.TAG_NAME, "button") manufacturer_name = manufacturer_button.find_element(By.CSS_SELECTOR, "span.t1").text print(f"제조사 선택: {manufacturer_name}") manufacturer_button.click() # 제조사 클릭 후 페이지가 로드될 때까지 대기 WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".area-model .group-list dd"))) # 2. 모델 정보 추출 model_elements = driver.find_elements(By.CSS_SELECTOR, ".area-model .group-list dd") model_count = len(model_elements) print(f" {manufacturer_name} 제조사에서 총 {model_count}개의 모델을 찾았습니다.") if model_elements: for mo_index in range(model_count): # 모델 요소를 다시 가져옵니다. model_elements = driver.find_elements(By.CSS_SELECTOR, ".area-model .group-list dd") model_element = model_elements[mo_index] try: model_button = model_element.find_element(By.TAG_NAME, "button") model_name = model_button.find_element(By.CSS_SELECTOR, "span.t1").text print(f" 모델 선택: {model_name}") model_button.click() # 3. 세부모델 정보 추출 WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".area-detail .group-list dd[class*='c_model_']"))) sub_model_elements = driver.find_elements(By.CSS_SELECTOR, ".area-detail .group-list dd[class*='c_model_']") sub_model_count = len(sub_model_elements) print(f" {model_name} 모델에서 총 {sub_model_count}개의 세부모델을 찾았습니다.") if sub_model_elements: for sm_index in range(sub_model_count): sub_model_elements = driver.find_elements(By.CSS_SELECTOR, ".area-detail .group-list dd[class*='c_model_']") sub_model_element = sub_model_elements[sm_index] # 보이는 세부모델만 선택 if sub_model_element.is_displayed(): sub_model_label = sub_model_element.find_element(By.CSS_SELECTOR, "label") sub_model_name = sub_model_label.text sub_model_checkbox = sub_model_element.find_element(By.CSS_SELECTOR, "input[type='checkbox']") is_checked = sub_model_checkbox.is_selected() if not is_checked: # 체크되지 않은 경우 클릭하여 선택 driver.execute_script("arguments[0].click();", sub_model_checkbox) print(f" 세부모델 선택: {sub_model_name}") else: print(f" 세부모델 이미 선택됨: {sub_model_name}") # 4. 등급 확인 try: grades = WebDriverWait(driver, 5).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".area-grade .group-list dd"))) except: grades = [] if grades: for grade in grades: grade_name = grade.find_element(By.CSS_SELECTOR, "label").text grade_count = grade.find_element(By.CSS_SELECTOR, "span.t2").text print(f" 등급: {grade_name}, 수량: {grade_count}") data.append([manufacturer_name, model_name, sub_model_name, grade_name, grade_count]) else: print(f" {sub_model_name} -> 등급 없음") data.append([manufacturer_name, model_name, sub_model_name, "등급 없음", "0"]) # 체크박스를 처음에 선택하지 않은 경우에만 해제 if not is_checked: driver.execute_script("arguments[0].click();", sub_model_checkbox) else: # 세부모델이 없는 경우 바로 등급 확인 try: grades = WebDriverWait(driver, 5).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".area-grade .group-list dd"))) except: grades = [] if grades: for grade in grades: grade_name = grade.find_element(By.CSS_SELECTOR, "label").text grade_count = grade.find_element(By.CSS_SELECTOR, "span.t2").text print(f" 등급: {grade_name}, 수량: {grade_count}") data.append([manufacturer_name, model_name, "", grade_name, grade_count]) else: print(f" {model_name} -> 등급 없음") data.append([manufacturer_name, model_name, "", "등급 없음", "0"]) except Exception as e: print(f" 모델 선택 오류: {e}") continue else: print(f"{manufacturer_name} 제조사에 모델이 없습니다.") # 제조사별로 데이터를 저장 df = pd.DataFrame(data, columns=['제조사', '모델', '세부모델', '등급', '수량']) df.to_excel(f"car_data_partial_{manufacturer_name}.xlsx", index=False) print(f"{manufacturer_name} 작업 완료: car_data_partial_{manufacturer_name}.xlsx 저장됨") # 다음 제조사로 이동하기 전에 이전 선택 초기화 # '초기화' 버튼 클릭 (있을 경우) reset_button = driver.find_element(By.CSS_SELECTOR, "button.btn-reset") reset_button.click() WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".area-maker .group-list dd"))) # 데이터 초기화 data = [] except Exception as e: print(f"제조사 선택 오류: {e}") continue except KeyboardInterrupt: print("Ctrl + C") finally: driver.quit() # 모든 작업 완료 후 전체 데이터를 엑셀 파일로 저장 df = pd.DataFrame(data, columns=['제조사', '모델', '세부모델', '등급', '수량']) df.to_excel("car_data_final.xlsx", index=False) print("엑셀 파일로 저장 완료: car_data_final.xlsx")