From d8292f9bca70838fb5400b69e1cb9393ca574ae0 Mon Sep 17 00:00:00 2001 From: fuzhongyun <15339891972@163.com> Date: Wed, 1 Apr 2026 09:23:33 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=B4=E6=97=B6=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=EF=BC=9B=E8=84=B1=E6=95=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + capture_fingerprint.py | 49 ---------------------------- deploy.sh | 72 ++++++++++++++++++++---------------------- main.py | 48 ++++++++++++++++++++++------ 4 files changed, 74 insertions(+), 96 deletions(-) create mode 100644 .gitignore delete mode 100644 capture_fingerprint.py mode change 100755 => 100644 deploy.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/capture_fingerprint.py b/capture_fingerprint.py deleted file mode 100644 index ba41fbd..0000000 --- a/capture_fingerprint.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -import asyncio -from playwright.async_api import async_playwright - -TARGET_PAGE = "https://gd.10086.cn/gdshop/qdxsd/index.html#/gd-fls/marketingActivity/index?id=1956241557401346048" -TARGET_API = "https://gd.10086.cn/gdshop/apigw/adv/ad/getInsertCode" -FINGERPRINT_HEADER = "x-device-fingerprint" - - -async def capture_fingerprint(): - async with async_playwright() as p: - browser = await p.chromium.launch(headless=True) - page = await browser.new_page() - - fingerprint_future = asyncio.Future() - - async def handle_request(request): - if TARGET_API in request.url and not fingerprint_future.done(): - headers = request.headers - if FINGERPRINT_HEADER in headers: - fingerprint = headers[FINGERPRINT_HEADER] - fingerprint_future.set_result(fingerprint) - - page.on("request", handle_request) - - print(f"[信息] 正在打开页面...") - await page.goto(TARGET_PAGE, wait_until="networkidle") - - try: - print(f"[信息] 等待指纹参数...") - fingerprint = await asyncio.wait_for(fingerprint_future, timeout=15) - print(f"\n{'='*60}") - print(f"[成功] 指纹参数捕获成功:") - print(f" {FINGERPRINT_HEADER}: {fingerprint}") - print(f"{'='*60}\n") - return fingerprint - except asyncio.TimeoutError: - print(f"\n{'='*60}") - print(f"[错误] 等待超时,未能捕获到 {FINGERPRINT_HEADER} 参数") - print(f"{'='*60}\n") - return None - finally: - await browser.close() - - -if __name__ == "__main__": - asyncio.run(capture_fingerprint()) - diff --git a/deploy.sh b/deploy.sh old mode 100755 new mode 100644 index 73cdeb1..3d555f7 --- a/deploy.sh +++ b/deploy.sh @@ -2,29 +2,39 @@ set -e -IMAGE_NAME="gd10086-fingerprint-service" -CONTAINER_NAME="gd10086-fingerprint-service" -PORT="10086" +IMAGE_NAME="web-signature-service" +CONTAINER_NAME="web-signature-service" +PORT="8000" echo "=========================================" -echo "广东移动指纹获取服务 - 部署脚本" +echo "Web Header Signature Service - Deploy" echo "=========================================" cd "$(dirname "$0")" +# 检查 .env 文件,如果存在则加载 +ENV_FILE="" +if [ -f ".env" ]; then + echo "Found .env file, will use it for deployment." + ENV_FILE="--env-file .env" +else + echo "Warning: .env file not found. Service will use default target configurations." +fi + case "${1:-up}" in up) echo "" - echo "[1/3] 构建 Docker 镜像..." + echo "[1/3] Building Docker image..." docker build -t ${IMAGE_NAME} . echo "" - echo "[2/3] 停止旧容器(如果存在)..." + echo "[2/3] Stopping old container (if exists)..." docker stop ${CONTAINER_NAME} 2>/dev/null || true docker rm ${CONTAINER_NAME} 2>/dev/null || true echo "" - echo "[3/3] 启动服务..." + echo "[3/3] Starting service..." + # 注意: 传入环境变量配置 docker run -d \ --name ${CONTAINER_NAME} \ -p ${PORT}:8000 \ @@ -32,58 +42,44 @@ case "${1:-up}" in -v /dev/shm:/dev/shm \ --security-opt seccomp=unconfined \ -e TZ=Asia/Shanghai \ + ${ENV_FILE} \ ${IMAGE_NAME} echo "" - echo "等待服务启动..." - sleep 5 + echo "Waiting for service to start..." + sleep 3 echo "" echo "=========================================" - echo "部署完成!" + echo "Deployment completed!" echo "" - echo "服务地址: http://localhost:${PORT}" - echo "API 文档: http://localhost:${PORT}/docs" - echo "健康检查: http://localhost:${PORT}/health" - echo "获取指纹: http://localhost:${PORT}/fingerprint" + echo "Service URL: http://localhost:${PORT}" + echo "API Docs: http://localhost:${PORT}/docs" + echo "Health: http://localhost:${PORT}/health" + echo "Get Sign: http://localhost:${PORT}/fingerprint" echo "" - echo "查看日志: docker logs -f ${CONTAINER_NAME}" - echo "停止服务: docker stop ${CONTAINER_NAME}" - echo "删除容器: docker rm ${CONTAINER_NAME}" + echo "View Logs: docker logs -f ${CONTAINER_NAME}" + echo "Stop: docker stop ${CONTAINER_NAME}" echo "=========================================" ;; down) - echo "" - echo "停止服务..." + echo "Stopping service..." docker stop ${CONTAINER_NAME} 2>/dev/null || true docker rm ${CONTAINER_NAME} 2>/dev/null || true - echo "服务已停止" + echo "Service stopped." ;; logs) - echo "" - echo "查看日志..." docker logs -f ${CONTAINER_NAME} ;; - restart) - echo "" - echo "重启服务..." - docker restart ${CONTAINER_NAME} - echo "服务已重启" - ;; - *) - echo "" - echo "用法: $0 [命令]" - echo "" - echo "命令:" - echo " up - 构建并启动服务(默认)" - echo " down - 停止并删除容器" - echo " logs - 查看日志" - echo " restart - 重启服务" - echo "" + echo "Usage: $0 [command]" + echo "Commands:" + echo " up - Build and start (default)" + echo " down - Stop and remove" + echo " logs - View logs" ;; esac diff --git a/main.py b/main.py index a2ca03b..2d80b9c 100644 --- a/main.py +++ b/main.py @@ -1,14 +1,23 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- import asyncio +import os +import logging from typing import Optional from contextlib import asynccontextmanager from fastapi import FastAPI, HTTPException from playwright.async_api import async_playwright -TARGET_PAGE = "https://gd.10086.cn/gdshop/qdxsd/index.html#/gd-fls/marketingActivity/index?id=1956241557401346048" -TARGET_API = "https://gd.10086.cn/gdshop/apigw/adv/ad/getInsertCode" -FINGERPRINT_HEADER = "x-device-fingerprint" +# 配置日志 +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger("fingerprint_service") + +TARGET_PAGE = os.getenv("TARGET_PAGE") +TARGET_API = os.getenv("TARGET_API") +FINGERPRINT_HEADER = os.getenv("FINGERPRINT_HEADER") playwright_instance = None browser = None @@ -19,6 +28,7 @@ RESOURCE_CACHE = {} @asynccontextmanager async def lifespan(app: FastAPI): global playwright_instance, browser + logger.info("Starting Playwright instance...") playwright_instance = await async_playwright().start() browser = await playwright_instance.chromium.launch( headless=True, @@ -29,20 +39,24 @@ async def lifespan(app: FastAPI): "--disable-software-rasterizer", ] ) + logger.info("Playwright browser launched successfully.") yield + logger.info("Closing Playwright browser...") await browser.close() await playwright_instance.stop() + logger.info("Playwright instance stopped.") app = FastAPI( - title="广东移动指纹获取服务", - description="获取 x-device-fingerprint 参数的 API 服务", + title="Web Header Signature Service", + description="API service for dynamic header signature generation via headless browser", version="1.0.0", lifespan=lifespan ) async def get_fingerprint(): + logger.info("Opening new browser page...") page = await browser.new_page() try: # [新增] 拦截无用资源,极大提升加载速度 @@ -59,6 +73,7 @@ async def get_fingerprint(): # 2. 强缓存 JS 文件 if resource_type == "script": if url in RESOURCE_CACHE: + logger.debug(f"Cache hit for script: {url}") await route.fulfill( status=200, headers=RESOURCE_CACHE[url]["headers"], @@ -68,6 +83,7 @@ async def get_fingerprint(): # 缓存未命中,去真实抓取 try: + logger.debug(f"Fetching script: {url}") response = await route.fetch() body = await response.body() RESOURCE_CACHE[url] = { @@ -76,7 +92,8 @@ async def get_fingerprint(): } await route.fulfill(response=response, body=body) return - except Exception: + except Exception as e: + logger.warning(f"Failed to fetch script {url}: {e}") pass # 抓取失败,降级给底层处理 await route.continue_() @@ -89,24 +106,33 @@ async def get_fingerprint(): if TARGET_API in request.url and not fingerprint_future.done(): headers = request.headers if FINGERPRINT_HEADER in headers: + logger.info("Successfully intercepted target API request with required header.") fingerprint_future.set_result(headers[FINGERPRINT_HEADER]) page.on("request", handle_request) # [修改] 并发执行 goto 和 wait_for。拿到结果就立刻返回,不再死等 goto 结束 + logger.info(f"Navigating to target page: {TARGET_PAGE}") goto_task = asyncio.create_task(page.goto(TARGET_PAGE, wait_until="domcontentloaded")) + logger.info("Waiting for header generation...") fingerprint = await asyncio.wait_for(fingerprint_future, timeout=15) + logger.info("Header successfully generated and retrieved.") return fingerprint except asyncio.TimeoutError: + logger.error("Timeout while waiting for header generation.") + return None + except Exception as e: + logger.error(f"Unexpected error during generation: {str(e)}") return None finally: + logger.info("Closing browser page...") await page.close() @app.get("/") async def root(): - return {"status": "ok", "message": "广东移动指纹获取服务"} + return {"status": "ok", "message": "Web Header Signature Service is running"} @app.get("/health") @@ -116,9 +142,11 @@ async def health(): @app.get("/fingerprint") async def get_fingerprint_endpoint(): + logger.info("Received request for new header signature") try: fingerprint = await get_fingerprint() if fingerprint: + logger.info("Successfully handled signature request") return { "status": "success", "data": { @@ -126,9 +154,11 @@ async def get_fingerprint_endpoint(): } } else: - raise HTTPException(status_code=500, detail="获取指纹失败") + logger.error("Failed to generate signature (returned None)") + raise HTTPException(status_code=500, detail="Failed to generate signature") except Exception as e: - raise HTTPException(status_code=500, detail=f"服务错误: {str(e)}") + logger.error(f"Service error during request: {str(e)}") + raise HTTPException(status_code=500, detail=f"Service error: {str(e)}") if __name__ == "__main__":