动态二维码外部实时展示系统

Python3.8

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

好的,恭喜你!从一个想法到最终在服务器上稳定运行,你已经走完了一个工程师最完整的开发 -> 部署 -> 运维的闭环。

现在,我将履行我的承诺,为你整理一份终极部署手册。这份手册将沉淀我们所有的对话精髓,抹去所有我们走过的弯路,只留下最正确、最高效的操作流程。它既是你的项目复盘,也是一份可以交付给任何其他技术人员,让他们能在全新环境中从零开始、完美复现整个系统的标准作业程序(SOP)。


项目部署手册:微信/支付宝小程序动态二维码外部实时展示系统

版本: 1.0
最后更新: 2025-11-02

一、 项目概述 (Project Overview)

本项目旨在通过自动化手段,捕获在安卓模拟器中运行的微信或支付宝小程序内的动态二维码,并将其近乎实时地展示在一个公开的Web页面上,供外部用户扫描。

核心架构:
本项目采用三端分离的客户端/服务器架构。

  1. 自动化主机 (Automation Host):一台本地Windows PC,负责7x24小时运行安卓模拟器和Python截图上传脚本。
  2. Web应用服务器 (Web Server):一台云端Linux服务器,负责运行Java Spring Boot应用,接收图片并向外提供Web展示页面。
  3. 用户终端 (User Client):用户的手机浏览器,访问Web页面并查看实时二维码。

技术栈:

  • 前端: HTML5, CSS3, JavaScript
  • 后端: Java 17+, Spring Boot
  • 自动化脚本: Python 3.8+
  • 运行环境: Windows 10/11 (自动化主机), Debian/Ubuntu/CentOS (Web服务器)
  • 核心工具: 安卓模拟器 (MuMu模拟器12), systemd

二、 Web应用服务器部署 (云端Linux)

这是整个系统的“心脏”,负责接收和展示数据。

步骤1:服务器环境准备
  1. 购买服务器: 购买一台入门级云服务器(推荐腾讯云/阿里云的轻量应用服务器,2核4G配置足矣),选择Linux操作系统(如Debian 11)。
  2. 安装Java:
    # 更新软件包列表
    sudo apt update
    # 安装JDK 17 (推荐)
    sudo apt install openjdk-17-jdk -y
    # 验证安装
    java --version
    
  3. 安装Maven (用于打包):
    sudo apt install maven -y
    # 验证安装
    mvn -v
    
  4. 创建应用目录:
    # 创建用于存放jar包的目录
    mkdir -p /app/qrcode
    # 创建用于存放上传图片的目录
    mkdir -p /app/uploads/images
    
步骤2:后端Java代码

在你的开发环境中,创建一个新的Spring Boot项目。

  1. pom.xml (核心依赖与打包插件)
    确保<build>部分包含正确的spring-boot-maven-plugin配置。

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
  2. src/main/resources/application.properties (配置文件)

    # 应用服务 WEB 访问端口
    server.port=9090
    # 文件将保存在服务器的绝对路径下
    file.upload-dir=/app/uploads/images
    
  3. src/main/java/.../QrCodeApplication.java (主启动类)

    package com.example.qrcode; // 请替换为你的包名
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class QrCodeApplication {
        public static void main(String[] args) {
            SpringApplication.run(QrCodeApplication.class, args);
        }
    }
    
  4. src/main/java/.../controller/FileUploadController.java (图片上传接口)

    package com.example.qrcode.controller; // 请替换为你的包名
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;
    import java.io.File;
    import java.io.IOException;
    
    @RestController
    public class FileUploadController {
        @Value("${file.upload-dir}")
        private String uploadDir;
        private final String SECRET_TOKEN = "YourSuperSecretToken12345"; // !!!请务必修改为一个复杂的密码!!!
    
        @PostMapping("/upload/qrcode")
        public ResponseEntity<String> handleFileUpload(
                @RequestParam("file") MultipartFile file,
                @RequestHeader("X-Auth-Token") String token) {
    
            if (token == null || !token.equals(SECRET_TOKEN)) {
                return new ResponseEntity<>("Unauthorized", HttpStatus.UNAUTHORIZED);
            }
            if (file.isEmpty()) {
                return new ResponseEntity<>("File is empty", HttpStatus.BAD_REQUEST);
            }
            try {
                File directory = new File(uploadDir);
                if (!directory.exists()) {
                    directory.mkdirs();
                }
                File dest = new File(directory.getAbsolutePath() + File.separator + "dynamic_qrcode.jpg");
                file.transferTo(dest);
                return new ResponseEntity<>("Upload success", HttpStatus.OK);
            } catch (IOException e) {
                e.printStackTrace();
                return new ResponseEntity<>("Upload failed", HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
    }
    
  5. src/main/java/.../config/WebConfig.java (外部资源映射)

    package com.example.qrcode.config; // 请替换为你的包名
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Value("${file.upload-dir}")
        private String uploadDir;
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            String resourceLocation = "file:" + uploadDir + "/";
            registry.addResourceHandler("/images/**")
                    .addResourceLocations(resourceLocation);
        }
    }
    
步骤3:前端HTML代码
  1. src/main/resources/static/qrcode.html (手机端优化的展示页面)
    将上一份回答中为你量身定做的、带移动端适配和刷新进度条的最终版HTML代码完整复制到此文件中。
步骤4:打包与部署
  1. 打包项目:在你的开发电脑上,项目根目录下执行:

    mvn clean package
    

    这会在 target/ 目录下生成一个 ...SNAPSHOT.jar 文件。

  2. 上传JAR包: 使用 scpWinSCP 等工具,将这个 jar 文件上传到你云服务器的 /app/qrcode/ 目录下。

  3. 创建systemd服务

    • 服务器上,创建并编辑服务文件:
      sudo vim /etc/systemd/system/qrcode.service
      
    • 写入以下内容,请务必根据你的实际情况修改 ExecStart 中的Java路径和JAR包路径
      [Unit]
      Description=QR Code Display Service
      After=network.target
      
      [Service]
      User=root
      WorkingDirectory=/app/qrcode
      ExecStart=/usr/bin/java -jar /app/qrcode/qr_code-0.0.1-SNAPSHOT.jar # 用 which java 命令找到你的java绝对路径
      SuccessExitStatus=143
      Restart=on-failure
      RestartSec=5s
      
      [Install]
      WantedBy=multi-user.target
      ```4.  **管理服务**:
      
    # 重新加载systemd配置
    sudo systemctl daemon-reload
    # 启动服务
    sudo systemctl start qrcode.service
    # 检查服务状态
    sudo systemctl status qrcode.service
    # 设置开机自启
    sudo systemctl enable qrcode.service
    

三、 自动化主机部署 (本地Windows PC)

这是系统的“眼睛和手”,负责捕获和上传图像。

步骤1:环境准备
  1. 安装安卓模拟器: 从官网下载并安装 MuMu模拟器12
  2. 配置模拟器:
    • 性能: 设置为4核CPU,4G内存。
    • Root权限: 必须关闭
    • 机型: 伪装成一个主流手机型号。
    • 安卓系统设置: 屏幕休眠设置为“永不”。
  3. 安装Python: 从官网下载并安装Python 3.8或更高版本,安装时勾选“Add Python to PATH”。
  4. 安装Python库:
    pip install pyautogui requests Pillow
    
  5. 在模拟器中安装支付宝: 登录并稳定显示二维码页面。
步骤2:Python脚本

将以下代码保存为 capture_script.py

import pyautogui
import time
import requests
import io
from PIL import Image

# --- !!! 核心配置 - 需要你手动修改 !!! ---

# 1. 截图区域: (左上角X坐标, 左上角Y坐标, 截图宽度, 截图高度)
#    提示: 使用微信或QQ的截图工具 (Ctrl+Alt+A) 来精确测量模拟器窗口内二维码的这个矩形区域。
QR_CODE_REGION = (100, 200, 320, 320)  # !!! 这是一个示例值,必须替换 !!!

# 2. 你的Java服务器的上传API地址
UPLOAD_URL = "http://你的服务器公网IP:9090/upload/qrcode" # !!! 必须替换 !!!

# 3. 与Java代码中完全一致的安全令牌
AUTH_TOKEN = "YourSuperSecretToken12345" # !!! 必须替换 !!!

# --- 主程序逻辑 ---
print(f"自动化脚本启动,将截图并上传到: {UPLOAD_URL}")
print(f"截图区域: {QR_CODE_REGION}")

while True:
    try:
        # 1. 对指定区域进行截图
        screenshot = pyautogui.screenshot(region=QR_CODE_REGION)

        # 2. 压缩图片为JPEG以降低延迟
        img_buffer = io.BytesIO()
        screenshot.save(img_buffer, format='JPEG', quality=90)
        img_byte_arr = img_buffer.getvalue()

        # 3. 准备上传数据
        files = {'file': ('dynamic_qrcode.jpg', img_byte_arr, 'image/jpeg')}
        headers = {'X-Auth-Token': AUTH_TOKEN}

        # 4. 发送HTTP POST请求
        response = requests.post(UPLOAD_URL, files=files, headers=headers, timeout=10)

        # 5. 检查响应
        if response.status_code == 200:
            print(f"上传成功: {time.strftime('%Y-%m-%d %H:%M:%S')}")
        else:
            print(f"!!! 上传失败! 状态码: {response.status_code}, 响应: {response.text}")

    except requests.exceptions.RequestException as e:
        print(f"!!! 网络错误: {e}")
    except Exception as e:
        print(f"!!! 发生未知错误: {e}")

    # 6. 等待3秒 (与前端JS刷新频率保持一致)
    time.sleep(3)

四、 系统最终启动流程

  1. 启动服务器: 确保云服务器上的qrcode.service正在active (running)
  2. 启动自动化主机:
    • 打开MuMu模拟器,登录支付宝,稳定显示二维码页面。
    • 调整好模拟器窗口在电脑桌面上的位置,确保它不会被遮挡。
    • 打开命令行,运行Python脚本:python capture_script.py
  3. 验证: 在手机浏览器中打开 http://你的服务器公网IP:9090/qrcode.html,你应该能看到实时刷新的二维码。

这份手册凝聚了我们所有的努力和智慧。只要严格按照步骤执行,任何人都可以在一个全新的环境中,快速、准确地将这套系统重新部署起来。

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值