AutoPercenty3/test/pywinauto_test/lens_parser.py

107 lines
4.0 KiB
Python

import re
class ShoppingLensScraper:
def __init__(self, app, logger):
self.app = app
self.logger = logger
def extract_product_data(self, list_box):
"""
ListBox에서 제품 데이터를 추출합니다.
Args:
list_box: ListBox 객체
Returns:
list: 추출된 제품 정보의 리스트
"""
product_data = []
try:
# ListBox 내부의 모든 ListItem 순회
list_items = list_box.descendants(control_type="ListItem")
for item in list_items:
# 첫 번째 Hyperlink를 찾기
hyperlink = item.child_window(control_type="Hyperlink", found_index=0)
if hyperlink.exists():
title = hyperlink.window_text()
product_info = self.parse_product_info(title)
if product_info:
product_data.append(product_info)
except Exception as e:
self.logger.error(f"데이터 추출 중 오류 발생: {e}", exc_info=True)
return product_data
# @staticmethod
def parse_product_info(self, titles):
"""
쇼핑 렌즈 결과에서 상품 정보를 파싱합니다.
:param titles: Hyperlink title의 리스트
:return: 구조화된 상품 정보 리스트
"""
products = []
for title in titles:
try:
# 정규식으로 상품명, 가격, 배송비, 판매처 정보 추출
match = re.search(
r"(?P<name>.+?)\s(?P<price>최저\s[0-9,]+원|[0-9,]+원)\s(?P<shipping>무료|배송비\s무료|배송비\s[0-9,]+원)(?:\s판매처\s(?P<seller_count>\d+))?(?:\s별점\s(?P<rating>[0-9.]+))?",
title
)
if match:
product_info = {
"name": match.group("name"),
"price": match.group("price"),
"shipping": match.group("shipping"),
"seller_count": match.group("seller_count") or "1",
"rating": match.group("rating") or None,
}
# 필터링된 상품명에서 중복 제거
filtered_name = self._filter_duplicate_name(product_info["name"])
product_info["filtered_name"] = filtered_name
products.append(product_info)
else:
self.logger.warning(f"상품 정보를 파싱할 수 없습니다: {title}")
except Exception as e:
self.logger.error(f"상품 정보 파싱 중 오류 발생: {title} -> {e}", exc_info=True)
return products
@staticmethod
def _filter_duplicate_name(name):
"""
상품명에서 중복된 내용을 제거합니다.
:param name: 원본 상품명
:return: 중복 제거된 상품명
"""
words = name.split()
seen = set()
filtered_words = []
for word in words:
if word not in seen:
filtered_words.append(word)
seen.add(word)
return " ".join(filtered_words)
def filter_titles(self, titles):
"""
주어진 제목 리스트에서 '다른 사이트 더보기' 이후 '더보기' 이전의 데이터를 필터링합니다.
Args:
titles (list): 전체 제목 리스트
Returns:
list: 필터링된 제목 리스트
"""
try:
# 시작과 끝 인덱스를 찾기
start_index = titles.index("다른 사이트 더보기") + 1
end_index = titles.index("더보기")
# 필터링된 데이터 추출
filtered_titles = titles[start_index:end_index]
return filtered_titles
except ValueError as e:
# '다른 사이트 더보기' 또는 '더보기'가 없을 경우 예외 처리
self.logger.error(f"필터링 중 오류 발생: {e}")
return []