# -*- coding: utf-8 -*- """ 지오영 장바구니 HTML 분석 및 삭제 버튼 API 캡처 """ import asyncio import os import re from dotenv import load_dotenv load_dotenv(r'c:\Users\청춘약국\source\pharmacy-wholesale-api\.env') async def analyze_cart_html(): from playwright.async_api import async_playwright username = os.getenv('GEOYOUNG_USER_ID') password = os.getenv('GEOYOUNG_PASSWORD') print("=" * 60) print("지오영 장바구니 HTML 분석") print("=" * 60) async with async_playwright() as p: browser = await p.chromium.launch(headless=True) context = await browser.new_context() page = await context.new_page() # 1. 로그인 print("\n1️⃣ 로그인 중...") await page.goto("https://gwn.geoweb.kr/Member/Login") await page.wait_for_load_state('networkidle') # 로그인 폼 찾기 await page.fill('input[type="text"], input[name*="id"], #userId', username) await page.fill('input[type="password"], input[name*="pw"], #userPwd', password) # 로그인 버튼 클릭 login_btns = ['button[type="submit"]', 'input[type="submit"]', '.btn-login', 'button:has-text("로그인")'] for btn_sel in login_btns: try: btn = page.locator(btn_sel).first if await btn.count() > 0: await btn.click() break except: pass await asyncio.sleep(3) await page.wait_for_load_state('networkidle') # 로그인 확인 if 'Login' in page.url: print("❌ 로그인 실패") await browser.close() return print(f"✅ 로그인 성공 (URL: {page.url})") # 2. 장바구니 HTML 가져오기 (AJAX) print("\n2️⃣ 장바구니 HTML 가져오기...") # PartialProductCart API 직접 호출 cart_response = await page.evaluate(''' async () => { const response = await fetch('/Home/PartialProductCart', { method: 'POST', headers: {'X-Requested-With': 'XMLHttpRequest'} }); return await response.text(); } ''') print(f"\n📦 장바구니 HTML 길이: {len(cart_response)} bytes") # 삭제 관련 키워드 찾기 patterns = [ r'onclick="[^"]*del[^"]*"', r'onclick="[^"]*Del[^"]*"', r'onclick="[^"]*삭제[^"]*"', r'class="[^"]*del[^"]*"', r'id="[^"]*del[^"]*"', r'function\s+\w*[dD]el\w*\s*\(', r'전체\s*삭제', r'delAll', r'deleteAll', ] print("\n🔍 삭제 관련 패턴 검색:") for pattern in patterns: matches = re.findall(pattern, cart_response, re.IGNORECASE) if matches: for m in matches[:3]: # 최대 3개만 print(f" ✅ {pattern}: {m[:100]}...") # 버튼 요소 찾기 print("\n🔘 버튼 요소:") button_pattern = r']*>.*?|]*class="[^"]*btn[^"]*"[^>]*>.*?' buttons = re.findall(button_pattern, cart_response, re.DOTALL | re.IGNORECASE) for btn in buttons[:10]: clean_btn = re.sub(r'\s+', ' ', btn)[:150] print(f" • {clean_btn}") # JavaScript 함수 찾기 print("\n📜 JavaScript 함수 (del/remove 관련):") js_pattern = r'function\s+(\w*[dD]el\w*|\w*[rR]emove\w*)\s*\([^)]*\)\s*\{[^}]*\}' js_funcs = re.findall(js_pattern, cart_response) for func in js_funcs[:5]: print(f" • {func}") # 전체 스크립트 태그에서 DataCart 관련 찾기 print("\n🔧 DataCart API 호출 패턴:") datacart_pattern = r'DataCart[^"\']*' datacart_matches = re.findall(datacart_pattern, cart_response) for m in set(datacart_matches): print(f" • {m}") # 페이지 전체 HTML에서도 검색 print("\n3️⃣ 메인 페이지에서 추가 검색...") await page.goto("https://gwn.geoweb.kr/Home/Order") await page.wait_for_load_state('networkidle') await asyncio.sleep(2) full_html = await page.content() # DataCart 관련 전체 검색 print("\n🔧 전체 페이지 DataCart API:") datacart_all = re.findall(r'/Home/DataCart/\w+', full_html) for api in set(datacart_all): print(f" • {api}") # 삭제 함수 찾기 print("\n📜 삭제 관련 함수:") del_funcs = re.findall(r'function\s+(\w*[dD]el\w*)\s*\(', full_html) for func in set(del_funcs): print(f" • {func}()") # 삭제 onclick 찾기 print("\n🖱️ 삭제 onclick:") del_onclick = re.findall(r'onclick="([^"]*[dD]el[^"]*)"', full_html) for onclick in set(del_onclick)[:5]: print(f" • {onclick[:100]}") await browser.close() print("\n✅ 분석 완료") if __name__ == "__main__": asyncio.run(analyze_cart_html())