title 추가
This commit is contained in:
parent
6f7a6249eb
commit
d7ddac9162
34
config.ini
34
config.ini
|
|
@ -39,9 +39,39 @@ leading_text_6 = "**반드시 옵션사진과 옵션이름을 확인하시고
|
||||||
leading_text_7 = "---"
|
leading_text_7 = "---"
|
||||||
# 필요한 만큼 추가 가능
|
# 필요한 만큼 추가 가능
|
||||||
|
|
||||||
[ProductNameLocators]
|
[TitleLocators]
|
||||||
product_name_input_locator = //*[@id='productMainContentContainerId']/div/div[1]/div/div/div[1]/input
|
|
||||||
|
|
||||||
|
# 상품명 관련 선택자
|
||||||
|
product_name_input_locator = //*[@id='productMainContentContainerId']/div/div[1]/div[5]/div[1]/span/input
|
||||||
|
product_name_input_css_path = 'div#productMainContentContainerId div:nth-child(5) > div:nth-child(1) > span > input'
|
||||||
|
|
||||||
|
# 상품명 추천단어 입력칸 선택자
|
||||||
|
product_name_suggestion_input_locator = //*[@id="productMainContentContainerId"]/div/div[1]/div[2]/div[2]/div/span/span/span[1]/input
|
||||||
|
product_name_suggestion_input_css_path = 'div#productMainContentContainerId div:nth-child(2) > div:nth-child(2) > div > span > span > span.ant-input-affix-wrapper.css-1li46mu.ant-input-outlined > input'
|
||||||
|
|
||||||
|
# 상품명 추천단어 입력 검색 버튼 선택자
|
||||||
|
product_name_search_button_locator = //*[@id="productMainContentContainerId"]/div/div[1]/div[2]/div[2]/div/span/span/span[2]/button
|
||||||
|
product_name_search_button_css_path = 'div#productMainContentContainerId div:nth-child(2) > div:nth-child(2) > div > span > span > span.ant-input-group-addon > button[type="button"]'
|
||||||
|
|
||||||
|
# 원본 상품명 선택자
|
||||||
|
original_product_name_locator = //*[@id="productMainContentContainerId"]/div/div[1]/div[6]/div[1]/div/span
|
||||||
|
original_product_name_css_path = 'div#productMainContentContainerId div.sc-aNeao.tNLFa > div.ant-flex.css-1li46mu.ant-flex-align-stretch.ant-flex-vertical > div:nth-child(1) > div > span'
|
||||||
|
|
||||||
|
# 상품명의 경고단어 삭제 버튼 선택자
|
||||||
|
product_name_warning_delete_button_locator = //*[@id="productMainContentContainerId"]/div/div[1]/div[6]/div[3]/div[2]/div/button
|
||||||
|
product_name_warning_delete_button_css_path = 'div#productMainContentContainerId div:nth-child(2) > div > button[type="button"]'
|
||||||
|
|
||||||
|
# 카테고리 관련 선택자
|
||||||
|
category_suggestion_button_locator = //*[@id='productMainContentContainerId']/div/div[1]/div[5]/div[2]/button
|
||||||
|
category_suggestion_button_css_path = 'div#productMainContentContainerId div:nth-child(2) > button[type="button"]'
|
||||||
|
|
||||||
|
# 카테고리 선택자 - 인증 여부에 따른 분기
|
||||||
|
category_main_selector_with_cp = '#productMainContentContainerId .ant-select.ant-select-outlined.css-1li46mu.ant-select-single.ant-select-show-arrow:nth-of-type(1)'
|
||||||
|
category_main_selector_with_ss = '#productMainContentContainerId .ant-select.ant-select-outlined.css-1li46mu.ant-select-single.ant-select-show-arrow:nth-of-type(2)'
|
||||||
|
category_main_selector_with_esm = '#productMainContentContainerId .ant-select.ant-select-outlined.css-1li46mu.ant-select-single.ant-select-show-arrow:nth-of-type(3)'
|
||||||
|
category_certified_text_locator = div.ant-col.css-1li46mu:nth-child(1)
|
||||||
|
category_text_with_certification_locator = div.ant-col.css-1li46mu:nth-child(2)
|
||||||
|
category_text_without_certification_locator = div.ant-col.css-1li46mu:nth-child(1)
|
||||||
|
|
||||||
[BrowserControl]
|
[BrowserControl]
|
||||||
# 크롬 창 이름
|
# 크롬 창 이름
|
||||||
|
|
|
||||||
10
gui.py
10
gui.py
|
|
@ -716,11 +716,11 @@ class TranslationApp(QWidget):
|
||||||
|
|
||||||
self.logger.debug(f'{index}/{len(product_buttons)}: 세부사항 수정 작업 중...')
|
self.logger.debug(f'{index}/{len(product_buttons)}: 세부사항 수정 작업 중...')
|
||||||
|
|
||||||
# 상품명 수집 및 수집 오류 처리
|
# # 상품명 수집 및 수집 오류 처리
|
||||||
product_name = await self.browser_controller.get_product_name(index, 'css')
|
# product_name = await self.browser_controller.get_product_name(index, 'css')
|
||||||
if product_name == "수집 오류 발생":
|
# if product_name == "수집 오류 발생":
|
||||||
self.logger.debug('상품 수집 오류, 다음 상품으로 넘어갑니다.')
|
# self.logger.debug('상품 수집 오류, 다음 상품으로 넘어갑니다.')
|
||||||
continue
|
# continue
|
||||||
|
|
||||||
# 상품 수정 다이얼로그 열기
|
# 상품 수정 다이얼로그 열기
|
||||||
await self.browser_controller.open_product_edit_dialog(button)
|
await self.browser_controller.open_product_edit_dialog(button)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
import asyncio
|
||||||
|
from playwright.async_api import async_playwright
|
||||||
|
from PySide6.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget, QMessageBox
|
||||||
|
from qasync import QEventLoop
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class CategoryHandler:
|
||||||
|
def __init__(self, page):
|
||||||
|
self.page = page
|
||||||
|
|
||||||
|
async def handle_category_action(self):
|
||||||
|
# #productMainContentContainerId 내부에서 클래스 이름 "ant-select ant-select-outlined css-1li46mu ant-select-single ant-select-show-arrow"를 포함한 요소 중 두 번째 요소 찾기
|
||||||
|
print("[DEBUG] handle_category_action: Locating category container element...")
|
||||||
|
category_locator = "div#productMainContentContainerId div.ant-select.ant-select-outlined.css-1li46mu.ant-select-single.ant-select-show-arrow >> nth=1"
|
||||||
|
|
||||||
|
try:
|
||||||
|
await self.page.wait_for_selector(category_locator, timeout=5000)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[ERROR] handle_category_action: Timed out waiting for category container element. Error: {e}")
|
||||||
|
QMessageBox.information(None, "결과", f"카테고리 컨테이너 요소를 찾는 데 실패했습니다: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
category_element = self.page.locator(category_locator)
|
||||||
|
count = await category_element.count()
|
||||||
|
print(f"[DEBUG] handle_category_action: Number of elements found with locator '{category_locator}': {count}")
|
||||||
|
if count == 0:
|
||||||
|
print(f"[ERROR] handle_category_action: Category container element not found using locator '{category_locator}'!")
|
||||||
|
QMessageBox.information(None, "결과", "카테고리 컨테이너 요소를 찾을 수 없습니다.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# "인증필요"와 카테고리 텍스트 추출
|
||||||
|
print("[DEBUG] handle_category_action: Extracting '인증필요' and category text...")
|
||||||
|
certification_text = ""
|
||||||
|
category_text = ""
|
||||||
|
|
||||||
|
try:
|
||||||
|
cert_needed_locator = category_element.locator("div.ant-col.css-1li46mu:nth-child(1)")
|
||||||
|
certification_text = await cert_needed_locator.inner_text()
|
||||||
|
print(f"[DEBUG] handle_category_action: Certification text found - '{certification_text}'")
|
||||||
|
if "인증필요" in certification_text:
|
||||||
|
# 인증필요가 있는 경우 두 번째 요소가 카테고리 텍스트
|
||||||
|
category_text_locator = category_element.locator("div.ant-col.css-1li46mu:nth-child(2)")
|
||||||
|
category_text = await category_text_locator.inner_text()
|
||||||
|
else:
|
||||||
|
# 인증필요가 없는 경우 첫 번째 요소가 카테고리 텍스트
|
||||||
|
category_text = certification_text
|
||||||
|
certification_text = "" # 인증필요가 없으므로 초기화
|
||||||
|
except Exception:
|
||||||
|
# 인증필요가 없는 경우 첫 번째 요소가 카테고리 텍스트
|
||||||
|
print("[DEBUG] handle_category_action: Certification text not found. Assuming first element is category text.")
|
||||||
|
category_text_locator = category_element.locator("div.ant-col.css-1li46mu:nth-child(1)")
|
||||||
|
category_text = await category_text_locator.inner_text()
|
||||||
|
|
||||||
|
full_text = f"{certification_text} {category_text}".strip()
|
||||||
|
print(f"[DEBUG] handle_category_action: Full text - '{full_text}'")
|
||||||
|
QMessageBox.information(None, "검색 결과", f"카테고리 텍스트: {full_text}")
|
||||||
|
|
||||||
|
# 카테고리 텍스트에 '인증'이라는 단어가 포함되어 있는지 검사
|
||||||
|
if "인증" in full_text:
|
||||||
|
print("[INFO] 인증 필요 카테고리입니다. 인증 절차를 진행합니다.")
|
||||||
|
# 인증이 필요한 경우 수행할 작업
|
||||||
|
await self.perform_certification_action()
|
||||||
|
else:
|
||||||
|
print("[INFO] 인증이 필요하지 않은 카테고리입니다.")
|
||||||
|
# 인증이 필요하지 않은 경우 수행할 작업
|
||||||
|
await self.perform_standard_action()
|
||||||
|
|
||||||
|
async def perform_certification_action(self):
|
||||||
|
# 인증 절차를 진행하는 코드 작성
|
||||||
|
print("[DEBUG] perform_certification_action: Starting certification process...")
|
||||||
|
# 예시: 특정 버튼 클릭하기
|
||||||
|
await self.page.click("button:has-text('인증 시작')")
|
||||||
|
print("[INFO] perform_certification_action: Certification process completed.")
|
||||||
|
|
||||||
|
async def perform_standard_action(self):
|
||||||
|
# 인증이 필요하지 않은 경우의 일반적인 작업 코드 작성
|
||||||
|
print("[DEBUG] perform_standard_action: Performing standard action...")
|
||||||
|
# 예시: 다음 단계로 이동
|
||||||
|
await self.page.click("button:has-text('다음 단계')")
|
||||||
|
print("[INFO] perform_standard_action: Standard action completed.")
|
||||||
|
|
||||||
|
async def run_playwright():
|
||||||
|
print("[DEBUG] run_playwright: Launching Playwright...")
|
||||||
|
playwright = await async_playwright().start()
|
||||||
|
browser = await playwright.chromium.launch(headless=False)
|
||||||
|
page = await browser.new_page()
|
||||||
|
print("[DEBUG] run_playwright: Navigating to https://www.percenty.co.kr...")
|
||||||
|
await page.goto("https://www.percenty.co.kr") # 실제 페이지 URL로 변경하세요
|
||||||
|
print("[INFO] run_playwright: Page loaded successfully.")
|
||||||
|
return page, browser, playwright
|
||||||
|
|
||||||
|
class MainWindow(QWidget):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.setWindowTitle("Playwright 테스트")
|
||||||
|
self.setGeometry(100, 100, 400, 300)
|
||||||
|
self.page = None
|
||||||
|
self.browser = None
|
||||||
|
self.playwright = None
|
||||||
|
|
||||||
|
# 버튼 생성
|
||||||
|
self.init_button = QPushButton("Playwright 실행")
|
||||||
|
self.init_button.clicked.connect(self.run_playwright_button)
|
||||||
|
|
||||||
|
self.check_button = QPushButton("요소 검사 및 메시지 출력")
|
||||||
|
self.check_button.clicked.connect(self.check_category_button)
|
||||||
|
self.check_button.setEnabled(False)
|
||||||
|
|
||||||
|
# 레이아웃 설정
|
||||||
|
layout = QVBoxLayout()
|
||||||
|
layout.addWidget(self.init_button)
|
||||||
|
layout.addWidget(self.check_button)
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
def run_playwright_button(self):
|
||||||
|
print("[DEBUG] run_playwright_button: Playwright 실행 버튼 클릭됨.")
|
||||||
|
asyncio.create_task(self.init_playwright())
|
||||||
|
|
||||||
|
async def init_playwright(self):
|
||||||
|
print("[DEBUG] init_playwright: Initializing Playwright...")
|
||||||
|
self.page, self.browser, self.playwright = await run_playwright()
|
||||||
|
self.check_button.setEnabled(True)
|
||||||
|
print("[INFO] init_playwright: Playwright initialized and check button enabled.")
|
||||||
|
|
||||||
|
def check_category_button(self):
|
||||||
|
if self.page:
|
||||||
|
print("[DEBUG] check_category_button: 요소 검사 버튼 클릭됨.")
|
||||||
|
asyncio.create_task(self.handle_category_action())
|
||||||
|
|
||||||
|
async def handle_category_action(self):
|
||||||
|
print("[DEBUG] handle_category_action: Handling category action...")
|
||||||
|
handler = CategoryHandler(self.page)
|
||||||
|
await handler.handle_category_action()
|
||||||
|
print("[INFO] handle_category_action: Category check completed.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("[DEBUG] Main: Starting application...")
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
loop = QEventLoop(app)
|
||||||
|
asyncio.set_event_loop(loop)
|
||||||
|
|
||||||
|
window = MainWindow()
|
||||||
|
window.show()
|
||||||
|
|
||||||
|
with loop:
|
||||||
|
sys.exit(loop.run_forever())
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
class TitleHandler:
|
||||||
|
"""
|
||||||
|
TitleHandler 클래스는 상품명과 카테고리 관련 정보를 처리하는 역할을 합니다.
|
||||||
|
다양한 선택자를 사용하여 웹 페이지에서 상품명, 추천 단어, 카테고리 등을 수집하고 입력하는 기능을 제공합니다.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
page (Page): Playwright의 페이지 객체로, 브라우저와의 상호작용을 담당합니다.
|
||||||
|
logger (Logger): 로깅을 위한 Logger 객체입니다.
|
||||||
|
"""
|
||||||
|
def __init__(self, page, logger, locator_manager):
|
||||||
|
self.page = 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_name_locator = self.locator_manager.get_locator('TitleLocators', 'original_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.main_category_locator_with_cp = self.locator_manager.get_locator('TitleLocators', 'category_main_selector_with_cp')
|
||||||
|
self.main_category_locator_with_ss = self.locator_manager.get_locator('TitleLocators', 'category_main_selector_with_ss')
|
||||||
|
self.main_category_locator_with_esm = self.locator_manager.get_locator('TitleLocators', 'category_main_selector_with_esm')
|
||||||
|
self.certified_text_locator = self.locator_manager.get_locator('TitleLocators', 'certified_text_locator')
|
||||||
|
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')
|
||||||
|
|
||||||
|
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_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(self, market) -> str:
|
||||||
|
"""
|
||||||
|
카테고리를 가져오는 메서드로 인증 필요 여부에 따라 카테고리 선택자를 다르게 처리합니다.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: 카테고리 텍스트
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
self.logger.debug("카테고리 텍스트를 가져오는 중입니다.")
|
||||||
|
if market == 'ss':
|
||||||
|
main_category_element = await self.page.query_selector(self.main_category_locator_with_ss)
|
||||||
|
self.logger.debug(f"선택 마켓 : 스마트스토어")
|
||||||
|
elif market == 'cp':
|
||||||
|
main_category_element = await self.page.query_selector(self.main_category_locator_with_cp)
|
||||||
|
self.logger.debug(f"선택 마켓 : 쿠팡")
|
||||||
|
elif market == 'esm':
|
||||||
|
main_category_element = await self.page.query_selector(self.main_category_locator_with_esm)
|
||||||
|
self.logger.debug(f"선택 마켓 : ESM")
|
||||||
|
if not main_category_element:
|
||||||
|
self.logger.error("카테고리 메인 선택자를 찾을 수 없습니다.")
|
||||||
|
return ""
|
||||||
|
|
||||||
|
certified_text_element = await main_category_element.query_selector(self.certified_text_locator)
|
||||||
|
if certified_text_element:
|
||||||
|
certified_text = await certified_text_element.inner_text()
|
||||||
|
if "인증" in certified_text:
|
||||||
|
category_text_element = await main_category_element.query_selector(self.category_text_locator_certified)
|
||||||
|
self.logger.debug(f"카테고리 인증 필요 발생: {category_text}")
|
||||||
|
else:
|
||||||
|
category_text_element = certified_text_element
|
||||||
|
category_text = await 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 ""
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
상품명 / 카테고리
|
||||||
|
|
||||||
|
상품명 추천단어 입력칸의 요소
|
||||||
|
<input placeholder="직접 검색하기" maxlength="100" class="ant-input css-1li46mu" type="text" value="">
|
||||||
|
상품명 추천단어 입력칸의 css
|
||||||
|
#productMainContentContainerId > div > div.sc-aNeao.tNLFa > div:nth-child(2) > div:nth-child(2) > div > span > span > span.ant-input-affix-wrapper.css-1li46mu.ant-input-outlined > input
|
||||||
|
css path
|
||||||
|
"div#productMainContentContainerId div:nth-child(2) > div:nth-child(2) > div > span > span > span.ant-input-affix-wrapper.css-1li46mu.ant-input-outlined > input"
|
||||||
|
xpath
|
||||||
|
//*[@id="productMainContentContainerId"]/div/div[1]/div[2]/div[2]/div/span/span/span[1]/input
|
||||||
|
|
||||||
|
상품명 추천단어 입력 검색버튼 요소
|
||||||
|
<button type="button" class="ant-btn css-1li46mu ant-btn-default ant-btn-icon-only ant-input-search-button"><span class="ant-btn-icon"><span role="img" aria-label="search" class="anticon anticon-search"><svg viewBox="64 64 896 896" focusable="false" data-icon="search" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"></path></svg></span></span></button>
|
||||||
|
상품명 추천단어 입력 검색버튼 css
|
||||||
|
#productMainContentContainerId > div > div.sc-aNeao.tNLFa > div:nth-child(2) > div:nth-child(2) > div > span > span > span.ant-input-group-addon > button
|
||||||
|
상품명 추천단어 입력 검색버튼 css path
|
||||||
|
"div#productMainContentContainerId div:nth-child(2) > div:nth-child(2) > div > span > span > span.ant-input-group-addon > button[type=\"button\"]"
|
||||||
|
상품명 추천단어 입력 검색버튼 xpath
|
||||||
|
//*[@id="productMainContentContainerId"]/div/div[1]/div[2]/div[2]/div/span/span/span[2]/button
|
||||||
|
|
||||||
|
카테고리 추천받기 버튼 요소
|
||||||
|
<button type="button" class="ant-btn css-1li46mu ant-btn-primary ant-btn-background-ghost"><span>카테고리 추천 받기</span></button>
|
||||||
|
카테고리 추천받기 버튼 css
|
||||||
|
#productMainContentContainerId > div > div.sc-aNeao.tNLFa > div:nth-child(5) > div:nth-child(2) > button
|
||||||
|
카테고리 추천받기 버튼 css path
|
||||||
|
"div#productMainContentContainerId div:nth-child(2) > button[type=\"button\"]"
|
||||||
|
카테고리 추천받기 버튼 xpath
|
||||||
|
//*[@id="productMainContentContainerId"]/div/div[1]/div[5]/div[2]/button
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
노출상품명 입력칸
|
||||||
|
//*[@id="productMainContentContainerId"]/div/div[1]/div[5]/div[1]/span/input
|
||||||
|
"div#productMainContentContainerId div:nth-child(5) > div:nth-child(1) > span > input"
|
||||||
|
<input class="ant-input css-1li46mu" type="text" value="Huali 공동 브랜드 Jade Gui Dog 여자 신발 2024 봄 가을 한정판 만화 스타일 아동 스포츠 편안한 운동화">
|
||||||
|
|
||||||
|
원본상품명
|
||||||
|
//*[@id="productMainContentContainerId"]/div/div[1]/div[6]/div[1]/div/span
|
||||||
|
"div#productMainContentContainerId div.sc-aNeao.tNLFa > div.ant-flex.css-1li46mu.ant-flex-align-stretch.ant-flex-vertical > div:nth-child(1) > div > span"
|
||||||
|
<span class="sc-fremEr TIBrr Body3Regular14 CharacterSecondary45">回力联名玉桂狗女童鞋2024春秋季限量卡通款小孩儿童运动舒适板鞋</span>
|
||||||
|
|
||||||
|
상품명의 경고단어 삭제 버튼
|
||||||
|
//*[@id="productMainContentContainerId"]/div/div[1]/div[6]/div[3]/div[2]/div/button
|
||||||
|
"div#productMainContentContainerId div:nth-child(2) > div > button[type=\"button\"]"
|
||||||
|
<button type="button" class="ant-btn css-1li46mu ant-btn-text ant-btn-sm"><span>삭제하기</span></button>
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue