class TitleHandler: """ TitleHandler 클래스는 상품명과 카테고리 관련 정보를 처리하는 역할을 합니다. 다양한 선택자를 사용하여 웹 페이지에서 상품명, 추천 단어, 카테고리 등을 수집하고 입력하는 기능을 제공합니다. Attributes: page (Page): Playwright의 페이지 객체로, 브라우저와의 상호작용을 담당합니다. logger (Logger): 로깅을 위한 Logger 객체입니다. """ def __init__(self, locator_manager, browser_controller, logger): self.browser_controller = browser_controller self.page = self.browser_controller.page self.logger = logger self.locator_manager = locator_manager # 선택자 로드 self.product_name_input_locator = self.locator_manager.get_locator('TitleLocators', 'product_name_input_locator') self.suggestion_input_locator = self.locator_manager.get_locator('TitleLocators', 'suggestion_input_locator') self.search_button_locator = self.locator_manager.get_locator('TitleLocators', 'search_button_locator') self.original_product_name_locator = self.locator_manager.get_locator('TitleLocators', 'original_product_name_locator') self.delete_warning_button_locator = self.locator_manager.get_locator('TitleLocators', 'delete_warning_button_locator') self.category_suggestion_button_locator = self.locator_manager.get_locator('TitleLocators', 'category_suggestion_button_locator') self.category_main_selector_with_cp = self.locator_manager.get_locator('TitleLocators', 'category_main_selector_with_cp') self.category_main_selector_with_ss = self.locator_manager.get_locator('TitleLocators', 'category_main_selector_with_ss') self.category_main_selector_with_esm = self.locator_manager.get_locator('TitleLocators', 'category_main_selector_with_esm') self.category_text_locator = self.locator_manager.get_locator('TitleLocators', 'category_text_locator') self.category_text_locator_certified = self.locator_manager.get_locator('TitleLocators', 'category_text_locator_certified') def update_page(self, page1): self.page = page1 self.logger.debug(f"page객체 업데이트 : {page1}") async def get_product_name(self) -> str: """ 노출상품명 입력칸에서 상품명을 가져오는 메서드입니다. Returns: str: 상품명 텍스트 """ try: self.logger.debug("노출상품명 입력칸에서 상품명을 가져오는 중입니다.") product_name_element = await self.page.query_selector(self.product_name_input_locator) product_name = await product_name_element.get_attribute('value') if product_name_element else "" self.logger.debug(f"상품명: {product_name}") return product_name except Exception as e: self.logger.error(f"상품명 가져오기 중 오류 발생: {e}", exc_info=True) return "" async def enter_product_name_suggestion(self, suggestion: str): """ 상품명 추천단어를 입력칸에 입력하는 메서드입니다. Args: suggestion (str): 입력할 추천 단어 """ try: self.logger.debug(f"추천 단어를 상품명 추천 입력칸에 입력 중: {suggestion}") suggestion_input_element = await self.page.query_selector(self.suggestion_input_locator) if suggestion_input_element: await suggestion_input_element.fill(suggestion) self.logger.debug(f"추천 단어 '{suggestion}' 입력 완료.") else: self.logger.error("추천 입력칸 요소를 찾을 수 없습니다.") except Exception as e: self.logger.error(f"추천 입력 단어 입력 중 오류 발생: {e}", exc_info=True) async def click_product_name_search_button(self): """ 상품명 추천단어 입력칸의 검색 버튼을 클릭하는 메서드입니다. """ try: self.logger.debug("상품명 추천단어 검색 버튼 클릭 중.") search_button_element = await self.page.query_selector(self.search_button_locator) if search_button_element: await search_button_element.click() self.logger.debug("검색 버튼 클릭 완료.") else: self.logger.error("검색 버튼 요소를 찾을 수 없습니다.") except Exception as e: self.logger.error(f"상품명 추천 검색 버튼 클릭 중 오류 발생: {e}", exc_info=True) async def get_original_product_name(self) -> str: """ 원본 상품명을 가져오는 메서드입니다. Returns: str: 원본 상품명 텍스트 """ try: self.logger.debug("원본 상품명을 가져오는 중입니다.") original_name_element = await self.page.query_selector(self.original_product_name_locator) original_name = await original_name_element.inner_text() if original_name_element else "" self.logger.debug(f"원본 상품명: {original_name}") return original_name except Exception as e: self.logger.error(f"원본 상품명 가져오기 중 오류 발생: {e}", exc_info=True) return "" async def delete_warning_word_in_product_name(self): """ 상품명에서 경고 단어를 삭제하는 버튼을 클릭하는 메서드입니다. """ try: self.logger.debug("경고 단어 삭제 버튼 클릭 중입니다.") delete_button_element = await self.page.query_selector(self.delete_warning_button_locator) if delete_button_element: await delete_button_element.click() self.logger.debug("경고 단어 삭제 버튼 클릭 완료.") else: self.logger.error("경고 단어 삭제 버튼 요소를 찾을 수 없습니다.") except Exception as e: self.logger.error(f"경고 단어 삭제 버튼 클릭 중 오류 발생: {e}", exc_info=True) async def click_category_suggestion_button(self): """ 카테고리 추천받기 버튼을 클릭하는 메서드입니다. """ try: self.logger.debug("카테고리 추천받기 버튼 클릭 중입니다.") category_suggestion_button_element = await self.page.query_selector(self.category_suggestion_button_locator) if category_suggestion_button_element: await category_suggestion_button_element.click() self.logger.debug("카테고리 추천받기 버튼 클릭 완료.") else: self.logger.error("카테고리 추천받기 버튼 요소를 찾을 수 없습니다.") except Exception as e: self.logger.error(f"카테고리 추천받기 버튼 클릭 중 오류 발생: {e}", exc_info=True) async def get_category_ori(self, market='ss') -> str: """ 카테고리를 가져오는 메서드로 인증 필요 여부에 따라 카테고리 선택자를 다르게 처리합니다. Returns: str: 카테고리 텍스트 """ try: self.logger.debug(f"마켓 : {market} - 카테고리 텍스트를 가져오는 중입니다.") if market == 'ss': main_category_element = self.page.locator(self.category_main_selector_with_ss) self.logger.debug(f"선택 마켓 : 스마트스토어 , selector : {self.category_main_selector_with_ss}, element : {main_category_element}") elif market == 'cp': main_category_element = self.page.locator(self.category_main_selector_with_cp) self.logger.debug(f"선택 마켓 : 쿠팡 , selector : {self.category_main_selector_with_cp}, element : {main_category_element}") elif market == 'esm': main_category_element = self.page.locator(self.category_main_selector_with_esm) self.logger.debug(f"선택 마켓 : ESM , selector : {self.category_main_selector_with_esm}, element : {main_category_element}") if not main_category_element: self.logger.error("카테고리 메인 선택자를 찾을 수 없습니다.") return "" certified_text_element = main_category_element.locator(self.certified_text_locator) if certified_text_element: certified_text = certified_text_element.inner_text() if "인증" in certified_text: category_text_element = main_category_element.locator(self.category_text_locator_certified) self.logger.debug(f"카테고리 인증 필요 발생: {category_text}") else: category_text_element = certified_text_element category_text = category_text_element.inner_text() if category_text_element else "" self.logger.debug(f"카테고리 텍스트: {category_text}") return category_text else: self.logger.error("카테고리 인증 요소를 찾을 수 없습니다.") return "" except Exception as e: self.logger.error(f"카테고리 텍스트 가져오기 중 오류 발생: {e}", exc_info=True) return "" async def get_category(self, market='ss') -> str: """ 카테고리를 가져오는 메서드로 인증 필요 여부에 따라 카테고리 선택자를 다르게 처리합니다. Returns: str: 카테고리 텍스트 """ try: self.logger.debug(f"마켓 : {market} - 카테고리 텍스트를 가져오는 중입니다.") if market == 'ss': category_locator = self.category_main_selector_with_ss elif market == 'cp': category_locator = self.category_main_selector_with_cp elif market == 'esm': category_locator = self.category_main_selector_with_esm self.logger.debug(f"category_locator : {category_locator}") await self.page.wait_for_selector(category_locator, timeout=5000, state="attached") # 요소가 나타날 때까지 대기 main_category_element = self.page.locator(category_locator) # 대기 후 동기적으로 요소 가져오기 self.logger.debug(f"main_category_element : {main_category_element}") if not await main_category_element.count(): self.logger.error("카테고리 메인 선택자를 찾을 수 없습니다.") return "" # 인증 텍스트 요소 선택 category_text_element = main_category_element.locator(self.category_text_locator) self.logger.debug(f"category_text_element : {category_text_element}") if await category_text_element.count(): category_text = await category_text_element.inner_text() if "인증" in category_text: self.logger.debug(f"카테고리 인증 필요 발생 category_text = {category_text}") category_text_certified_element = main_category_element.locator(self.category_text_locator_certified) if await category_text_certified_element.count(): category_text = await category_text_certified_element.inner_text() self.logger.debug(f"인증 필요 카테고리 text = {category_text}") if "그룹상품" in category_text: self.logger.debug(f"카테고리 그룹상품 발생 category_text = {category_text}") category_text_certified_element = main_category_element.locator(self.category_text_locator_certified) if await category_text_certified_element.count(): category_text = await category_text_certified_element.inner_text() self.logger.debug(f"그룹상품 카테고리 text = {category_text}") else: self.logger.debug(f"카테고리 text = {category_text}") return category_text else: self.logger.error("카테고리 인증 요소를 찾을 수 없습니다.") return "" except Exception as e: self.logger.error(f"카테고리 텍스트 가져오기 중 오류 발생: {e}", exc_info=True) return ""