Amateur开发日记
本文最后更新于20 天前,其中的信息可能已经过时,如有错误请发送邮件到likethedramaallthetime@gmail.com

项目地址

DefensiveSniper/Amateur

此项目仅为蒟蒻本人学习、接触知识而随手创建的,目前没有任何实际意义。

Flask

打包flask

pyinstaller --onefile --noconsole --name=flask_server --add-data "templates;templates" --add-data "static;static" --add-data "func;func" --add-data "base;base" --add-data "libs;libs" --add-data "cache;cache" --add-data "tools;tools" --collect-binaries azure.cognitiveservices.speech --collect-all dns --collect-all eventlet flask_server.py

或者:

pyi-makespec flask_server.py
pyinstaller flask_server.spec

flask_server.spec 里面添加参数

解释:

  • --onefile :打包成一个独立的文件
  • --noconsole :隐藏终端窗口,避免黑框弹出
  • --add-data "templates;templates":添加数据,防止找不到关联文件
  • --name=flask_server :生成 flask_server.exe

成功后,dist/ 目录下会生成 flask_server.exe

Electron

打包 Electron

安装 Electron 及构建工具

npm install
npm install -g electron electron-builder wait-on concurrently

修改 package.json

package.json 里,添加:

"build": {
  "appId": "com.yourapp.id",
  "productName": "AmateurApp",
  "win": {
    "target": "nsis",
    "icon": "static/images/logo.ico"
  }
}

执行打包,onlyWindows

electron-builder --win --x64

ps:记得改版本号

运行

npm run start

ps:记得在main.js中变动调试代码

笔记

前端FormData内容的获取

表单用 FormData 时,只会收集带有 name 属性的表单项,和 id 没关系。

<form id="douyin-download-form" style="display: flex; flex-direction: column; gap: 22px;">
  <label>
    <span style="font-weight:500;">sec_user_id:</span>
    <input type="text" name="sec_user_id" id="sec_user_id" class="input-field" placeholder="请输入sec_user_id" required>
  </label>
</form>

const formData = new FormData(form);
const data = Object.fromEntries(formData.entries());

<input>中的name属性缺失,那么data的数据则为空

eventlet猴子补丁

保证在monkey_patch之后才import其它内容,否则requests、threading、socketio、Flask内部依赖的socket等都无法被eventlet控制。

猴子补丁一定要在最最最最前面打,不然所有异步、websocket、定时操作全都可能崩溃。

import eventlet
eventlet.monkey_patch()

import .....

request请求返回的三种结构

response.text字符串,拿到的是网页或接口响应的“文本内容”。

response.json() 是直接解析成 Python 的字典/列表(前提是返回内容本身就是标准 JSON 格式)。

response.content二进制内容,比如图片、文件等。

BUG

PyInstaller打包

临时目录问题

File "func\get_a_bogus.py", line 11, in <module>
  douyin_sign_obj = execjs.compile(open('libs/douyin.js', encoding='utf-8-sig').read())
FileNotFoundError: [Errno 2] No such file or directory: 'libs/douyin.js'

--onefile 模式下,所有文件是打包到一个 .exe 中的,运行时会被解压到临时目录sys._MEIPASS),而不是在真实磁盘上的 libs/ 路径中。

.exe 中运行时,找的是 当前目录下的 libs/douyin.js,但它实际在临时目录中,所以失败了。

import sys
import os

def resource_path(relative_path):
    if hasattr(sys, '_MEIPASS'):
        # 打包后运行,从临时目录加载
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.abspath(relative_path)

douyin_js_path = resource_path("libs/douyin.js")
with open(douyin_js_path, encoding='utf-8-sig') as f:
    douyin_sign_obj = execjs.compile(f.read())

ValueError: Invalid async_mode specified

Flask-SocketIO 在初始化时会检查 async_mode,如果你没有指定,它会自动选择一个可用的。但在 PyInstaller 打包后,如果某些异步库(如 eventletgevent)未被正确包含或安装,就会导致这个错误。

在stack overflow中佬的回答解决了这个问题,即在打包的py文件中加入:

from engineio.async_drivers import gevent,eventlet

AttributeError: ‘NoneType’ object has no attribute ‘write’

这个错误的根本原因是:eventlet.wsgi.server()log 参数为 None,而它内部却尝试调用 log.write(...)

eventlet.wsgi.server() 中有一个 log 参数,用于记录 WSGI 启动/退出等日志。

  • 如果你没有传入这个参数(或 PyInstaller 打包后出了问题),serv.log 会是 None
  • 然后程序调用了 serv.log.write(...),于是就报错了。

socketio.run(app, port=6969, log_output=True)
#或者
socketio.run(app, port=6969, log=sys.stdout)

改为

# 安全日志对象(兼容 eventlet)
logger = logging.getLogger("eventlet")
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler())

# 使用底层的 eventlet 方式启动,显式传 log
import eventlet
import eventlet.wsgi
listener = eventlet.listen(('0.0.0.0', 6969))
eventlet.wsgi.server(listener, app, log=logger)

日志

2025.2.6 AmateurApp1.0.0

2025.2.6 AmateurApp1.0.1 修复了应用伪关闭的问题

2025.2.7 AmateurApp1.1.0 添加了AI交流,支持DeepSeek和OPENAI的多种模型

2025.2.8 AmateurApp1.1.2 在ai交流页面添加“新聊天”按钮,优化“配置”设置

2025.2.16 AmateurApp1.1.3 添加了AI交流上下文

2025.7.7 AmateurApp1.1.4 添加了聊天记录功能

2025.7.24 AmateurApp1.1.5 添加了抖音主页视频下载功能,优化了UI,修复了一些BUG(使用Trae SOLO模式)不过AI交流的流式输出有些问题

2025.8.6 AmateurApp1.1.6 添加了抖音分享链接视频下载功能

2025.8.15 对项目进行重构,去除electron,保留flask和前端,使用tauri构建桌面

标题:Amateur开发日记
作者:LovelyYy
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇