当前位置:首页>python>Python Web 图形验证码实战项目

Python Web 图形验证码实战项目

  • 2026-08-20 07:17:11
Python Web 图形验证码实战项目

🔐 Python Web 图形验证码实战项目

项目概述

本项目是一个基于 Flask + captcha + Pillow 技术栈构建的完整图形验证码实战演示系统。项目涵盖了从最基础的字符验证码到交互式滑块验证码的多种实现方式,提供了丰富的可视化操作界面和实时交互体验。无论你是初学者想要理解验证码的工作原理,还是开发者需要在项目中集成验证码功能,本项目都能为你提供清晰的参考实现。

技术架构

组件
技术
说明
后端框架
Flask 3.0
轻量级 Web 框架,处理路由和会话管理
验证码生成
captcha 0.5
专业的验证码图像生成库
图像处理
Pillow 10.2
Python 图像处理库,用于自定义绘制
前端
HTML5 + CSS3 + JS
现代化响应式界面,无需额外框架
会话管理
Flask Session
服务端存储验证码答案,确保安全

功能特性

🎯 五种验证码类型

  1. 标准混合验证码 — 使用 captcha 库生成包含大写字母和数字的经典验证码
  2. 自定义风格验证码 — 基于 Pillow 手动绘制,支持实时调节干扰线和噪点参数
  3. 数学运算验证码 — 随机生成加减乘运算题目,有效抵御 OCR 攻击
  4. 纯数字验证码 — 6位纯数字,模拟短信验证场景
  5. 滑块验证码 — 交互式拖拽验证,支持鼠标和触屏

📊 实时统计面板

页面顶部展示生成总数、验证成功/失败次数、成功率。

🎨 交互体验

  • 点击图片快速刷新、验证后即时视觉反馈
  • 自定义验证码参数滑动条实时调节
  • 滑块支持移动端触摸操作

项目结构

captcha_project/├── app.py                 # Flask 主应用(路由、验证码生成逻辑)├── requirements.txt       # Python 依赖├── templates/│   └── index.html         # 前端页面(完整的交互式演示界面)└── README.md              # 项目文档

快速开始

cd captcha_projectpython -m venv venvsource venv/bin/activate  # Windows: venv\Scripts\activatepip install -r requirements.txtpython app.py

浏览器打开 http://127.0.0.1:5000

API 接口

接口路径
方法
说明
/api/captcha/standard
GET
标准混合验证码图片
/api/captcha/custom?lines=&noise=
GET
自定义验证码图片
/api/captcha/math
GET
数学运算验证码图片
/api/captcha/digit
GET
纯数字验证码图片
/api/captcha/slide
GET
滑块验证码JSON
/api/verify
POST
图形验证码校验
/api/verify/slide
POST
滑块验证码校验

核心实现原理

  1. 服务端存储答案 — 验证码答案保存在 Flask Session 中,客户端无法获取
  2. 一次性验证 — 验证成功后立即删除答案,防止重放攻击
  3. 干扰元素 — 随机干扰线、噪点、字符旋转增加 OCR 识别难度
  4. 滑块容差 — 允许 ±8 像素误差,兼顾安全性和用户体验

扩展方向

  • 接入 Redis 支持分布式部署
  • 添加验证码有效期(TTL)
  • 集成音频验证码
  • 增加点选验证码
  • 前后端分离架构改造

完整源码

后端源码 app.py

"""Python Web 图形验证码实战项目基于 Flask + captcha 库实现完整的验证码生成、展示、验证流程"""from flask import Flask, render_template, session, request, jsonify, send_filefrom captcha.image import ImageCaptchafrom captcha.audio import AudioCaptchaimport randomimport stringimport ioimport osimport base64from PIL import Image, ImageDraw, ImageFont, ImageFilterapp = Flask(__name__)app.secret_key = 'captcha-demo-secret-key-2024'# ============ 验证码生成工具函数 ============defgenerate_random_text(length=4, mode='mixed'):"""生成随机验证码文本"""if mode == 'digit':        chars = string.digitselif mode == 'letter':        chars = string.ascii_uppercaseelif mode == 'math':return generate_math_captcha()else:        chars = string.ascii_uppercase + string.digitsreturn''.join(random.choices(chars, k=length))defgenerate_math_captcha():"""生成数学运算验证码"""    ops = ['+''-''×']    a = random.randint(120)    b = random.randint(120)    op = random.choice(ops)if op == '+':        answer = a + belif op == '-':if a < b:            a, b = b, a        answer = a - belse:        a = random.randint(19)        b = random.randint(19)        answer = a * b    expression = f"{a}{op}{b}=?"return expression, str(answer)defgenerate_captcha_image(text, width=200, height=80, font_size=42):"""使用 captcha 库生成标准验证码图片"""    image = ImageCaptcha(width=width, height=height, font_sizes=[font_size])    data = image.generate(text)return datadefgenerate_custom_captcha(text, width=240, height=80,                            bg_color=None, text_color=None,                            noise_level=3, line_count=5):"""自定义风格验证码 - 使用 Pillow 手动绘制"""if bg_color isNone:        bg_color = (random.randint(200255), random.randint(200255), random.randint(200255))if text_color isNone:        text_color = (random.randint(0100), random.randint(0100), random.randint(0100))    img = Image.new('RGB', (width, height), bg_color)    draw = ImageDraw.Draw(img)# 绘制干扰线for _ in range(line_count):        x1, y1 = random.randint(0, width), random.randint(0, height)        x2, y2 = random.randint(0, width), random.randint(0, height)        line_color = (random.randint(100200), random.randint(100200), random.randint(100200))        draw.line([(x1, y1), (x2, y2)], fill=line_color, width=random.randint(13))# 绘制干扰点for _ in range(width * height // noise_level):        x, y = random.randint(0, width - 1), random.randint(0, height - 1)        dot_color = (random.randint(0255), random.randint(0255), random.randint(0255))        draw.point((x, y), fill=dot_color)# 绘制文字(每个字符随机偏移和旋转)    char_width = width // (len(text) + 1)for i, char in enumerate(text):try:            font = ImageFont.truetype("arial.ttf", random.randint(3244))except (IOError, OSError):            font = ImageFont.load_default()# 创建单字符图像并旋转        char_img = Image.new('RGBA', (5060), (0000))        char_draw = ImageDraw.Draw(char_img)        char_draw.text((55), char, fill=text_color, font=font)        char_img = char_img.rotate(random.randint(-2525), expand=True, fillcolor=(0000))# 粘贴到主图        x = 10 + i * char_width        y = random.randint(520)        img.paste(char_img, (x, y), char_img)# 添加轻微模糊    img = img.filter(ImageFilter.SMOOTH)    buf = io.BytesIO()    img.save(buf, format='PNG')    buf.seek(0)return bufdefgenerate_slide_captcha(width=300, height=180):"""生成滑块验证码数据"""# 创建背景图    bg_color = (random.randint(100200), random.randint(150220), random.randint(150220))    img = Image.new('RGB', (width, height), bg_color)    draw = ImageDraw.Draw(img)# 绘制一些装饰图形for _ in range(8):        x, y = random.randint(0, width), random.randint(0, height)        r = random.randint(1040)        color = (random.randint(50200), random.randint(50200), random.randint(50200))        draw.ellipse([x - r, y - r, x + r, y + r], fill=color, outline=color)# 滑块目标位置    block_size = 40    target_x = random.randint(100, width - block_size - 20)    target_y = random.randint(20, height - block_size - 20)# 在目标位置画出缺口(灰色)    draw.rectangle([target_x, target_y, target_x + block_size, target_y + block_size],                   fill=(180180180), outline=(100100100), width=2)# 生成滑块图片    block_img = Image.new('RGBA', (block_size, block_size), (80140200230))    block_draw = ImageDraw.Draw(block_img)    block_draw.rectangle([00, block_size - 1, block_size - 1], outline=(255255255), width=2)# 转为 base64    bg_buf = io.BytesIO()    img.save(bg_buf, format='PNG')    bg_base64 = base64.b64encode(bg_buf.getvalue()).decode()    block_buf = io.BytesIO()    block_img.save(block_buf, format='PNG')    block_base64 = base64.b64encode(block_buf.getvalue()).decode()return {'bg_image': bg_base64,'block_image': block_base64,'target_x': target_x,'target_y': target_y,'block_size': block_size    }# ============ Flask 路由 ============@app.route('/')defindex():"""主页 - 验证码演示面板"""return render_template('index.html')@app.route('/api/captcha/standard', methods=['GET'])defstandard_captcha():"""标准图形验证码接口"""    text = generate_random_text(4'mixed')    session['captcha_text'] = text    data = generate_captcha_image(text)return send_file(data, mimetype='image/png')@app.route('/api/captcha/custom', methods=['GET'])defcustom_captcha():"""自定义风格验证码接口"""    noise = int(request.args.get('noise'3))    lines = int(request.args.get('lines'5))    text = generate_random_text(4'mixed')    session['captcha_text'] = text    data = generate_custom_captcha(text, noise_level=noise, line_count=lines)return send_file(data, mimetype='image/png')@app.route('/api/captcha/math', methods=['GET'])defmath_captcha():"""数学运算验证码接口"""    expression, answer = generate_math_captcha()    session['captcha_text'] = answer    data = generate_captcha_image(expression, width=240)return send_file(data, mimetype='image/png')@app.route('/api/captcha/digit', methods=['GET'])defdigit_captcha():"""纯数字验证码接口"""    text = generate_random_text(6'digit')    session['captcha_text'] = text    data = generate_captcha_image(text)return send_file(data, mimetype='image/png')@app.route('/api/captcha/slide', methods=['GET'])defslide_captcha():"""滑块验证码接口"""    slide_data = generate_slide_captcha()    session['slide_target_x'] = slide_data['target_x']return jsonify({'bg_image': slide_data['bg_image'],'block_image': slide_data['block_image'],'target_y': slide_data['target_y'],'block_size': slide_data['block_size']    })@app.route('/api/verify', methods=['POST'])defverify_captcha():"""验证码校验接口"""    data = request.get_json()    user_input = data.get('captcha''').strip().upper()    correct = session.get('captcha_text''').upper()ifnot correct:return jsonify({'success'False'message''验证码已过期,请刷新'})if user_input == correct:        session.pop('captcha_text'None)return jsonify({'success'True'message''✅ 验证成功!'})else:return jsonify({'success'False'message''❌ 验证码错误,请重试'})@app.route('/api/verify/slide', methods=['POST'])defverify_slide():"""滑块验证码校验接口"""    data = request.get_json()    user_x = data.get('x'0)    target_x = session.get('slide_target_x'0)    tolerance = 8# 容差像素if abs(user_x - target_x) <= tolerance:        session.pop('slide_target_x'None)return jsonify({'success'True'message''✅ 滑块验证成功!'})else:return jsonify({'success'False'message''❌ 滑块位置不正确,请重试'})if __name__ == '__main__':    app.run(debug=True, port=5000)

前端源码 templates/index.html

<!DOCTYPE html><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Python 图形验证码实战演示</title><style>        * {margin0;padding0;box-sizing: border-box;        }body {font-family'Segoe UI''Microsoft YaHei', sans-serif;backgroundlinear-gradient(135deg, #667eea 0%, #764ba2 100%);min-height100vh;padding20px;        }.container {max-width1100px;margin0 auto;        }h1 {text-align: center;color#fff;font-size2.2rem;margin-bottom10px;text-shadow2px2px4pxrgba(0,0,0,0.3);        }.subtitle {text-align: center;colorrgba(255,255,255,0.85);margin-bottom30px;font-size1.1rem;        }.demo-grid {display: grid;grid-template-columnsrepeat(auto-fit, minmax(480px1fr));gap24px;        }.card {background#fff;border-radius16px;padding28px;box-shadow010px40pxrgba(0,0,0,0.15);transition: transform 0.3s ease, box-shadow 0.3s ease;        }.card:hover {transformtranslateY(-4px);box-shadow014px50pxrgba(0,0,0,0.2);        }.cardh2 {color#333;font-size1.3rem;margin-bottom6px;display: flex;align-items: center;gap8px;        }.card.desc {color#666;font-size0.9rem;margin-bottom18px;line-height1.5;        }.captcha-area {display: flex;align-items: center;gap12px;margin-bottom16px;flex-wrap: wrap;        }.captcha-areaimg {border2px solid #e0e0e0;border-radius8px;cursor: pointer;transition: opacity 0.3s;        }.captcha-areaimg:hover {opacity0.7;        }.refresh-btn {padding8px16px;backgroundlinear-gradient(135deg, #667eea, #764ba2);color#fff;border: none;border-radius8px;cursor: pointer;font-size0.9rem;transition: all 0.3s;        }.refresh-btn:hover {transformscale(1.05);box-shadow04px12pxrgba(1021262340.4);        }.input-group {display: flex;gap10px;margin-bottom12px;        }.input-groupinput {flex1;padding10px16px;border2px solid #e0e0e0;border-radius8px;font-size1rem;outline: none;transition: border-color 0.3s;        }.input-groupinput:focus {border-color#667eea;        }.verify-btn {padding10px24px;background#28a745;color#fff;border: none;border-radius8px;cursor: pointer;font-size1rem;font-weight: bold;transition: all 0.3s;        }.verify-btn:hover {background#218838;transformscale(1.05);        }.result {padding10px16px;border-radius8px;font-size0.95rem;font-weight: bold;min-height40px;display: flex;align-items: center;        }.result.success {background#d4edda;color#155724;        }.result.error {background#f8d7da;color#721c24;        }.result.info {background#e8f4fd;color#0c5460;        }/* 滑块验证码样式 */.slide-container {position: relative;margin-bottom16px;        }.slide-bg {border-radius8px;display: block;width100%;max-width300px;        }.slide-block {position: absolute;cursor: grab;user-select: none;        }.slide-track {width100%;max-width300px;height40px;background#e9ecef;border-radius20px;position: relative;margin-top12px;overflow: hidden;        }.slide-thumb {width50px;height40px;backgroundlinear-gradient(135deg, #667eea, #764ba2);border-radius20px;position: absolute;left0;top0;cursor: grab;display: flex;align-items: center;justify-content: center;color#fff;font-size1.2rem;user-select: none;transition: box-shadow 0.3s;        }.slide-thumb:hover {box-shadow04px12pxrgba(1021262340.5);        }.slide-hint {position: absolute;width100%;text-align: center;line-height40px;color#999;font-size0.85rem;pointer-events: none;        }/* 参数控制面板 */.controls {display: flex;gap16px;margin-bottom16px;flex-wrap: wrap;align-items: center;        }.controlslabel {font-size0.85rem;color#555;display: flex;align-items: center;gap6px;        }.controlsinput[type="range"] {width100px;        }.controlsspan.val {font-weight: bold;color#667eea;min-width20px;        }/* 统计面板 */.stats {display: flex;gap20px;justify-content: center;margin-top30px;flex-wrap: wrap;        }.stat-item {backgroundrgba(255,255,255,0.15);backdrop-filterblur(10px);border-radius12px;padding16px28px;text-align: center;color#fff;        }.stat-item.num {font-size2rem;font-weight: bold;        }.stat-item.label {font-size0.85rem;opacity0.8;        }.badge {display: inline-block;padding2px10px;border-radius12px;font-size0.75rem;font-weight: bold;margin-left8px;        }.badge-blue { background#e3f2fdcolor#1565c0; }.badge-green { background#e8f5e9color#2e7d32; }.badge-orange { background#fff3e0color#e65100; }.badge-purple { background#f3e5f5color#6a1b9a; }</style></head><body><divclass="container"><h1>🔐 Python 图形验证码实战</h1><pclass="subtitle">Flask + Captcha + Pillow | 多种验证码类型 | 实时交互验证</p><!-- 统计面板 --><divclass="stats"><divclass="stat-item"><divclass="num"id="stat-total">0</div><divclass="label">生成总数</div></div><divclass="stat-item"><divclass="num"id="stat-success">0</div><divclass="label">验证成功</div></div><divclass="stat-item"><divclass="num"id="stat-fail">0</div><divclass="label">验证失败</div></div><divclass="stat-item"><divclass="num"id="stat-rate">0%</div><divclass="label">成功率</div></div></div><br><divclass="demo-grid"><!-- 标准验证码 --><divclass="card"><h2>📝 标准混合验证码 <spanclass="badge badge-blue">经典</span></h2><pclass="desc">使用 captcha 库生成包含大写字母和数字的标准验证码,带干扰线和噪点。点击图片可刷新。</p><divclass="captcha-area"><imgid="standard-img"src="/api/captcha/standard"alt="验证码"width="200"height="80"onclick="refreshCaptcha('standard')"><buttonclass="refresh-btn"onclick="refreshCaptcha('standard')">🔄 换一张</button></div><divclass="input-group"><inputtype="text"id="standard-input"placeholder="请输入验证码(不区分大小写)"maxlength="4"onkeypress="if(event.key==='Enter') verifyCaptcha('standard')"><buttonclass="verify-btn"onclick="verifyCaptcha('standard')">验证</button></div><divclass="result"id="standard-result"></div></div><!-- 自定义风格验证码 --><divclass="card"><h2>🎨 自定义风格验证码 <spanclass="badge badge-purple">可调参</span></h2><pclass="desc">使用 Pillow 手动绘制,支持调节干扰线数量、噪点密度,每个字符随机旋转偏移。</p><divclass="controls"><label>干扰线: <inputtype="range"id="lines-range"min="1"max="15"value="5"oninput="document.getElementById('lines-val').textContent=this.value"><spanclass="val"id="lines-val">5</span></label><label>噪点密度: <inputtype="range"id="noise-range"min="1"max="10"value="3"oninput="document.getElementById('noise-val').textContent=this.value"><spanclass="val"id="noise-val">3</span></label></div><divclass="captcha-area"><imgid="custom-img"src="/api/captcha/custom"alt="验证码"width="240"height="80"onclick="refreshCaptcha('custom')"><buttonclass="refresh-btn"onclick="refreshCaptcha('custom')">🔄 换一张</button></div><divclass="input-group"><inputtype="text"id="custom-input"placeholder="请输入验证码"maxlength="4"onkeypress="if(event.key==='Enter') verifyCaptcha('custom')"><buttonclass="verify-btn"onclick="verifyCaptcha('custom')">验证</button></div><divclass="result"id="custom-result"></div></div><!-- 数学运算验证码 --><divclass="card"><h2>🧮 数学运算验证码 <spanclass="badge badge-green">趣味</span></h2><pclass="desc">随机生成加减乘运算题目,需要计算结果后输入答案。适合防止简单 OCR 破解。</p><divclass="captcha-area"><imgid="math-img"src="/api/captcha/math"alt="验证码"width="240"height="80"onclick="refreshCaptcha('math')"><buttonclass="refresh-btn"onclick="refreshCaptcha('math')">🔄 换一题</button></div><divclass="input-group"><inputtype="text"id="math-input"placeholder="请输入计算结果"maxlength="4"onkeypress="if(event.key==='Enter') verifyCaptcha('math')"><buttonclass="verify-btn"onclick="verifyCaptcha('math')">验证</button></div><divclass="result"id="math-result"></div></div><!-- 纯数字验证码 --><divclass="card"><h2>🔢 纯数字验证码 <spanclass="badge badge-orange">6位</span></h2><pclass="desc">6位纯数字验证码,常见于手机短信验证场景的图形化展示,安全性适中。</p><divclass="captcha-area"><imgid="digit-img"src="/api/captcha/digit"alt="验证码"width="200"height="80"onclick="refreshCaptcha('digit')"><buttonclass="refresh-btn"onclick="refreshCaptcha('digit')">🔄 换一张</button></div><divclass="input-group"><inputtype="text"id="digit-input"placeholder="请输入6位数字"maxlength="6"onkeypress="if(event.key==='Enter') verifyCaptcha('digit')"><buttonclass="verify-btn"onclick="verifyCaptcha('digit')">验证</button></div><divclass="result"id="digit-result"></div></div><!-- 滑块验证码 --><divclass="card"style="grid-column: 1 / -1;"><h2>🎯 滑块验证码 <spanclass="badge badge-purple">交互式</span></h2><pclass="desc">拖动滑块到缺口位置完成验证,模拟主流网站的行为验证方式。体验拖拽交互验证的趣味性。</p><divclass="slide-container"id="slide-container"><imgclass="slide-bg"id="slide-bg"alt="背景"><imgclass="slide-block"id="slide-block"alt="滑块"></div><divclass="slide-track"id="slide-track"><divclass="slide-hint">← 拖动滑块到缺口位置 →</div><divclass="slide-thumb"id="slide-thumb"></div></div><br><buttonclass="refresh-btn"onclick="loadSlide()"style="margin-bottom: 12px;">🔄 重新加载</button><divclass="result"id="slide-result"></div></div></div></div><script>// ============ 统计数据 ============let stats = { total0success0fail0 };functionupdateStats() {document.getElementById('stat-total').textContent = stats.total;document.getElementById('stat-success').textContent = stats.success;document.getElementById('stat-fail').textContent = stats.fail;const rate = stats.total > 0 ? Math.round(stats.success / stats.total * 100) : 0;document.getElementById('stat-rate').textContent = rate + '%';        }// ============ 验证码刷新 ============functionrefreshCaptcha(type{const img = document.getElementById(type + '-img');let url = '/api/captcha/' + type;if (type === 'custom') {const lines = document.getElementById('lines-range').value;const noise = document.getElementById('noise-range').value;                url += `?lines=${lines}&noise=${noise}`;            }            img.src = url + (url.includes('?') ? '&' : '?') + 't=' + Date.now();            stats.total++;            updateStats();// 清空输入和结果const input = document.getElementById(type + '-input');const result = document.getElementById(type + '-result');if (input) input.value = '';if (result) {                result.textContent = '';                result.className = 'result';            }        }// ============ 验证码校验 ============asyncfunctionverifyCaptcha(type{const input = document.getElementById(type + '-input');const result = document.getElementById(type + '-result');const value = input.value.trim();if (!value) {                result.textContent = '⚠️ 请先输入验证码';                result.className = 'result info';return;            }try {const resp = await fetch('/api/verify', {method'POST',headers: { 'Content-Type''application/json' },bodyJSON.stringify({ captcha: value })                });const data = await resp.json();                result.textContent = data.message;if (data.success) {                    result.className = 'result success';                    stats.success++;                    setTimeout(() => refreshCaptcha(type), 1500);                } else {                    result.className = 'result error';                    stats.fail++;                    setTimeout(() => refreshCaptcha(type), 1000);                }                updateStats();            } catch (err) {                result.textContent = '⚠️ 网络错误,请重试';                result.className = 'result error';            }        }// ============ 滑块验证码 ============let slideData = null;asyncfunctionloadSlide() {const result = document.getElementById('slide-result');            result.textContent = '';            result.className = 'result';try {const resp = await fetch('/api/captcha/slide');                slideData = await resp.json();const bgImg = document.getElementById('slide-bg');const blockImg = document.getElementById('slide-block');                bgImg.src = 'data:image/png;base64,' + slideData.bg_image;                blockImg.src = 'data:image/png;base64,' + slideData.block_image;                blockImg.style.left = '0px';                blockImg.style.top = slideData.target_y + 'px';document.getElementById('slide-thumb').style.left = '0px';                stats.total++;                updateStats();            } catch (err) {console.error('加载滑块验证码失败:', err);            }        }// 滑块拖拽逻辑        (function() {const thumb = document.getElementById('slide-thumb');const track = document.getElementById('slide-track');const block = document.getElementById('slide-block');let isDragging = false;let startX = 0;let thumbLeft = 0;            thumb.addEventListener('mousedown'function(e{                isDragging = true;                startX = e.clientX;                thumbLeft = parseInt(thumb.style.left) || 0;                thumb.style.cursor = 'grabbing';                e.preventDefault();            });document.addEventListener('mousemove'function(e{if (!isDragging) return;const dx = e.clientX - startX;const trackWidth = track.offsetWidth - thumb.offsetWidth;let newLeft = Math.min(Math.max(0, thumbLeft + dx), trackWidth);                thumb.style.left = newLeft + 'px';if (block && slideData) {const ratio = 260 / trackWidth;                    block.style.left = Math.round(newLeft * ratio) + 'px';                }            });document.addEventListener('mouseup'asyncfunction(e{if (!isDragging) return;                isDragging = false;                thumb.style.cursor = 'grab';const trackWidth = track.offsetWidth - thumb.offsetWidth;const currentLeft = parseInt(thumb.style.left) || 0;const ratio = 260 / trackWidth;const finalX = Math.round(currentLeft * ratio);if (currentLeft > 10) {try {const resp = await fetch('/api/verify/slide', {method'POST',headers: { 'Content-Type''application/json' },bodyJSON.stringify({ x: finalX })                        });const data = await resp.json();const result = document.getElementById('slide-result');                        result.textContent = data.message;if (data.success) {                            result.className = 'result success';                            stats.success++;                            setTimeout(loadSlide, 2000);                        } else {                            result.className = 'result error';                            stats.fail++;                            setTimeout(loadSlide, 1000);                        }                        updateStats();                    } catch (err) {console.error('验证失败:', err);                    }                }            });// 触摸事件支持(移动端)            thumb.addEventListener('touchstart'function(e{                isDragging = true;                startX = e.touches[0].clientX;                thumbLeft = parseInt(thumb.style.left) || 0;                e.preventDefault();            });document.addEventListener('touchmove'function(e{if (!isDragging) return;const dx = e.touches[0].clientX - startX;const trackWidth = track.offsetWidth - thumb.offsetWidth;let newLeft = Math.min(Math.max(0, thumbLeft + dx), trackWidth);                thumb.style.left = newLeft + 'px';if (block && slideData) {const ratio = 260 / trackWidth;                    block.style.left = Math.round(newLeft * ratio) + 'px';                }            });document.addEventListener('touchend'function(e{if (!isDragging) return;                isDragging = false;const trackWidth = track.offsetWidth - thumb.offsetWidth;const currentLeft = parseInt(thumb.style.left) || 0;const ratio = 260 / trackWidth;const finalX = Math.round(currentLeft * ratio);if (currentLeft > 10) {                    fetch('/api/verify/slide', {method'POST',headers: { 'Content-Type''application/json' },bodyJSON.stringify({ x: finalX })                    }).then(r => r.json()).then(data => {const result = document.getElementById('slide-result');                        result.textContent = data.message;if (data.success) {                            result.className = 'result success';                            stats.success++;                            setTimeout(loadSlide, 2000);                        } else {                            result.className = 'result error';                            stats.fail++;                            setTimeout(loadSlide, 1000);                        }                        updateStats();                    });                }            });        })();// 页面加载时初始化滑块window.addEventListener('load', loadSlide);</script></body></html>

依赖文件 requirements.txt

flask==3.0.0captcha==0.5.0Pillow==10.2.0

许可证

MIT License - 可自由使用、修改和分发。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 22:54:57 HTTP/2.0 GET : https://f.mffb.com.cn/a/506938.html
  2. 运行时间 : 0.329743s [ 吞吐率:3.03req/s ] 内存消耗:4,647.23kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=5d2650ccbda9e871d71f79bfafdf0563
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000808s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001324s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.003876s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.016767s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001379s ]
  6. SELECT * FROM `set` [ RunTime:0.026329s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001631s ]
  8. SELECT * FROM `article` WHERE `id` = 506938 LIMIT 1 [ RunTime:0.006326s ]
  9. UPDATE `article` SET `lasttime` = 1787324097 WHERE `id` = 506938 [ RunTime:0.012275s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000703s ]
  11. SELECT * FROM `article` WHERE `id` < 506938 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.007998s ]
  12. SELECT * FROM `article` WHERE `id` > 506938 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.020217s ]
  13. SELECT * FROM `article` WHERE `id` < 506938 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.041531s ]
  14. SELECT * FROM `article` WHERE `id` < 506938 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.013922s ]
  15. SELECT * FROM `article` WHERE `id` < 506938 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.004033s ]
0.335796s