90 lines
4.3 KiB
Python
90 lines
4.3 KiB
Python
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))
|