import asyncio import os import random from playwright.async_api import async_playwright from playwright_stealth import stealth_async # pip install playwright-stealth async def test_url(url: str): async with async_playwright() as p: base_path = os.path.dirname(os.path.abspath(__file__)) browser_path = os.path.join(base_path, 'src', 'browsers', 'chromium-1140', 'chrome-win', 'chrome.exe') extension_path = os.path.join(base_path, 'src', 'browsers', 'extensions', '1.1.100_0') user_data_dir = os.path.join(base_path, 'src', 'browsers', 'user_data') debug_mode = False user_agent = random.choice([ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.0.0", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 OPR/85.0.0.0", ]) browser = await p.chromium.launch_persistent_context( user_data_dir, headless=True, permissions=["geolocation", "notifications"], geolocation={"latitude": 37.5665, "longitude": 126.9780}, locale="ko-KR", args=[ '--disable-popup-blocking', f'--disable-extensions-except={extension_path}', f'--load-extension={extension_path}', '--start-maximized', '--window-size=1920,1080', '--disable-blink-features=AutomationControlled' ], executable_path=browser_path, user_agent=user_agent ) page = await browser.new_page() # 기존 Stealth 적용 await stealth_async(page) # 추가 JS 주입을 통해 탐지 우회 스크립트 실행 await page.evaluate("""() => { // navigator.webdriver 값 삭제 Object.defineProperty(navigator, 'webdriver', { get: () => undefined }); // navigator.languages 재정의 (예: 한국어, 영어) Object.defineProperty(navigator, 'languages', { get: () => ['ko-KR', 'en-US'] }); // navigator.plugins 가 실제 브라우저처럼 보이도록 임의의 값 설정 Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5] }); // permissions.query 재정의: 알림에 대해서는 실제 권한 상태를 반환 const originalQuery = window.navigator.permissions.query; window.navigator.permissions.query = (parameters) => { if (parameters.name === 'notifications') { return Promise.resolve({ state: Notification.permission }); } return originalQuery(parameters); }; // window.chrome 객체 추가 (일부 사이트에서 이를 확인) window.chrome = { runtime: {} }; }""") print("Navigating to", url) await page.goto(url) await page.wait_for_selector("body", timeout=10000) title = await page.title() print("Page Title:", title) content = await page.content() print("Page content length:", len(content)) # __NEXT_DATA__ 스크립트 존재 여부 확인 (대소문자 구분 없이) if "__NEXT_DATA__" in content or "__next_data__" in content: print("__NEXT_DATA__ 스크립트가 페이지 소스에 존재합니다.") else: print("__NEXT_DATA__ 스크립트를 찾을 수 없습니다.") await browser.close() if __name__ == '__main__': test_url_str = "https://search.shopping.naver.com/search/all?bt=-1&frm=NVSCPRO&query=ambishop%20%EC%BD%94%EC%B9%B4%EC%BD%9C%EB%9D%BC%20%EB%AF%B8%EB%8B%88%20%EB%83%89%EC%9E%A5%EA%B3%A0%20%EB%A0%88%ED%8A%B8%EB%A1%9C%20%EB%A7%A5%EC%A3%BC%20%EC%BA%A0%ED%95%91%EC%9A%A9%20%EC%9B%90%EB%A3%B8%20%EC%9E%90%EC%B7%A8%EB%B0%A9%20%EB%A0%88%EB%93%9C%20%EA%B0%95%ED%99%94" asyncio.run(test_url(test_url_str))