232 lines
12 KiB
Python
232 lines
12 KiB
Python
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 ""
|