diff --git a/config.ini b/config.ini
deleted file mode 100644
index c9c0c9a..0000000
--- a/config.ini
+++ /dev/null
@@ -1,18 +0,0 @@
-[Settings]
-maxweightset = 10
-maxlengthset = 100
-maxvolumeset = 155
-addfeeinterval = 6
-addfeesetting = 3
-addfee = 2000
-fontsize = 14
-weightinterval = 0.5
-setsavesetting = True
-favoritedelv =
-
-[Kipris]
-use_kipris = True
-usage_mode = api
-api_key = X9Tz3JqC/JcCwxnNewA6qdloIN6QFIitVBgS1a2KVDYk1AmddaDTvzr6+t3dyLZV3gh2TPXdNhxsRQwaKP673Q==
-set_status = ['°ÅÀý', 'µî·Ï']
-
diff --git a/config.json b/config.json
index 302b194..f215ed7 100644
--- a/config.json
+++ b/config.json
@@ -6,19 +6,17 @@
"addFeeInterval": 5,
"addFeeSetting": 20,
"addFee": 1000,
- "fontSize": 10,
+ "fontSize": 12,
"weightInterval": 0.5,
"setSaveSetting": true,
"favoriteDelv": "\ub178\ube60\uafb8\ud574\uc6b4(\ubc30\uc1a1\ube44)"
},
"Kipris": {
"use_kipris": true,
- "usage_mode": "web",
- "api_key": "",
+ "usage_mode": "api",
+ "api_key": "X9Tz3JqC/JcCwxnNewA6qdloIN6QFIitVBgS1a2KVDYk1AmddaDTvzr6+t3dyLZV3gh2TPXdNhxsRQwaKP673Q==",
"set_status": [
- "\ub4f1\ub85d",
- "\ucde8\ud558",
- "\ud3ec\uae30"
+ "\ub4f1\ub85d"
]
}
}
\ No newline at end of file
diff --git a/delv.py b/delv.py
index 8fafa46..cd16ea2 100644
--- a/delv.py
+++ b/delv.py
@@ -14,9 +14,9 @@ from src.kipris_settingUI import SettingsDialog
from src.kipris_api_from_publicdata import Kipris_API
# from src.kipris_web_from_playwright import Kipris_WEB
from src.kiprisThread import *
-from src.search_display import TrademarkSearchDisplay
+# from src.search_display import TrademarkSearchDisplay
from src.result_widget import ResultWidget
-
+from src.currencyInfo import ExchangeRateScraper
def minimize_console():
""" 콘솔 ì°½ì„ ìµœì†Œí™”í•˜ëŠ” 함수 """
@@ -40,7 +40,8 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.asyncWorker = None
self.search_keyword = None
self.set_status =[]
-
+ self.web_scraper = None # ì›¹ë°©ì‹ Playwright ê°ì²´ 미리 초기화
+ self.currentURL = ""
self.config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.json')
self.maxWeightSet = 25
@@ -58,12 +59,12 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.addFeeSetting = 20
self.addFeeInterval = 5
-
self.setUSD = None
self.setCNY = None
- self.searchDisplay = TrademarkSearchDisplay()
+ self.currentCurrency = None
+ # self.searchDisplay = TrademarkSearchDisplay()
self.searchDisplayWidget = ResultWidget()
-
+ self.currencyInfoObject = ExchangeRateScraper()
self.favoriteDelv = ""
@@ -108,6 +109,14 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
}
self.settingDialog = SettingsDialog(parent=self, initial_settings=self.user_settings)
+ currencis = ['USD','CNY']
+ self.currencyInfoObject.getCurrency(currencis)
+ self.setUSD = self.currencyInfoObject.currencyInfo['USD']['basePrice']
+ logger.debug(f"setUSD : {self.setUSD}")
+ self.setCNY = self.currencyInfoObject.currencyInfo['CNY']['basePrice']
+ logger.debug(f"setCNY : {self.setCNY}")
+ self.currentCurrency = self.setCNY
+
def saveSettings(self):
""" ì„¤ì •ì„ JSON 파ì¼ì— ì €ìž¥í•©ë‹ˆë‹¤. """
try:
@@ -220,7 +229,7 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
# self.api_key = self.config.get('Kipris', 'api_key', fallback="")
# self.set_status = self.config.get('Kipris', 'set_status', fallback="[등ë¡]")
- # # print(f"use_kipris : {self.use_kipris}, usage_mode : {self.usage_mode}, api_key : {self.api_key}")
+ # # logger.debug(f"use_kipris : {self.use_kipris}, usage_mode : {self.usage_mode}, api_key : {self.api_key}")
# except Exception as e:
# logger.error(f"ì„¤ì •ì„ ë¶ˆëŸ¬ì˜¤ëŠ” 중 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤: {e}", exc_info=True)
@@ -283,17 +292,17 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
if keyword:
if keyword and keyword not in self.history: # ì¤‘ë³µëœ ê²€ìƒ‰ì–´ê°€ 아니면 추가
self.history.append(keyword)
- print(f"검색어 [{keyword}] ížˆìŠ¤í† ë¦¬ì— ì¶”ê°€")
+ logger.debug(f"검색어 [{keyword}] ížˆìŠ¤í† ë¦¬ì— ì¶”ê°€")
def load_history(self):
try:
with open("search_history.json", "r") as file:
self.history = json.load(file)
- print(f"self.history file loaded{self.history}")
+ logger.debug(f"self.history file loaded{self.history}")
except (FileNotFoundError, json.JSONDecodeError):
self.history = []
- print(f"self.history{self.history}")
+ logger.debug(f"self.history{self.history}")
def save_history(self):
with open("search_history.json", "w") as file:
@@ -599,7 +608,7 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.kipris_layout = QtWidgets.QHBoxLayout(self.kiprisWidget)
self.kiprisWidget.setLayout(self.kipris_layout)
self.kiprisWidget.setVisible(False)
- self.kipris_label = QtWidgets.QLabel("키프리스 검색")
+ self.kipris_label = QtWidgets.QLabel(f"키프리스 검색")
self.kipris_edit = QtWidgets.QLineEdit()
self.kipris_btn = QtWidgets.QPushButton("검색")
self.kipris_btn.clicked.connect(self.kipris_btn_clicked)
@@ -620,8 +629,8 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.addInfo_vlayout = QtWidgets.QVBoxLayout(self.addInfoWidget)
self.addInfo_h1layout = QtWidgets.QHBoxLayout()
self.addInfo_h2layout = QtWidgets.QHBoxLayout()
- self.addInfo_vlayout.addLayout(self.addInfo_h1layout)
self.addInfo_vlayout.addLayout(self.addInfo_h2layout)
+ self.addInfo_vlayout.addLayout(self.addInfo_h1layout)
self.addInfoWidget.setLayout(self.addInfo_vlayout)
self.addInfoWidget.setVisible(True)
self.setUSD_label = QtWidgets.QLabel(f"[{self.setUSD}]USD/KRW")
@@ -647,9 +656,11 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.addInfo2_btn.clicked.connect(self.addInfo2_btn_clicked)
self.addInfo_h2layout.addWidget(self.addInfo2_btn)
self.addInfo3_btn = QtWidgets.QPushButton("타ëƒì–´ë¡")
+ self.addInfo3_btn.setEnabled(False)
self.addInfo3_btn.clicked.connect(self.addInfo3_btn_clicked)
self.addInfo_h2layout.addWidget(self.addInfo3_btn)
self.addInfo4_btn = QtWidgets.QPushButton("딥러ë‹ë²ˆì—")
+ self.addInfo4_btn.setEnabled(False)
self.addInfo4_btn.clicked.connect(self.addInfo4_btn_clicked)
self.addInfo_h2layout.addWidget(self.addInfo4_btn)
# self.addInfo_layout.setStretch(0,3)
@@ -659,6 +670,35 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.setting_layout.addWidget(self.addInfoWidget) # self.addInfoWidget ì„¤ì • ë ˆì´ì•„ì›ƒì— ì¶”ê°€
+ # ê²½ë™íƒë°° 무게기준 ì¡°ì • 스핀박스
+ self.changeCurreny_btn = QtWidgets.QPushButton("CNY/KRW")
+ self.changeCurreny_btn.clicked.connect(self.changeCurreny_btn_clicked)
+
+ self.calcCurrency_label = QtWidgets.QLabel("")
+ self.calcCurrency_label.setText(" ì›")
+ self.calcCurrency_label.setAlignment(QtCore.Qt.AlignCenter)
+ calcCurrency_label_font = QFont()
+ calcCurrency_label_font.setBold(True) # 굵게
+ calcCurrency_label_font.setUnderline(True) # 밑줄
+ calcCurrency_label_font.setWeight(16) # í°íЏí¬ê¸°
+ self.calcCurrency_label.setFont(calcCurrency_label_font)
+
+ self.currency_calc_box = QtWidgets.QSpinBox()
+ self.currency_calc_box.setRange(0, 1000000)
+ self.currency_calc_box.setSingleStep(10)
+ self.currency_calc_box.setValue(100)
+ self.currency_calc_box.setSuffix(" CNY")
+ self.currency_calc_box.setAlignment(QtCore.Qt.AlignRight) # ê°€ìš´ë° ì •ë ¬
+ self.currency_calc_box.valueChanged.connect(self.calcCurrency)
+ self.currency_calc_box_layout = self.create_label_and_spin("환율", self.currency_calc_box)
+ self.currency_calc_box_layout.addWidget(self.calcCurrency_label)
+ self.currency_calc_box_layout.addWidget(self.changeCurreny_btn)
+ self.currency_calc_box_layout.setStretch(0,2)
+ self.currency_calc_box_layout.setStretch(1,4)
+ self.currency_calc_box_layout.setStretch(2,4)
+ self.currency_calc_box_layout.setStretch(3,2)
+ self.setting_layout.addLayout(self.currency_calc_box_layout)
+
# í•ìƒ ìœ„ì— í† ê¸€ 스위치
self.alwaysOnTopSwitch = ToggleSwitch(self.setting_frame)
self.alwaysOnTopSwitch.move(10, 10)
@@ -694,17 +734,17 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
# if current_type is not target_type:
# # 기존 ê°ì²´ê°€ 다른 타입ì´ë©´ ì‚ì œí•˜ê³ ìƒˆë¡œ ìƒì„±
- # print(f"기존 {self.kiprisAPI} ê°ì²´ë¥¼ ì‚ì œí•˜ê³ ìƒˆ ê°ì²´ë¥¼ ìƒì„±í•©ë‹ˆë‹¤.")
+ # logger.debug(f"기존 {self.kiprisAPI} ê°ì²´ë¥¼ ì‚ì œí•˜ê³ ìƒˆ ê°ì²´ë¥¼ ìƒì„±í•©ë‹ˆë‹¤.")
# self.kiprisAPI.close_Kipris() # 기존ê°ì²´ 리소스 ì •ë¦¬
# del self.kiprisAPI # 기존 ê°ì²´ 참조 ì œê±°
# self.kiprisAPI = target_type(self.api_key) # 새 ê°ì²´ ìƒì„±
- # print(f"{self.usage_mode.upper()} ë°©ì‹ kiprisAPI ê°ì²´ ìƒì„±: {self.kiprisAPI}")
+ # logger.debug(f"{self.usage_mode.upper()} ë°©ì‹ kiprisAPI ê°ì²´ ìƒì„±: {self.kiprisAPI}")
# else:
- # print(f"ê¸°ì¡´ì— ì ì ˆí•œ {self.kiprisAPI} ê°ì²´ê°€ ì´ë¯¸ 존재합니다.")
+ # logger.debug(f"ê¸°ì¡´ì— ì ì ˆí•œ {self.kiprisAPI} ê°ì²´ê°€ ì´ë¯¸ 존재합니다.")
# else:
# # ê°ì²´ê°€ 없으면 새로 ìƒì„±
# self.kiprisAPI = Kipris_API(self.api_key) if self.usage_mode == 'api' else Kipris_WEB(self.api_key)
- # print(f"{self.usage_mode.upper()} ë°©ì‹ kiprisAPI ê°ì²´ ìƒì„±: {self.kiprisAPI}")
+ # logger.debug(f"{self.usage_mode.upper()} ë°©ì‹ kiprisAPI ê°ì²´ ìƒì„±: {self.kiprisAPI}")
def initSettings_for_kipris(self):
if self.kiprisAPI:
@@ -714,7 +754,7 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
if current_type is not target_type:
# 기존 ê°ì²´ê°€ 다른 타입ì´ë©´ ì‚ì œí•˜ê³ ìƒˆë¡œ ìƒì„±
- print(f"기존 {self.kiprisAPI} ê°ì²´ë¥¼ ì‚ì œí•˜ê³ ìƒˆ ê°ì²´ë¥¼ ìƒì„±í•©ë‹ˆë‹¤.")
+ logger.debug(f"기존 {self.kiprisAPI} ê°ì²´ë¥¼ ì‚ì œí•˜ê³ ìƒˆ ê°ì²´ë¥¼ ìƒì„±í•©ë‹ˆë‹¤.")
if isinstance(self.kiprisAPI, AsyncWebSearchWorker):
self.kiprisAPI.deleteLater() # 비ë™ê¸° 작업ìžëŠ” Qt ê°ì²´ë¡œ 관리ë˜ë¯€ë¡œ deleteLater 사용
self.kiprisAPI = None
@@ -722,18 +762,20 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.kiprisAPI = Kipris_API(self.api_key) # 새 ê°ì²´ ìƒì„±
else:
web_scraper = WebScraper() # WebScraper ì¸ìŠ¤í„´ìŠ¤ ìƒì„±
- self.kiprisAPI = AsyncWebSearchWorker(web_scraper, "") # 초기 키워드는 비워ë‘기
- print(f"{self.usage_mode.upper()} ë°©ì‹ kiprisAPI ê°ì²´ ìƒì„±: {self.kiprisAPI}")
+ self.web_scraper = web_scraper
+ self.kiprisAPI = AsyncWebSearchWorker(self.web_scraper, "") # 초기 키워드는 비워ë‘기
+ logger.debug(f"{self.usage_mode.upper()} ë°©ì‹ kiprisAPI ê°ì²´ ìƒì„±: {self.kiprisAPI}")
else:
- print(f"ê¸°ì¡´ì— ì ì ˆí•œ {self.kiprisAPI} ê°ì²´ê°€ ì´ë¯¸ 존재합니다.")
+ logger.debug(f"ê¸°ì¡´ì— ì ì ˆí•œ {self.kiprisAPI} ê°ì²´ê°€ ì´ë¯¸ 존재합니다.")
else:
# ê°ì²´ê°€ 없으면 새로 ìƒì„±
if self.usage_mode == 'api':
self.kiprisAPI = Kipris_API(self.api_key)
else:
web_scraper = WebScraper() # WebScraper ì¸ìŠ¤í„´ìŠ¤ ìƒì„±
+ self.web_scraper = web_scraper
self.kiprisAPI = AsyncWebSearchWorker(web_scraper, "") # 초기 키워드는 비워ë‘기
- print(f"{self.usage_mode.upper()} ë°©ì‹ kiprisAPI ê°ì²´ ìƒì„±: {self.kiprisAPI}")
+ logger.debug(f"{self.usage_mode.upper()} ë°©ì‹ kiprisAPI ê°ì²´ ìƒì„±: {self.kiprisAPI}")
def addInfo1_btn_clicked(self):
pass
@@ -761,6 +803,7 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
if self.use_kipris:
self.kiprisWidget.setVisible(True)
self.initSettings_for_kipris()
+ self.kipris_label.setText(f"키프리스 검색({self.usage_mode})")
else:
self.kiprisWidget.setVisible(False)
@@ -1061,6 +1104,26 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
self.addFeeInterval = value
self.updateDeliveryFee()
+ def changeCurreny_btn_clicked(self):
+ selected = self.changeCurreny_btn.text()
+ if selected == 'CNY/KRW':
+ self.currency_calc_box.setSuffix(" USD")
+ self.changeCurreny_btn.setText('USD/KRW')
+ self.currentCurrency = self.setUSD
+ else:
+ self.currency_calc_box.setSuffix(" CNY")
+ self.changeCurreny_btn.setText('CNY/KRW')
+ self.currentCurrency = self.setCNY
+ self.calcCurrency(100)
+
+ def calcCurrency(self,value):
+ result = value * self.currentCurrency
+ result = round(result,0)
+ result = '{0:,}'.format(result)
+ # logger.debug(f"result{result}")
+ # logger.debug(f"round(result,2){str(round(result,0))}")
+ self.calcCurrency_label.setText(result+' ì›')
+
def isSaveSetting(self, state):
if state:
self.setSaveSetting = True
@@ -1075,10 +1138,10 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
logger.debug(f"키프리스 검색버튼 í´ë¦ : 키워드 = [{self.search_keyword}]")
# result = self.kiprisAPI.run(self.search_keyword, self.set_status)
- # print(f"result {result}")
+ # logger.debug(f"result {result}")
if self.search_keyword.strip(): # 검색어가 비어있지 ì•Šì€ ê²½ìš°ì—ë§Œ 검색 수행
- print(f"검색 í˜¸ì¶œë°©ì‹ : {self.usage_mode}")
+ logger.debug(f"검색 í˜¸ì¶œë°©ì‹ : {self.usage_mode}")
if self.usage_mode == 'web':
self.handle_search_for_web(self.search_keyword)
if self.usage_mode == 'api':
@@ -1089,16 +1152,17 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
if self.asyncWorker: # ê¸°ì¡´ì— ë¹„ë™ê¸° 작업ìžê°€ 존재한다면
self.asyncWorker.thread.quit() # 기존 ìŠ¤ë ˆë“œ 종료
- print(f"키프리스 검색버튼 í´ë¦ : 키워드 = [{keyword}]")
+ logger.debug(f"키프리스 검색버튼 í´ë¦ : 키워드 = [{keyword}]")
self.asyncWorker = AsyncWebSearchWorker(keyword, self.set_status) # 새 비ë™ê¸° ìž‘ì—…ìž ìƒì„±
self.asyncWorker.finished.connect(self.display_results_for_web) # 완료 시그ë„ì„ ê²°ê³¼ 표시 í•¨ìˆ˜ì— ì—°ê²°
self.asyncWorker.start() # 비ë™ê¸° 작업 시작
- print("비ë™ê¸° 검색 시작")
+ logger.debug("비ë™ê¸° 검색 시작")
def display_results_for_web(self, result, elapsed_time):
- print(f"result : {result}")
-
- self.searchDisplayWidget.show_results(result)
+ # logger.debug(f"result : {result}")
+ searchType = 'web'
+ logger.debug(f"display_results_for_web - currentURL : {self.web_scraper.currentURL}")
+ self.searchDisplayWidget.show_results(result, searchType, elapsed_time, self.web_scraper.currentURL)
# self.searchDisplay.display_web_results(result, elapsed_time)
# self.searchDisplay.show()
@@ -1113,28 +1177,31 @@ class DeliveryFeeCalculator(QtWidgets.QWidget):
if self.searchThread is not None and self.searchThread.isRunning():
self.searchThread.quit() # ì´ì „ ìŠ¤ë ˆë“œê°€ 실행 중ì´ë¼ë©´ ì•ˆì „í•˜ê²Œ 종료
- print("기존 ì“°ë ˆë“œê°€ 존재하므로 기존 ì“°ë ˆë“œ 종료")
- print(f"키프리스 검색버튼 í´ë¦ : 키워드 = [{keyword}]")
+ logger.debug("기존 ì“°ë ˆë“œê°€ 존재하므로 기존 ì“°ë ˆë“œ 종료")
+ logger.debug(f"키프리스 검색버튼 í´ë¦ : 키워드 = [{keyword}]")
worker = APISearchWorker(self.kiprisAPI, keyword, self.set_status)
# worker = SearchWorker(self.kiprisAPI, keyword, self.set_status)
- print("워커 ìƒì„±")
+ logger.debug("워커 ìƒì„±")
self.searchThread = SearchThread(worker)
- print("ì“°ë ˆë“œ ìƒì„±")
+ logger.debug("ì“°ë ˆë“œ ìƒì„±")
worker.finished.connect(self.display_results_for_api)
self.searchThread.finished.connect(self.clear_thread_reference)
self.searchThread.start_search()
- print("검색 시작")
+ logger.debug("검색 시작")
def clear_thread_reference(self):
# ìŠ¤ë ˆë“œ 종료 후 참조를 ì œê±°í•˜ì—¬ ë‹¤ìŒ ê²€ìƒ‰ì„ ìœ„í•´ 준비
self.searchThread = None
def display_results_for_api(self, result, elapsed_time):
+ searchType = 'api'
+ logger.debug(f"display_results_for_api result: {result}")
+ self.searchDisplayWidget.show_results(result, searchType, elapsed_time)
message = f"검색 ê²°ê³¼ : {result}\nê²€ìƒ‰ì— ê±¸ë¦° 시간: {elapsed_time:.1f}ì´ˆ"
- QtWidgets.QMessageBox.information(self, "Search Results", message)
+ # QtWidgets.QMessageBox.information(self, "Search Results", message)
def reset_action(self):
self.lengthInput.setValue(1)
@@ -1171,7 +1238,7 @@ if __name__ == '__main__':
minimize_console()
app = QtWidgets.QApplication(sys.argv)
- logger = setup_logger('default_logger', 'delivery_calc.log', level=logging.INFO)
+ logger = setup_logger('default_logger', 'delivery_calc.log', level=logging.DEBUG)
ex = DeliveryFeeCalculator(logger)
ex.show()
sys.exit(app.exec_())
diff --git a/delv.xlsx b/delv.xlsx
index 12d1379..59dfc16 100644
Binary files a/delv.xlsx and b/delv.xlsx differ
diff --git a/delv_py.spec b/delv_py.spec
index 1313aee..038af49 100644
--- a/delv_py.spec
+++ b/delv_py.spec
@@ -3,12 +3,10 @@
a = Analysis(
['delv.py'],
- pathex=['H:\\py\\delvfee'],
+ pathex=[],
binaries=[],
datas=[],
- hiddenimports=[
- 'sip', 'jinja2'
- ],
+ hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
diff --git a/src/Kiprismain.py b/src/Kiprismain.py
index 125ab77..558b358 100644
--- a/src/Kiprismain.py
+++ b/src/Kiprismain.py
@@ -3,7 +3,10 @@ from PyQt5.QtWidgets import QApplication, QMessageBox, QSizePolicy, QWidget, QVB
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt, QByteArray, QBuffer, QIODevice
from kipris_web_from_playwright import WebScraper
+import logging
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
class MainApp(QWidget):
def __init__(self):
super().__init__()
@@ -163,7 +166,7 @@ class MainApp(QWidget):
self.results_widget.show()
except Exception as e:
- print(f"Error displaying results: {e}")
+ logger.debug(f"Error displaying results: {e}")
def close_results_widget(self):
diff --git a/src/currencyInfo.py b/src/currencyInfo.py
new file mode 100644
index 0000000..b05f4f1
--- /dev/null
+++ b/src/currencyInfo.py
@@ -0,0 +1,63 @@
+import requests
+import logging
+
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
+
+class ExchangeRateScraper:
+ def __init__(self):
+ super().__init__()
+
+ self.currencyInfo = {}
+
+ self.initUI()
+
+ def initUI(self):
+ pass
+
+
+ def getCurrency(self, currencies):
+ headers = {
+ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'
+ }
+
+ # ë™ì 으로 URL 구성하기
+ codes = ','.join([f'FRX.KRW{currency}' for currency in currencies])
+ url = f'https://quotation-api-cdn.dunamu.com/v1/forex/recent?codes={codes}'
+
+ # url = 'https://quotation-api-cdn.dunamu.com/v1/forex/recent?codes=FRX.KRWUSD,FRX.KRWCNY'
+ response = requests.get(url, headers=headers)
+
+ if response.status_code == 200:
+ exchange_rates = response.json()
+ for rate in exchange_rates:
+ currency_code = rate['currencyCode']
+ if currency_code in currencies:
+ # 해당 통화 ì •ë³´ ì €ìž¥
+ self.currencyInfo[currency_code] = {
+ 'basePrice': rate['basePrice'],
+ 'modifiedAt': rate['modifiedAt'],
+ 'provider': rate['provider']
+ }
+ logger.debug("Exchange rates updated.")
+ else:
+ logger.error("Failed to retrieve data")
+
+
+ def get_Currency_Info(self, currency):
+ # íŠ¹ì • 통화 ì •ë³´ ì¶œë ¥ 메서드
+ if currency in self.currencyInfo:
+ info = self.currencyInfo[currency]
+
+ logger.debug(f"Currency: {currency}")
+ logger.debug(f"Base Price: {info['basePrice']}")
+ logger.debug(f"Modified At: {info['modifiedAt']}")
+ logger.debug(f"Provider: {info['provider']}")
+ else:
+ logger.debug(f"No data available for {currency}")
+
+# # í´ëž˜ìФ 메서드 사용 ì˜ˆì œ
+# scraper = ExchangeRateScraper()
+# scraper.getCurrency(['USD', 'CNY']) # USD와 CNY 환율 ì •ë³´ë¥¼ ìš”ì²
+# scraper.get_Currency_Info('USD')
+# scraper.get_Currency_Info('CNY')
diff --git a/src/kiprisThread.py b/src/kiprisThread.py
index 7f8f92f..7492168 100644
--- a/src/kiprisThread.py
+++ b/src/kiprisThread.py
@@ -1,9 +1,12 @@
from PyQt5.QtCore import QThread, pyqtSignal, QObject
import time
from src.web_scraper_async import *
+import logging
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
class APISearchWorker(QObject):
- finished = pyqtSignal(list, float)
+ finished = pyqtSignal(dict, float)
def __init__(self, kiprisObject, keyword, set_status):
super().__init__()
@@ -13,9 +16,9 @@ class APISearchWorker(QObject):
def run(self):
start_time = time.time() # 검색 시작 시간
- print(f"Search keyword : [{self.keyword}], self.set_status : [{self.set_status}]")
+ logger.debug(f"Search keyword : [{self.keyword}], self.set_status : [{self.set_status}]")
result = self.kiprisObject.run(self.keyword, self.set_status)
- print(f"Search finished | result \n [{result}]")
+ logger.debug(f"Search finished | result \n {result}")
elapsed_time = time.time() - start_time # 경과 시간 계산
self.finished.emit(result, elapsed_time)
@@ -36,7 +39,7 @@ class SearchThread(QThread):
def handle_finished(self, result, elapsed_time):
# 검색 ìž‘ì—…ì´ ì™„ë£Œë˜ë©´ ì´ ì‹œê·¸ë„ì´ ë°œìƒí•©ë‹ˆë‹¤.
- print(f"Search finished : [{elapsed_time}]초 경과")
+ logger.debug(f"Search finished : [{elapsed_time}]초 경과")
class AsyncWebSearchWorker(QObject):
@@ -68,7 +71,7 @@ class AsyncWebSearchWorker(QObject):
elapsed_time = time.time() - self.start_time # 소요 시간 계산
self.finished.emit(result, elapsed_time) # 작업 완료 ì‹ í˜¸ ì „ì†¡
except Exception as e:
- print(f"Error in AsyncWebSearchWorker: {e}")
+ logger.debug(f"Error in AsyncWebSearchWorker: {e}")
self.finished.emit(None, 0) # ì—러 ë°œìƒ ì‹œ None ì „ì†¡
finally:
await self.scraper.close_Kipris() # 리소스 ì •ë¦¬
diff --git a/src/kipris_api_from_publicdata.py b/src/kipris_api_from_publicdata.py
index d35755c..6f48205 100644
--- a/src/kipris_api_from_publicdata.py
+++ b/src/kipris_api_from_publicdata.py
@@ -1,11 +1,17 @@
import xml.etree.ElementTree as ET
-import requests
+import requests, json
+import logging
+
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
class Kipris_API:
def __init__(self, apikey=None):
self.url = 'http://kipo-api.kipi.or.kr/openapi/service/trademarkInfoSearchService/getWordSearch'
self.apikey = apikey
- self.results = []
+ self.results = {}
+ filename = 'categories.json'
+ self.category_description = self.load_category_descriptions(filename)
def fetch_and_decode(self, params):
# API ìš”ì² ë° ì‘답 받기
@@ -14,7 +20,7 @@ class Kipris_API:
decoded_data = response.content.decode('utf-8')
return decoded_data
except Exception as e:
- print(f"키프리스 ìš”ì² ì¤‘ ì—ëŸ¬ë°œìƒ : {e}")
+ logger.error(f"키프리스 ìš”ì² ì¤‘ ì—ëŸ¬ë°œìƒ : {e}")
def parse_xml(self, xml_data, status):
# XML ë°ì´í„° 파싱
@@ -24,10 +30,15 @@ class Kipris_API:
status_published = 0
# 'body/items/item' ê²½ë¡œì— ë§žì¶° 'item' 태그를 순회하면서 필요한 ë°ì´í„° 추출
- for item in root.findall('.//body/items/item'):
+ for i, item in enumerate(root.findall('.//body/items/item')):
total_items += 1
application_status = item.find('applicationStatus').text if item.find('applicationStatus') is not None else None
+ product_category = item.find('classificationCode').text if item.find('classificationCode') is not None else None
+ if product_category:
+ category_desc = self.add_category_description(product_category) if product_category else "No category description"
+ else:
+ category_desc = None
# ê° ìƒíƒœì˜ 개수를 카운트
if application_status == "등ë¡":
status_registered += 1
@@ -36,7 +47,8 @@ class Kipris_API:
# if application_status in ["등ë¡", "공개"]:
if application_status in status: # status는 self.set_status 리스트를 참조
- result = {
+
+ self.results[f"result_{i+1}"] = {
"index_no": item.find('indexNo').text if item.find('indexNo') is not None else None,
"application_number": item.find('applicationNumber').text if item.find('applicationNumber') is not None else None,
"application_date": item.find('applicationDate').text if item.find('applicationDate') is not None else None,
@@ -51,14 +63,16 @@ class Kipris_API:
"big_drawing_url": item.find('bigDrawing').text if item.find('bigDrawing') is not None else None,
"full_text": item.find('fullText').text if item.find('fullText') is not None else None,
"application_status": application_status,
- "classification_code": item.find('classificationCode').text if item.find('classificationCode') is not None else None
+ "classification_code": item.find('classificationCode').text if item.find('classificationCode') is not None else None,
+ "category_description": category_desc
}
- self.results.append(result)
+ # self.results.append(result)
# ìƒíƒœ 개수와 ì´ ì•„ì´í…œ 개수 ì¶œë ¥
- print(f"ê²€ìƒ‰ëœ item ì´ ê°œìˆ˜: {total_items}")
- print(f"ë“±ë¡ ìƒíƒœì¸ item 개수: {status_registered}")
- print(f"공개 ìƒíƒœì¸ item 개수: {status_published}")
+ logger.debug(f"ê²€ìƒ‰ëœ item ì´ ê°œìˆ˜: {total_items}")
+ self.results['total_count'] = total_items
+ logger.debug(f"ë“±ë¡ ìƒíƒœì¸ item 개수: {status_registered}")
+ logger.debug(f"공개 ìƒíƒœì¸ item 개수: {status_published}")
def get_results(self):
return self.results
@@ -73,9 +87,25 @@ class Kipris_API:
'drawing': '',
'bigDrawing': ''
}
- xml_data = self.fetch_and_decode(params)
- self.parse_xml(xml_data, status)
+ logger.debug(f" Search params : {params}")
+ try:
+ xml_data = self.fetch_and_decode(params)
+ self.parse_xml(xml_data, status)
+ except Exception as e:
+ logger.error(f"API ìš”ì² ì¤‘ ì—ëŸ¬ë°œìƒ : {e}")
+
return self.get_results()
def close_Kipris(self):
- pass
\ No newline at end of file
+ pass
+
+ def load_category_descriptions(self, filename):
+ """JSON 파ì¼ì—서 ì¹´í…Œê³ ë¦¬ ì„¤ëª…ì„ ë¡œë“œí•©ë‹ˆë‹¤."""
+ with open(filename, 'r', encoding='utf-8') as file:
+ return json.load(file)
+
+ def add_category_description(self, category_code):
+ """주어진 ì¹´í…Œê³ ë¦¬ ì½”ë“œì— ë”°ë¼ ì„¤ëª…ì„ ë°˜í™˜í•©ë‹ˆë‹¤."""
+ logger.debug(f"add_category_description => category_code: {category_code}")
+ return self.category_description.get(category_code, "ì¹´í…Œê³ ë¦¬ ì„¤ëª…ì„ ì°¾ì„ ìˆ˜ 없습니다.")
+
diff --git a/src/kipris_image/4019850019868.jpg b/src/kipris_image/4019850019868.jpg
deleted file mode 100644
index 1d74bb3..0000000
Binary files a/src/kipris_image/4019850019868.jpg and /dev/null differ
diff --git a/src/kipris_image/4020060031901.jpg b/src/kipris_image/4020060031901.jpg
deleted file mode 100644
index 1d74bb3..0000000
Binary files a/src/kipris_image/4020060031901.jpg and /dev/null differ
diff --git a/src/kipris_image/4020100044795.jpg b/src/kipris_image/4020100044795.jpg
deleted file mode 100644
index 3bbd78e..0000000
Binary files a/src/kipris_image/4020100044795.jpg and /dev/null differ
diff --git a/src/kipris_image/4020180008447.jpg b/src/kipris_image/4020180008447.jpg
deleted file mode 100644
index 1722774..0000000
Binary files a/src/kipris_image/4020180008447.jpg and /dev/null differ
diff --git a/src/kipris_image/4020180057525.jpg b/src/kipris_image/4020180057525.jpg
deleted file mode 100644
index dacdaee..0000000
Binary files a/src/kipris_image/4020180057525.jpg and /dev/null differ
diff --git a/src/kipris_image/4020200194865.jpg b/src/kipris_image/4020200194865.jpg
deleted file mode 100644
index c86ce79..0000000
Binary files a/src/kipris_image/4020200194865.jpg and /dev/null differ
diff --git a/src/kipris_image/4020200194866.jpg b/src/kipris_image/4020200194866.jpg
deleted file mode 100644
index c86ce79..0000000
Binary files a/src/kipris_image/4020200194866.jpg and /dev/null differ
diff --git a/src/kipris_image/4020210039825.jpg b/src/kipris_image/4020210039825.jpg
deleted file mode 100644
index 4cf3b20..0000000
Binary files a/src/kipris_image/4020210039825.jpg and /dev/null differ
diff --git a/src/kipris_image/4020227013143.jpg b/src/kipris_image/4020227013143.jpg
deleted file mode 100644
index 1d74bb3..0000000
Binary files a/src/kipris_image/4020227013143.jpg and /dev/null differ
diff --git a/src/kipris_image/4020230000430.jpg b/src/kipris_image/4020230000430.jpg
deleted file mode 100644
index 1fe1dd7..0000000
Binary files a/src/kipris_image/4020230000430.jpg and /dev/null differ
diff --git a/src/kipris_image/4020230000431.jpg b/src/kipris_image/4020230000431.jpg
deleted file mode 100644
index 1fe1dd7..0000000
Binary files a/src/kipris_image/4020230000431.jpg and /dev/null differ
diff --git a/src/kipris_image/4120080018739.jpg b/src/kipris_image/4120080018739.jpg
deleted file mode 100644
index 5498c5a..0000000
Binary files a/src/kipris_image/4120080018739.jpg and /dev/null differ
diff --git a/src/kipris_settingUI.py b/src/kipris_settingUI.py
index 8551f45..b64b097 100644
--- a/src/kipris_settingUI.py
+++ b/src/kipris_settingUI.py
@@ -3,7 +3,10 @@ from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QDesktopServices
from src.toggleSwitch import ToggleSwitch
+import logging
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
class SettingsDialog(QtWidgets.QDialog):
def __init__(self, parent=None, initial_settings=None):
super().__init__(parent)
@@ -42,6 +45,7 @@ class SettingsDialog(QtWidgets.QDialog):
def setupUI(self):
+ logger.debug(f"setupUI 시작")
# ì…‹ì—… ë©”ì¸ ë ˆì´ì•„웃
self.mainLayout = QtWidgets.QVBoxLayout(self)
@@ -207,7 +211,9 @@ class SettingsDialog(QtWidgets.QDialog):
self.accept()
def loadSettings(self, settings):
- # print(f"SettingsDialog settings : {settings}")
+ logger.debug(f"loadSettings 시작")
+
+ # logger.debug(f"SettingsDialog settings : {settings}")
self.use_kipris = settings.get('use_kipris', False) # 기본값 False로 ì„¤ì •
self.usage_mode = settings.get('usage_mode', 'web') # 기본값 'web'로 ì„¤ì •
@@ -215,10 +221,10 @@ class SettingsDialog(QtWidgets.QDialog):
self.set_status = settings.get('set_status', []) # 기본값 빈 리스트로 ì„¤ì •
# ìƒíƒœ ì—…ë°ì´íЏ 로그 ì¶œë ¥
- # print(f"SettingsDialog Loaded settings: use_kipris={self.use_kipris}, usage_mode={self.usage_mode}, api_key={self.api_key}")
+ # logger.debug(f"SettingsDialog Loaded settings: use_kipris={self.use_kipris}, usage_mode={self.usage_mode}, api_key={self.api_key}")
- # print(f"SettingsDialog self.use_kipris : {self.use_kipris}")
+ # logger.debug(f"SettingsDialog self.use_kipris : {self.use_kipris}")
# UI ì—…ë°ì´íЏ
self.isUseKiprisSwitch.setChecked(self.use_kipris)
self.apikeySwitch.setChecked(self.usage_mode == 'api')
@@ -246,17 +252,19 @@ class SettingsDialog(QtWidgets.QDialog):
def toggleCNYexchange(self, checked):
self.exchangeCNYSwitch.setChecked(checked)
self.setCNY = checked
- print(f"self.setCNY : {self.setCNY}")
- def toggleUSDexchange(self, checked):
+ logger.debug(f"self.setCNY : {self.setCNY}")
+ def toggleUSDexchange(self, checked):
self.exchangeUSDSwitch.setChecked(checked)
self.setUSD = checked
- print(f"self.setUSD : {self.setUSD}")
+ logger.debug(f"self.setUSD : {self.setUSD}")
def toggleKiprisUsage(self, checked):
self.settingKiprisWidget.setVisible(checked)
self.checkWidget.setVisible(checked)
self.use_kipris = checked
+ logger.debug(f"self.use_kipris : {self.use_kipris}")
+
# self.kiprisFrame.setVisible(False)
def toggleAPIUsage(self, checked):
@@ -264,12 +272,14 @@ class SettingsDialog(QtWidgets.QDialog):
self.useWebSwitch.setChecked(not checked)
self.editAPIWidget.setVisible(checked)
self.usage_mode = 'api' if checked else 'web'
+ logger.debug(f"self.usage_mode : {self.usage_mode}")
def toggleWebUsage(self, checked):
self.useWebSwitch.setChecked(checked)
self.apikeySwitch.setChecked(not checked)
self.editAPIWidget.setVisible(not checked)
self.usage_mode = 'web' if checked else 'api'
+ logger.debug(f"self.usage_mode : {self.usage_mode}")
def create_label_and_switch(self, widget, label_text, target_switch):
layout = QtWidgets.QHBoxLayout()
@@ -306,36 +316,51 @@ class SettingsDialog(QtWidgets.QDialog):
if status in self.set_status:
self.set_status.remove(status)
- # print("Current Status List:", self.set_status)
+ logger.debug(f"self.set_status : {self.set_status}")
+
+ # logger.debug("Current Status List:", self.set_status)
def handle_all_checked(self, state):
if state == QtCore.Qt.Checked:
- for checkbox in self.checkboxes:
- checkbox.setChecked(True)
+ self.right_rejected_checkbox.setChecked(True)
+ self.right_registered_checkbox.setChecked(True)
+ self.right_expiration_checkbox.setChecked(True)
+ self.right_void_checkbox.setChecked(True)
+ self.right_Withdrawal_checkbox.setChecked(True)
+ self.right_remise_checkbox.setChecked(True)
+ self.right_Disclosure_checkbox.setChecked(True)
+
elif state == QtCore.Qt.Unchecked:
- for checkbox in self.checkboxes[1:]: # "등ë¡" ì²´í¬ë°•스 ì œì™¸
- checkbox.setChecked(False)
- self.checkboxes[0].setChecked(True) # "등ë¡" ì²´í¬ë°•스는 í•ìƒ ì²´í¬
+ self.right_rejected_checkbox.setChecked(False)
+ self.right_expiration_checkbox.setChecked(False)
+ self.right_void_checkbox.setChecked(False)
+ self.right_Withdrawal_checkbox.setChecked(False)
+ self.right_remise_checkbox.setChecked(False)
+ self.right_Disclosure_checkbox.setChecked(False)
- def handle_checkbox_state_changed(self):
- for checkbox in self.checkboxes:
- # 글ìžë¥¼ 진하게 만들기
- font = checkbox.font()
- font.setBold(checkbox.isChecked())
- checkbox.setFont(font)
+ self.right_registered_checkbox.setChecked(True) # "등ë¡" ì²´í¬ë°•스는 í•ìƒ ì²´í¬
- # ì „ì²´ ì²´í¬ ìƒíƒœ ì—…ë°ì´íЏ
- all_checked = all(checkbox.isChecked() for checkbox in self.checkboxes)
- all_unchecked = all(not checkbox.isChecked() for checkbox in self.checkboxes[1:]) # "등ë¡" ì œì™¸
+ logger.debug(f"all_checked : {state}")
- self.all_checkbox.blockSignals(True) # ì‹œê·¸ë„ ì¼ì‹œ 중지
- if all_checked:
- self.all_checkbox.setCheckState(QtCore.Qt.Checked)
- elif all_unchecked:
- self.all_checkbox.setCheckState(QtCore.Qt.Unchecked)
- else:
- self.all_checkbox.setCheckState(QtCore.Qt.PartiallyChecked)
- self.all_checkbox.blockSignals(False) # ì‹œê·¸ë„ ìž¬ê°œ
+ # def handle_checkbox_state_changed(self):
+ # for checkbox in self.checkboxes:
+ # # 글ìžë¥¼ 진하게 만들기
+ # font = checkbox.font()
+ # font.setBold(checkbox.isChecked())
+ # checkbox.setFont(font)
+
+ # # ì „ì²´ ì²´í¬ ìƒíƒœ ì—…ë°ì´íЏ
+ # all_checked = all(checkbox.isChecked() for checkbox in self.checkboxes)
+ # all_unchecked = all(not checkbox.isChecked() for checkbox in self.checkboxes[1:]) # "등ë¡" ì œì™¸
+
+ # self.all_checkbox.blockSignals(True) # ì‹œê·¸ë„ ì¼ì‹œ 중지
+ # if all_checked:
+ # self.all_checkbox.setCheckState(QtCore.Qt.Checked)
+ # elif all_unchecked:
+ # self.all_checkbox.setCheckState(QtCore.Qt.Unchecked)
+ # else:
+ # self.all_checkbox.setCheckState(QtCore.Qt.PartiallyChecked)
+ # self.all_checkbox.blockSignals(False) # ì‹œê·¸ë„ ìž¬ê°œ
class HelpDialog(QtWidgets.QDialog):
@@ -354,9 +379,14 @@ class HelpDialog(QtWidgets.QDialog):
)
else:
self.resize(400, 300) # ë‹¨ë… ì‹¤í–‰ 시 í¬ê¸° ì„¤ì •
+
+ logger.debug(f"HelpDialog 초기화")
+
self.setupUI()
def setupUI(self):
+ logger.debug(f"HelpDialog setupUI 로드")
+
layout = QtWidgets.QVBoxLayout(self)
textBrowser = QtWidgets.QTextBrowser(self)
textBrowser.setOpenExternalLinks(False) # 외부 ë§í¬ ìžë™ 열기 비활성화
@@ -387,10 +417,6 @@ class HelpDialog(QtWidgets.QDialog):
QDesktopServices.openUrl(url)
-
-
-
-
# ※ í–‰ì • ìƒíƒœ ë„움ë§
# ê±°ì ˆ : ì¶œì› í›„ 특허 ì‹¬ì‚¬ê³¼ì •ì—서 실체ì ì¸ íŠ¹í—ˆ 등ë¡ìš”ê±´ì„ ë§Œì¡±í•˜ì§€ ëª»í• ê²½ìš°ì— ì‹¬ì‚¬ê´€ì´ ì·¨í•˜ëŠ” í–‰ì •ì²˜ë¶„
# ë“±ë¡ : ì‹¬ì‚¬ê´€ì´ ì‹¬ì‚¬í•œ ê²°ê³¼ 등ë¡ìš”ê±´ì— ì 합하여 ì„¤ì •ë“±ë¡ì„ ë°›ì„ ìˆ˜ 있다는 ë‚´ìš©ì˜ í–‰ì •ì²˜ë¶„
diff --git a/src/kipris_web_from_playwright.py b/src/kipris_web_from_playwright.py
index 7a23890..23e89e9 100644
--- a/src/kipris_web_from_playwright.py
+++ b/src/kipris_web_from_playwright.py
@@ -3,7 +3,10 @@ import random, requests, json
from PIL import Image
import os
from io import BytesIO
+import logging
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
class Kipris_WEB:
def __init__(self, apikey=None):
self.apikey = apikey
@@ -42,45 +45,45 @@ class Kipris_WEB:
def run(self, term, status):
"""검색어로 ê²€ìƒ‰í•˜ê³ ê²°ê³¼ 수집"""
- print(f"Playwright 검색시작 : 키워드 : [{term}]")
+ logger.debug(f"Playwright 검색시작 : 키워드 : [{term}]")
try:
self.page.fill("#queryText", term)
self.page.click(".input_btn")
# JavaScriptì— ì˜í•´ 결과가 ë™ì 으로 로드ë˜ê¸°ë¥¼ 기다립니다.
loaded = self.page.wait_for_function("document.querySelector('form#listForm section.search_section article') != null")
- print("검색페ì´ì§€ 로드 완료")
+ logger.debug("검색페ì´ì§€ 로드 완료")
if not loaded:
- print("검색 결과가 시간 ë‚´ì— ë¡œë“œë˜ì§€ 않았습니다.")
+ logger.debug("검색 결과가 시간 ë‚´ì— ë¡œë“œë˜ì§€ 않았습니다.")
return None
# 검색 결과가 없는지 확ì¸
nodata_info = self.page.query_selector(".nodata_info")
if nodata_info:
- print("검색 결과가 없습니다.")
+ logger.debug("검색 결과가 없습니다.")
# íŠ¹ì • 메서드 호출 ë° í•¨ìˆ˜ 종료
# self.handle_no_search_results()
return None
- print("검색 ê²°ê³¼ 로딩 후 ì‹¤ì œ 요소 수집 시작")
+ logger.debug("검색 ê²°ê³¼ 로딩 후 ì‹¤ì œ 요소 수집 시작")
# ê²°ê³¼ ë¡œë”©ì´ í™•ì¸ëœ 후, ì‹¤ì œ 요소를 수집
self.page.wait_for_selector("form#listForm section.search_section", state="visible", timeout=10000)
- print("listForm")
+ logger.debug("listForm")
total_count = self.page.text_content("form#listForm section.search_section div p span.total")
- print(f"total_count : {total_count}")
+ logger.debug(f"total_count : {total_count}")
if total_count:
self.results['total_count'] = total_count.strip()
articles = self.page.query_selector_all("form#listForm section.search_section article")
- print(f"articles : {len(articles)}")
+ logger.debug(f"articles : {len(articles)}")
for i, article in enumerate(articles):
id_and_name_element = article.query_selector("div:nth-child(1) span input[type='checkbox']")
trademark_name = id_and_name_element.get_attribute("title") if id_and_name_element else "No name found"
- print(f"trademark_name : {trademark_name}")
+ logger.debug(f"trademark_name : {trademark_name}")
applno = id_and_name_element.get_attribute("value") if id_and_name_element else "No ID found"
if applno:
trademark_image_url_by_id = f"http://kdtj.kipris.or.kr/kdtj/remoteFile.do?method=bigImageTM&applno={applno}&no={applno}_tm000001.jpg"
- print(f"applno : {applno}")
+ logger.debug(f"applno : {applno}")
img_element = article.query_selector("div:nth-child(2) div a img")
trademark_image = img_element.get_attribute("src") if img_element else "No image found"
@@ -107,7 +110,7 @@ class Kipris_WEB:
# Use the title attribute of the checkbox input for the trademark name
# name_element = article.query_selector("div:nth-child(1) span input[type='checkbox']")
# trademark_name = name_element.get_attribute("title") if name_element else "No name found"
- print(f"ì•„ì´í…œ ì •ë³´ 변수 만들기")
+ logger.debug(f"ì•„ì´í…œ ì •ë³´ 변수 만들기")
# if not admin_status == "소멸":
if admin_status in status:
@@ -123,12 +126,12 @@ class Kipris_WEB:
"publication_date": publication_date,
"registration_date": registration_date,
}
- print("리턴")
+ logger.debug("리턴")
return self.results
else:
- print("No total count element found, possibly incorrect selector or page structure has changed.")
+ logger.debug("No total count element found, possibly incorrect selector or page structure has changed.")
except Exception as e:
- print(f"오류 ë°œìƒ : {e}")
+ logger.debug(f"오류 ë°œìƒ : {e}")
return None
def download_image(url, applno):
@@ -138,9 +141,9 @@ class Kipris_WEB:
filename = f"{applno}.jpeg" # íŒŒì¼ ì´ë¦„ì„ ID로 ì„¤ì •
with open(filename, 'wb') as file:
file.write(response.content)
- print(f"ì´ë¯¸ì§€ê°€ 성공ì 으로 ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤: {filename}")
+ logger.debug(f"ì´ë¯¸ì§€ê°€ 성공ì 으로 ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤: {filename}")
else:
- print(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status_code}")
+ logger.debug(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status_code}")
def load_category_descriptions(self, filename):
"""JSON 파ì¼ì—서 ì¹´í…Œê³ ë¦¬ ì„¤ëª…ì„ ë¡œë“œí•©ë‹ˆë‹¤."""
@@ -167,10 +170,10 @@ class Kipris_WEB:
image.save(buffer, 'JPEG') # 예시로 JPEG í¬ë§·ì„ 사용
return buffer.getvalue()
except Exception as e:
- print(f"ì´ë¯¸ì§€ 변환 실패: {e}")
+ logger.debug(f"ì´ë¯¸ì§€ 변환 실패: {e}")
return None
else:
- print(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status_code}")
+ logger.debug(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status_code}")
return None
def close_Kipris(self):
diff --git a/src/result_widget.py b/src/result_widget.py
index d2ac4c4..d9210a8 100644
--- a/src/result_widget.py
+++ b/src/result_widget.py
@@ -2,11 +2,16 @@ import sys
from PyQt5.QtWidgets import QSizePolicy, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QGridLayout
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
+# from PyQt5.Qt import QDesktopServices
+import webbrowser
import requests
from PIL import Image
from io import BytesIO
import asyncio, aiofiles, aiohttp
+import logging
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
class ResultWidget(QWidget):
def __init__(self):
super().__init__()
@@ -15,64 +20,82 @@ class ResultWidget(QWidget):
def initUI(self):
self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
- def show_results(self, results):
+ def show_results(self, results, searchType, elapsed_time, currentURL=''):
+ searchType = searchType
+ elapsed_time = elapsed_time
+ currentURL = currentURL
+ logger.debug(f"show_results - searchType : {searchType}")
+ logger.debug(f"show_results - elapsed_time : {elapsed_time}")
+ # try:
+ # ê²°ê³¼ ìœ„ì ¯ ìƒì„±
+ self.results_widget = QWidget()
+ layout = QVBoxLayout()
+ self.results_widget.setLayout(layout)
- try:
- # ê²°ê³¼ ìœ„ì ¯ ìƒì„±
- self.results_widget = QWidget()
- layout = QVBoxLayout()
- self.results_widget.setLayout(layout)
+ # ê²°ê³¼ 갯수 í™•ì¸ ë° ë ˆì´ì•„웃 ë™ì ìƒì„±
+ total_count = int(results['total_count'])
+ set_count = min(total_count, 10)
+ grid_layout = QGridLayout()
+ layout.addLayout(grid_layout)
+ grid_index = 0
+ grid_columns = 5
+ logger.debug(f"show_results - set_count : {set_count}")
- # ê²°ê³¼ 갯수 í™•ì¸ ë° ë ˆì´ì•„웃 ë™ì ìƒì„±
- total_count = int(results['total_count'])
- set_count = min(total_count, 10)
- grid_layout = QGridLayout()
- layout.addLayout(grid_layout)
- grid_index = 0
- grid_columns = 5
+ for i in range(1, set_count + 1):
+ result_key = f"result_{i}"
+ if result_key in results:
+ result = results[result_key]
+ logger.debug(f"show_results - result_key : {result_key}")
- for i in range(1, set_count + 1):
- result_key = f"result_{i}"
- if result_key in results:
- result = results[result_key]
+ # í…Œë‘리 ì„¤ì •
+ border_style = ''
+ if result['application_status'] == '등ë¡':
+ border_style = 'border: 4px solid red;'
+ elif result['application_status'] == 'ê³µê³ ':
+ border_style = 'border: 3px solid black;'
+
+ # ê° ê²°ê³¼ì— ëŒ€í•œ ë ˆì´ì•„웃 ìƒì„±
+ item_layout = QVBoxLayout()
+ item_widget = QWidget() # ìœ„ì ¯ ìƒì„±
- # í…Œë‘리 ì„¤ì •
- border_style = ''
- if result['application_status'] == '등ë¡':
- border_style = 'border: 4px solid red;'
- elif result['application_status'] == 'ê³µê³ ':
- border_style = 'border: 3px solid black;'
-
- # ê° ê²°ê³¼ì— ëŒ€í•œ ë ˆì´ì•„웃 ìƒì„±
- item_layout = QVBoxLayout()
- item_widget = QWidget() # ìœ„ì ¯ ìƒì„±
+ # item_layoutì˜ í¬ê¸° ì •ì±… ì„¤ì •
+ item_widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)
- # item_layoutì˜ í¬ê¸° ì •ì±… ì„¤ì •
- item_widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)
+ # ì´ë¯¸ì§€ 처리
+ image_label = QLabel()
+ image_label.setFixedSize(150, 150)
+ image_data = self.fetch_image_data(result['drawing_url'])
+ pixmap = QPixmap()
+ pixmap.loadFromData(image_data)
+ # QLabelì˜ í¬ê¸°ì— 맞게 ì´ë¯¸ì§€ í¬ê¸° ì¡°ì •
+ scaled_pixmap = pixmap.scaled(image_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
+ image_label.setPixmap(scaled_pixmap)
+ # QLabelì˜ ê°€ë¡œ 세로 ì¤‘ì•™ì— ì´ë¯¸ì§€ 표시
+ image_label.setAlignment(Qt.AlignCenter)
+ # ì´ë¯¸ì§€ 표시 ìœ„ì ¯ì˜ í¬ê¸° ì¡°ì • ì •ì±… ì„¤ì •
+ image_label.setScaledContents(True)
- # ì´ë¯¸ì§€ 처리
- image_label = QLabel()
- image_label.setFixedSize(150, 150)
- image_data = self.fetch_image_data(result['drawing_url'])
- pixmap = QPixmap()
- pixmap.loadFromData(image_data)
- # QLabelì˜ í¬ê¸°ì— 맞게 ì´ë¯¸ì§€ í¬ê¸° ì¡°ì •
- scaled_pixmap = pixmap.scaled(image_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
- image_label.setPixmap(scaled_pixmap)
- # QLabelì˜ ê°€ë¡œ 세로 ì¤‘ì•™ì— ì´ë¯¸ì§€ 표시
- image_label.setAlignment(Qt.AlignCenter)
- # ì´ë¯¸ì§€ 표시 ìœ„ì ¯ì˜ í¬ê¸° ì¡°ì • ì •ì±… ì„¤ì •
- image_label.setScaledContents(True)
+ #ì´ë¯¸ì§€ 중앙배치를 위해
+ horizontal_layout = QHBoxLayout()
+ horizontal_layout.addWidget(image_label)
+ horizontal_layout.setAlignment(Qt.AlignCenter)
+ item_layout.addLayout(horizontal_layout)
- #ì´ë¯¸ì§€ 중앙배치를 위해
- horizontal_layout = QHBoxLayout()
- horizontal_layout.addWidget(image_label)
- horizontal_layout.setAlignment(Qt.AlignCenter)
- item_layout.addLayout(horizontal_layout)
+ # item_layout.addWidget(image_label)
- # item_layout.addWidget(image_label)
-
- # ì •ë³´ í…스트
+ if searchType =='api':
+ # API ì •ë³´ í…스트
+ # info_text = f"ìƒí‘œê¶Œëª…: {result['title']}\n등ë¡ìƒíƒœ: {result['admin_status']}\nCategory: {result['product_category']}\nApplicant: {result['applicant']}\nPublication Date: {result['publication_date']}\nRegistration Date: {result['registration_date']}"
+ info_text = f"ìƒí‘œê¶Œëª…: {result['title']}
\n" \
+ f"등ë¡ìƒíƒœ: {result['application_status']}
\n" \
+ f"ì¹´í…Œê³ ë¦¬: {result['classification_code']}
\n" \
+ f"권리ìž: {result['applicant_name']}
\n" \
+ f"ì¶œì›ì¼ìž {result['application_date']}
\n" \
+ f"ê³µê³ ì¼ìž {result['publication_date']}
\n" \
+ f"등ë¡ì¼ìž {result['registration_date']}\n" \
+ f"ì „ë¬¸ {result['full_text']}
\n"
+ elif searchType =='web':
+ # WEB ì •ë³´ í…스트
# info_text = f"ìƒí‘œê¶Œëª…: {result['title']}\n등ë¡ìƒíƒœ: {result['admin_status']}\nCategory: {result['product_category']}\nApplicant: {result['applicant']}\nPublication Date: {result['publication_date']}\nRegistration Date: {result['registration_date']}"
info_text = f"ìƒí‘œê¶Œëª…: {result['title']}
\n" \
f"등ë¡ìƒíƒœ: {result['application_status']}
\n" \
@@ -81,38 +104,49 @@ class ResultWidget(QWidget):
f" {result['publication_date']}
\n" \
f" {result['registration_date']}"
- info_label = QLabel(info_text)
- info_label.setToolTip(self.wrap_text(result['category_description'], 50))
- image_label.setToolTip(self.wrap_text(result['category_description'], 50))
- item_layout.addWidget(info_label)
+ info_label = QLabel(info_text)
+ if searchType =='web':
+ currentURL_btn = QPushButton("웹 열기")
+ # currentURL_btn.clicked.connect(self.openCurrentPage(currentURL))
+ info_label.setToolTip(self.wrap_text(result['category_description'], 50))
+ image_label.setToolTip(self.wrap_text(result['category_description'], 50))
+ item_layout.addWidget(info_label)
- image_label.setStyleSheet(border_style)
- info_label.setStyleSheet(border_style)
+ image_label.setStyleSheet(border_style)
+ info_label.setStyleSheet(border_style)
- # ë ˆì´ì•„ì›ƒì— ìœ„ì ¯ 추가
- row = grid_index // grid_columns
- col = grid_index % grid_columns
- grid_layout.addLayout(item_layout, row, col)
- grid_index += 1
+ # ë ˆì´ì•„ì›ƒì— ìœ„ì ¯ 추가
+ row = grid_index // grid_columns
+ col = grid_index % grid_columns
+ grid_layout.addLayout(item_layout, row, col)
+ grid_index += 1
- # ê²°ê³¼ ìœ„ì ¯ì— ë‹«ê¸° 버튼 추가
- close_button = QPushButton("Close")
- close_button.clicked.connect(self.close_results_widget)
- layout.addWidget(close_button)
+ # ê²°ê³¼ ìœ„ì ¯ì— ë‹«ê¸° 버튼 추가
+ close_button = QPushButton("Close")
+ close_button.clicked.connect(self.close_results_widget)
+ layout.addWidget(close_button)
+
+ # e
+ elapsed_time_Label = QLabel(f"Elapsed Time : {elapsed_time}")
+ layout.addWidget(elapsed_time_Label)
- # ê²°ê³¼ ìœ„ì ¯ì„ ë©”ì¸ ìœˆë„ìš°ì— ì¶”ê°€
- self.results_widget.setGeometry(300, 300, 600, 300) # 위치와 í¬ê¸° ì„¤ì •
- self.results_widget.setWindowTitle('Search Results') # 타ì´í‹€ ì„¤ì •
- self.results_widget.show()
-
- except Exception as e:
- print(f"Error displaying results: {e}")
+ # ê²°ê³¼ ìœ„ì ¯ì„ ë©”ì¸ ìœˆë„ìš°ì— ì¶”ê°€
+ self.results_widget.setGeometry(300, 300, 600, 300) # 위치와 í¬ê¸° ì„¤ì •
+ self.results_widget.setWindowTitle('Search Results') # 타ì´í‹€ ì„¤ì •
+ self.results_widget.show()
+ # except Exception as e:
+ # logger.debug(f"Error displaying results: {e}")
def close_results_widget(self):
# ê²°ê³¼ ìœ„ì ¯ë‹«ê¸° 함수를 í˜¸ì¶œí• ë•Œ 사용하는 메서드
self.results_widget.close()
+ def openCurrentPage(self, currentURL):
+ logger.debug(f"open the page : {currentURL}")
+ webbrowser.open('currentURL')
+ pass
+ # QDesktopServices.openUrl(self.currentURL)
def wrap_text(self, text, width=40):
"""주어진 ë„ˆë¹„ì— ë§žê²Œ í…스트를 줄바꿈합니다."""
@@ -133,31 +167,31 @@ class ResultWidget(QWidget):
async def fetch_image_data_async(self, url):
"""주어진 URL로부터 ì´ë¯¸ì§€ ë°ì´í„°ë¥¼ 비ë™ê¸°ì 으로 ê°€ì ¸ì™€ 반환합니다."""
async with aiohttp.ClientSession() as session:
- # print(f"download_image session Start!!")
+ # logger.debug(f"download_image session Start!!")
async with session.get(url) as response:
- print(f"download_image url : {url}")
+ logger.debug(f"download_image url : {url}")
if response.status == 200:
- # print(f"response : {response}")
+ # logger.debug(f"response : {response}")
content_type = response.headers.get('Content-Type', '') # await ì œê±°
- print(f"content_type : {content_type}")
+ logger.debug(f"content_type : {content_type}")
if 'image' in content_type or 'octet-stream' in content_type:
- # print(f"image content type or octet-stream : {content_type}")
+ # logger.debug(f"image content type or octet-stream : {content_type}")
return await response.read()
else:
try:
# Content-Typeì´ ì´ë¯¸ì§€ê°€ 아니면, ë°ì´í„°ë¥¼ ì´ë¯¸ì§€ë¡œ 변환
data = await response.read()
- # print(f"Content-Typeì´ ì´ë¯¸ì§€ê°€ 아님 : {data}")
+ # logger.debug(f"Content-Typeì´ ì´ë¯¸ì§€ê°€ 아님 : {data}")
image = Image.open(BytesIO(data))
with BytesIO() as buffer:
image.save(buffer, 'JPEG')
- print(f"image 를 JPEG로 ì €ìž¥")
+ logger.debug(f"image 를 JPEG로 ì €ìž¥")
return buffer.getvalue()
except Exception as e:
- print(f"ì´ë¯¸ì§€ 변환 실패: {e}")
+ logger.debug(f"ì´ë¯¸ì§€ 변환 실패: {e}")
return None
else:
- print(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status}")
+ logger.debug(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status}")
return None
@@ -177,8 +211,8 @@ class ResultWidget(QWidget):
image.save(buffer, 'JPEG') # 예시로 JPEG í¬ë§·ì„ 사용
return buffer.getvalue()
except Exception as e:
- print(f"ì´ë¯¸ì§€ 변환 실패: {e}")
+ logger.debug(f"ì´ë¯¸ì§€ 변환 실패: {e}")
return None
else:
- print(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status_code}")
+ logger.debug(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status_code}")
return None
diff --git a/src/search_display.py b/src/search_display.py
index 6ff8351..befd710 100644
--- a/src/search_display.py
+++ b/src/search_display.py
@@ -2,6 +2,11 @@ import requests, os
from PyQt5.QtWidgets import QWidget, QTextBrowser, QVBoxLayout
from PyQt5.QtCore import Qt
from PIL import Image
+import logging
+
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
+
class TrademarkSearchDisplay(QWidget):
def __init__(self, parent=None):
super().__init__()
@@ -69,22 +74,22 @@ class TrademarkSearchDisplay(QWidget):
self.text_browser.append(html_content)
def display_web_results(self, data, elapsed_time):
- print(f"Processing results... Elapsed time: {elapsed_time}s")
+ logger.debug(f"Processing results... Elapsed time: {elapsed_time}s")
# data 딕셔너리 ë‚´ì˜ í‚¤ 중 'result_'로 시작하는 키를 찾아 ê·¸ ê°’ì„ ì²˜ë¦¬
for key, item in data.items():
- print(f"Checking key: {key}") # 로그 추가
+ logger.debug(f"Checking key: {key}") # 로그 추가
if key.startswith('result_'): # 'result_'로 시작하는 키 확ì¸
- print(f"Found valid key: {key}, Processing item...") # 로그 추가
+ logger.debug(f"Found valid key: {key}, Processing item...") # 로그 추가
if isinstance(item, dict): # itemì´ ë”•ì…”ë„ˆë¦¬ì¸ì§€ 확ì¸
- print(f"Item is a dictionary. Generating HTML for item with title: {item.get('title')}") # 로그 추가
+ logger.debug(f"Item is a dictionary. Generating HTML for item with title: {item.get('title')}") # 로그 추가
# ì´ë¯¸ì§€ 다운로드 시ë„
downloaded_image_path = self.download_image(item.get("drawing_url"), item.get("ID"))
if downloaded_image_path:
- print(f"Image downloaded and saved to {downloaded_image_path}")
+ logger.debug(f"Image downloaded and saved to {downloaded_image_path}")
image_html = f'
'
else:
- print("Failed to download image.")
+ logger.debug("Failed to download image.")
image_html = 'Image not available'
# HTML 콘í…ì¸ ìƒì„±
@@ -123,11 +128,11 @@ class TrademarkSearchDisplay(QWidget):
'''
self.text_browser.append(html_content)
- print("HTML content appended to QTextBrowser.") # 로그 추가
+ logger.debug("HTML content appended to QTextBrowser.") # 로그 추가
else:
- print(f"Error: Item associated with {key} is not a dictionary.") # 오류 로그
+ logger.debug(f"Error: Item associated with {key} is not a dictionary.") # 오류 로그
else:
- print(f"Ignored key: {key}") # ë¬´ì‹œëœ í‚¤ 로그
+ logger.debug(f"Ignored key: {key}") # ë¬´ì‹œëœ í‚¤ 로그
def download_image(self, image_url, identifier):
@@ -160,7 +165,7 @@ class TrademarkSearchDisplay(QWidget):
img_resized.save(image_path)
return image_path
except Exception as e:
- print(f"Error resizing image: {e}")
+ logger.debug(f"Error resizing image: {e}")
return None
diff --git a/src/test_api.py b/src/test_api.py
deleted file mode 100644
index 26ae570..0000000
--- a/src/test_api.py
+++ /dev/null
@@ -1,42 +0,0 @@
-from kipris_api_from_publicdata import Kipris
-
-# 테스트를 위한 URL ë° íŒŒë¼ë¯¸í„° ì„¤ì •
-apikey = 'X9Tz3JqC/JcCwxnNewA6qdloIN6QFIitVBgS1a2KVDYk1AmddaDTvzr6+t3dyLZV3gh2TPXdNhxsRQwaKP673Q=='
-search_keyword = "ì¨ì§€ì˜¤"
-url = 'http://kipo-api.kipi.or.kr/openapi/service/trademarkInfoSearchService/getWordSearch'
-
-params = {
- 'serviceKey': apikey,
- 'searchString': search_keyword,
- 'searchRecentYear': '0',
- 'title': '',
- 'fullText': '',
- 'drawing': '',
- 'bigDrawing': ''
-}
-
-# XMLParser ì¸ìŠ¤í„´ìŠ¤ ìƒì„± ë° ì‹¤í–‰
-parser = Kipris(url, params)
-results = parser.run()
-
-# ëª¨ë“ ì•„ì´í…œì˜ ê²°ê³¼ ì¶œë ¥
-if results:
- print("결과가 있는 ì•„ì´í…œ 목ë¡:")
- for index, item in enumerate(results, start=1):
- print(f"\nì•„ì´í…œ {index} ì •ë³´:")
- for key, value in item.items():
- print(f"{key}: {value}")
-else:
- print("결과가 없습니다.")
-
-
-# ※ í–‰ì • ìƒíƒœ ë„움ë§
-# ê±°ì ˆ : ì¶œì› í›„ 특허 ì‹¬ì‚¬ê³¼ì •ì—서 실체ì ì¸ íŠ¹í—ˆ 등ë¡ìš”ê±´ì„ ë§Œì¡±í•˜ì§€ ëª»í• ê²½ìš°ì— ì‹¬ì‚¬ê´€ì´ ì·¨í•˜ëŠ” í–‰ì •ì²˜ë¶„
-# ë“±ë¡ : ì‹¬ì‚¬ê´€ì´ ì‹¬ì‚¬í•œ ê²°ê³¼ 등ë¡ìš”ê±´ì— ì 합하여 ì„¤ì •ë“±ë¡ì„ ë°›ì„ ìˆ˜ 있다는 ë‚´ìš©ì˜ í–‰ì •ì²˜ë¶„
-# 소멸 : íŠ¹í—ˆë“±ë¡ í›„ ì¡´ì†ê¸°ê°„ì´ ë§Œë£Œë˜ì–´ 권리가 ì†Œë©¸ëœ ìƒíƒœ
-# 무효 : ì¶œì› ë˜ëŠ” 등ë¡ëœ ìƒíƒœì— 대하여 íŠ¹ì • ì‚¬ìœ ë¡œ ì¸í•´ ê·¸ 권리나 행위가 무효화 ëœ ìƒíƒœ
-# 취하 : ì¶œì›í•œ 특허가 등ë¡ë˜ê¸°ì „ 여러 ì‚¬ìœ ë¡œ ì¸í•˜ì—¬ ì¶œì›ì´ ì·¨ì†Œëœ ìƒíƒœ
-# í¬ê¸° : ì¶œì›ì¸ì˜ í¬ê¸°ì„œ ì œì¶œ, 등ë¡ë£Œ 불납 등으로 등ë¡ê²°ì •ì´ë‚˜ 권리를 í¬ê¸°í•œ ìƒíƒœ
-# 공개 : ì¶œì›ì´ë‚˜ 등ë¡ì‚¬ì‹¤ì´ ì¼ë°˜ 공중ì—게 ê³µí‘œëœ ìƒíƒœë¡œ ì¶œì› í›„ 18ê°œì›”ì´ ì§€ë‚œ ê±´
-# ï¼Šì¡°ê¸°ê³µê°œì‹ ì²ì‹œ 18개월 ë¯¸ë§Œë„ ê³µê°œê°€ëŠ¥
-#
\ No newline at end of file
diff --git a/src/toggleSwitch.py b/src/toggleSwitch.py
index 69c4b8c..b10d13e 100644
--- a/src/toggleSwitch.py
+++ b/src/toggleSwitch.py
@@ -1,6 +1,10 @@
from PyQt5.QtCore import Qt, QRect, QPropertyAnimation, pyqtProperty, pyqtSignal, QPoint
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QWidget
+import logging
+
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
class ToggleSwitch(QWidget):
clicked = pyqtSignal(bool)
diff --git a/src/web_scraper_async.py b/src/web_scraper_async.py
index 73158bd..134ae7e 100644
--- a/src/web_scraper_async.py
+++ b/src/web_scraper_async.py
@@ -4,7 +4,10 @@ import random, requests, json
from PIL import Image
from io import BytesIO
import os
+import logging
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
class WebScraper:
def __init__(self):
self.results = {}
@@ -12,6 +15,7 @@ class WebScraper:
self.browser = None
self.context = None
self.page = None
+ self.currentURL = ''
filename = 'categories.json'
self.category_description = self.load_category_descriptions(filename)
self.url = "http://kdtj.kipris.or.kr/kdtj/searchLogina.do?method=loginTM#page1"
@@ -42,9 +46,9 @@ class WebScraper:
try:
await self.page.goto(self.url, wait_until='networkidle')
self.is_page_loaded = True
- print("Page loaded successfully.")
+ logger.debug("Page loaded successfully.")
except Exception as e:
- print(f"Failed to load the page: {e}")
+ logger.debug(f"Failed to load the page: {e}")
self.is_page_loaded = False # 로드 실패 처리
@@ -52,9 +56,9 @@ class WebScraper:
try:
await self.page.goto(url, wait_until='networkidle')
self.is_page_loaded = True
- print("Page loaded successfully.")
+ logger.debug("Page loaded successfully.")
except Exception as e:
- print(f"Failed to load the page: {e}")
+ logger.debug(f"Failed to load the page: {e}")
self.is_page_loaded = False # 로드 실패 처리
@@ -65,23 +69,23 @@ class WebScraper:
# await self.page.fill("#queryText", term)
await self.page.fill("#keywordTextarea", term)
- print(f"검색어 ìž…ë ¥ : {term}")
+ logger.debug(f"검색어 ìž…ë ¥ : {term}")
await self.page.click(".input_btn")
- print(f"검색버튼 í´ë¦")
+ logger.debug(f"검색버튼 í´ë¦")
# JavaScriptì— ì˜í•´ 결과가 ë™ì 으로 로드ë˜ê¸°ë¥¼ 기다립니다.
loaded = await self.page.wait_for_function(
"document.querySelector('form#listForm section.search_section article') != null"
)
if not loaded:
- print("검색 결과가 시간 ë‚´ì— ë¡œë“œë˜ì§€ 않았습니다.")
+ logger.debug("검색 결과가 시간 ë‚´ì— ë¡œë“œë˜ì§€ 않았습니다.")
return None
- print(f"결과가 ë™ì 으로 로드ë˜ê¸°ë¥¼ 기다림 : {loaded}")
+ logger.debug(f"결과가 ë™ì 으로 로드ë˜ê¸°ë¥¼ 기다림 : {loaded}")
# 검색 결과가 없는지 확ì¸
nodata_info = await self.page.query_selector(".nodata_info")
if nodata_info:
- print("검색 결과가 없습니다.")
+ logger.debug("검색 결과가 없습니다.")
return None
# ê²°ê³¼ ë¡œë”©ì´ í™•ì¸ëœ 후, ì‹¤ì œ 요소를 수집
@@ -89,41 +93,44 @@ class WebScraper:
total_count = await self.page.text_content("form#listForm section.search_section div p span.total")
total_count = total_count.strip()
total_count = int(total_count.replace(',', ''))
- print(f"total_count : {total_count}")
+ logger.debug(f"total_count : {total_count}")
+
+ self.currentURL = self.page.url
+ logger.debug(f"currentURL : {self.currentURL}")
if total_count:
self.results['total_count'] = total_count
articles = await self.page.query_selector_all("form#listForm section.search_section article")
- print(f"articles : {len(articles)} 개")
+ logger.debug(f"articles : {len(articles)} 개")
for i, article in enumerate(articles):
id_and_name_element = await article.query_selector("div:nth-child(1) span input[type='checkbox']")
trademark_name = await id_and_name_element.get_attribute("title") if id_and_name_element else "No name found"
- print(f"trademark_name : {trademark_name}")
+ logger.debug(f"trademark_name : {trademark_name}")
applno = await id_and_name_element.get_attribute("value") if id_and_name_element else "No ID found"
trademark_image_url_by_id = (
f"http://kdtj.kipris.or.kr/kdtj/remoteFile.do?method=bigImageTM&applno={applno}&no={applno}_tm000001.jpg"
if applno else None
)
- print(f"trademark_image_url_by_id : {trademark_image_url_by_id}")
+ logger.debug(f"trademark_image_url_by_id : {trademark_image_url_by_id}")
img_element = await article.query_selector("div:nth-child(2) div a img")
trademark_image = await img_element.get_attribute("src") if img_element else "No image found"
- print(f"trademark_image : {trademark_image}")
+ logger.debug(f"trademark_image : {trademark_image}")
admin_status_element = await article.query_selector("div:nth-child(1) h1 a:nth-child(1) span")
admin_status = await admin_status_element.text_content() if admin_status_element else "No status found"
- print(f"admin_status : {admin_status}")
+ logger.debug(f"admin_status : {admin_status}")
product_category_element = await article.query_selector("div:nth-child(2) ul li:nth-child(1) a span")
product_category = await product_category_element.text_content() if product_category_element else "No category found"
category_desc = self.add_category_description(product_category) if product_category else "No category description"
- print(f"product_category : {product_category}")
- print(f"category_desc : {category_desc}")
+ logger.debug(f"product_category : {product_category}")
+ logger.debug(f"category_desc : {category_desc}")
applicant_element = await article.query_selector("div:nth-child(2) ul li:nth-child(2) span[title]")
applicant = await applicant_element.get_attribute("title") if applicant_element else "No applicant found"
- print(f"applicant : {applicant}")
+ logger.debug(f"applicant : {applicant}")
publication_date_element = await article.query_selector("div:nth-child(2) ul li:nth-child(8)")
if publication_date_element:
@@ -131,7 +138,7 @@ class WebScraper:
publication_date = publication_date_content.strip() if publication_date_content else "No publication date found"
else:
publication_date = "No publication date found"
- print(f"publication_date : {publication_date}")
+ logger.debug(f"publication_date : {publication_date}")
registration_date_element = await article.query_selector("div:nth-child(2) ul li:nth-child(6)")
if registration_date_element:
@@ -139,9 +146,9 @@ class WebScraper:
registration_date = registration_date_content.strip() if registration_date_content else "No registration date found"
else:
registration_date = "No registration date found"
- print(f"registration_date : {registration_date}")
-
- if not (admin_status == "소멸" or admin_status == "ê±°ì ˆ"):
+ logger.debug(f"registration_date : {registration_date}")
+ if admin_status in status: # status는 self.set_status 리스트를 참조
+ # if not (admin_status == "소멸" or admin_status == "ê±°ì ˆ"):
self.results[f"result_{i+1}"] = {
"ID": applno,
"title": trademark_name,
@@ -154,65 +161,65 @@ class WebScraper:
"publication_date": publication_date,
"registration_date": registration_date,
}
- # print(f"results : {self.results}")
+ # logger.debug(f"results : {self.results}")
await self.navigate_to_page(self.url)
return self.results
else:
- print("No total count element found, possibly incorrect selector or page structure has changed.")
+ logger.debug("No total count element found, possibly incorrect selector or page structure has changed.")
except Exception as e:
- print(f"오류 ë°œìƒ : {e}")
+ logger.debug(f"오류 ë°œìƒ : {e}")
return None
async def download_image(self, url, applno):
"""ì´ë¯¸ì§€ë¥¼ 비ë™ê¸°ì 으로 ë‹¤ìš´ë¡œë“œí•˜ê³ applno를 íŒŒì¼ ì´ë¦„으로 사용하여 ì €ìž¥í•©ë‹ˆë‹¤."""
async with aiohttp.ClientSession() as session:
- print(f"download_image session Start!!")
+ logger.debug(f"download_image session Start!!")
async with session.get(url) as response:
- print(f"download_image url : {url}")
+ logger.debug(f"download_image url : {url}")
if response.status == 200:
filename = f"{applno}.jpeg"
async with aiofiles.open(filename, 'wb') as file:
content = await response.read()
await file.write(content)
- print(f"ì´ë¯¸ì§€ê°€ 성공ì 으로 ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤: {filename}")
+ logger.debug(f"ì´ë¯¸ì§€ê°€ 성공ì 으로 ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤: {filename}")
else:
- print(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status}")
+ logger.debug(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status}")
async def fetch_image_data(self, url):
"""주어진 URL로부터 ì´ë¯¸ì§€ ë°ì´í„°ë¥¼ 비ë™ê¸°ì 으로 ê°€ì ¸ì™€ 반환합니다."""
async with aiohttp.ClientSession() as session:
- # print(f"download_image session Start!!")
+ # logger.debug(f"download_image session Start!!")
async with session.get(url) as response:
- print(f"download_image url : {url}")
+ logger.debug(f"download_image url : {url}")
if response.status == 200:
- # print(f"response : {response}")
+ # logger.debug(f"response : {response}")
content_type = response.headers.get('Content-Type', '') # await ì œê±°
- print(f"content_type : {content_type}")
+ logger.debug(f"content_type : {content_type}")
if 'image' in content_type or 'octet-stream' in content_type:
- # print(f"image content type or octet-stream : {content_type}")
+ # logger.debug(f"image content type or octet-stream : {content_type}")
return await response.read()
else:
try:
# Content-Typeì´ ì´ë¯¸ì§€ê°€ 아니면, ë°ì´í„°ë¥¼ ì´ë¯¸ì§€ë¡œ 변환
data = await response.read()
- # print(f"Content-Typeì´ ì´ë¯¸ì§€ê°€ 아님 : {data}")
+ # logger.debug(f"Content-Typeì´ ì´ë¯¸ì§€ê°€ 아님 : {data}")
image = Image.open(BytesIO(data))
with BytesIO() as buffer:
image.save(buffer, 'JPEG')
- print(f"image 를 JPEG로 ì €ìž¥")
+ logger.debug(f"image 를 JPEG로 ì €ìž¥")
return buffer.getvalue()
except Exception as e:
- print(f"ì´ë¯¸ì§€ 변환 실패: {e}")
+ logger.debug(f"ì´ë¯¸ì§€ 변환 실패: {e}")
return None
else:
- print(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status}")
+ logger.debug(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status}")
return None
# async def load_category_descriptions(self, filename):
# """JSON 파ì¼ì—서 ì¹´í…Œê³ ë¦¬ ì„¤ëª…ì„ ë¹„ë™ê¸°ì 으로 로드합니다."""
# async with aiofiles.open(filename, 'r', encoding='utf-8') as file:
# content = await file.read()
- # print(f"JSON 파ì¼ì—서 ì¹´í…Œê³ ë¦¬ ì„¤ëª…ì„ ë¹„ë™ê¸°ì 으로 로드합니다: {content}")
+ # logger.debug(f"JSON 파ì¼ì—서 ì¹´í…Œê³ ë¦¬ ì„¤ëª…ì„ ë¹„ë™ê¸°ì 으로 로드합니다: {content}")
# return json.loads(content)
def load_category_descriptions(self, filename):
@@ -222,7 +229,7 @@ class WebScraper:
def add_category_description(self, category_code):
"""주어진 ì¹´í…Œê³ ë¦¬ ì½”ë“œì— ë”°ë¼ ì„¤ëª…ì„ ë°˜í™˜í•©ë‹ˆë‹¤."""
- print(f"add_category_description => category_code: {category_code}")
+ logger.debug(f"add_category_description => category_code: {category_code}")
return self.category_description.get(category_code, "ì¹´í…Œê³ ë¦¬ ì„¤ëª…ì„ ì°¾ì„ ìˆ˜ 없습니다.")
diff --git a/src/web_scraper_with_re.py b/src/web_scraper_with_re.py
index 447d492..96c85aa 100644
--- a/src/web_scraper_with_re.py
+++ b/src/web_scraper_with_re.py
@@ -1,7 +1,10 @@
from requests_html import HTMLSession
import json
import requests
+import logging
+# 로거 ì¸ìŠ¤í„´ìŠ¤ ê°€ì ¸ì˜¤ê¸°
+logger = logging.getLogger('default_logger')
class WebScraper:
def __init__(self):
self.session = HTMLSession()
@@ -23,7 +26,7 @@ class WebScraper:
"""ì§€ì •ëœ URL로 ì´ë™í•˜ê³ 페ì´ì§€ë¥¼ 로드합니다."""
response = self.session.get(url)
response.html.render() # 필요 시 JavaScript 실행
- print("Page loaded successfully.")
+ logger.debug("Page loaded successfully.")
return response
def search_for_term(self, term):
@@ -43,17 +46,17 @@ class WebScraper:
search_response.html.render()
return search_response
else:
- print("í¼ì˜ action URLì„ ì°¾ì„ ìˆ˜ 없습니다.")
+ logger.debug("í¼ì˜ action URLì„ ì°¾ì„ ìˆ˜ 없습니다.")
else:
- print("검색 í¼ì„ ì°¾ì„ ìˆ˜ 없습니다.")
+ logger.debug("검색 í¼ì„ ì°¾ì„ ìˆ˜ 없습니다.")
except Exception as e:
- print(f"검색 실행 중 오류 ë°œìƒ: {e}")
+ logger.debug(f"검색 실행 중 오류 ë°œìƒ: {e}")
# response.html.render(script=script, reload=False)
# # response.html.find('#keywordTextarea', first=True).fill(term)
# self.page.evaluate(f"document.querySelector('#keywordTextarea').value = '{term}';")
- # print(f"검색어 ìž…ë ¥: {term}")
+ # logger.debug(f"검색어 ìž…ë ¥: {term}")
# input_field = response.html.find('#keywordTextarea', first=True)
# script = f"document.querySelector('#keywordTextarea').value = '{term}';"
# response.html.page.evaluate(script) # JavaScript 실행
@@ -64,7 +67,7 @@ class WebScraper:
articles = response.html.find('form#listForm section.search_section article')
if not articles:
- print("검색 결과가 없습니다.")
+ logger.debug("검색 결과가 없습니다.")
return None
# Store results in a structured format
@@ -87,9 +90,9 @@ class WebScraper:
filename = f"{applno}.jpeg"
with open(filename, 'wb') as file:
file.write(response.content)
- print(f"ì´ë¯¸ì§€ê°€ 성공ì 으로 ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤: {filename}")
+ logger.debug(f"ì´ë¯¸ì§€ê°€ 성공ì 으로 ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤: {filename}")
else:
- print(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status_code}")
+ logger.debug(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status_code}")
def fetch_image_data(self, url):
"""주어진 URL로부터 ì´ë¯¸ì§€ ë°ì´í„°ë¥¼ ì§ì ‘ ê°€ì ¸ì™€ 반환합니다."""
@@ -97,7 +100,7 @@ class WebScraper:
if response.status_code == 200:
return response.content
else:
- print(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status_code}")
+ logger.debug(f"ì´ë¯¸ì§€ 다운로드 실패: HTTP {response.status_code}")
return None
def close_browser(self):
@@ -107,4 +110,4 @@ class WebScraper:
# # 사용 예시
# scraper = WebScraper()
# results = scraper.search_for_term("특허")
-# print(results)
+# logger.debug(results)