OpenSSL手写HTTPS客户端:嵌入式TLS通信最小实现
简介本资源是一份面向C开发者与网络编程初学者的HTTPS通信实战项目聚焦OpenSSL在MFC环境下的集成应用解决传统Socket无法直接访问HTTPS站点的核心痛点。代码完整实现了原生Socket HTTP POST登录与基于OpenSSL的HTTPS POST登录已实测通过小米官网并附带编译好的OpenSSL头文件、静态/动态库及全部依赖项开箱即用大幅降低HTTPS接入门槛。压缩包共148个文件含9个核心cpp源文件、81个h头文件涵盖客户端基类、登录服务、静态工具等模块、2个可执行exe及配套资源文件结构清晰便于理解分层设计逻辑整体大小为40.15MB。目前已有711人学习下载适合希望掌握安全通信底层实现、快速复用HTTPS客户端能力的中初级C工程师。1. OpenSSL访问HTTPS一个被低估的“裸金属”网络通信能力它不依赖任何高级框架却能让你在嵌入式设备、安全网关或自研协议栈里用不到200行C代码完成带证书校验、SNI支持、TLS 1.2/1.3协商的HTTPS POST请求——适合需要完全掌控握手细节、规避第三方库绑定、或在无libc/std::filesystem环境如某些RTOS或精简Linux镜像下做轻量级HTTP交互的开发者。你可能已经用过libcurl、Boost.Beast甚至Qt Network但当某天你面对一台只开放了OpenSSL 1.1.1静态库、禁用动态链接、且不允许引入新.so的工业网关时你会发现所有“开箱即用”的封装都成了累赘。而这份OpenSSL访问HTTPS项目就是从零手写的一套最小可行实现——它不封装成SDK不抽象成Client类不提供异步回调就老老实实走BIO SSL connect write read这条最原始的链路。它跑通了GitHub API的POST提交、阿里云IoT平台的设备认证、以及某高校实验室自研传感器网关的固件升级通知。核心逻辑全部落在https_client.cpp里连错误码都直接SSL_get_error()后查表打印没有一行魔法。如果你正卡在“怎么让OpenSSL不跳过证书验证”“为什么SNI没发出去导致Nginx返回421”“如何复用SSL_CTX避免重复加载根证书”这类问题上这篇笔记就是为你写的血泪经验总结。2. 环境准备与编译链路从源码包到可执行二进制的完整构建闭环2.1 依赖版本锚定为什么必须是OpenSSL 1.1.1而非3.x这个项目明确要求OpenSSL ≥ 1.1.1原因很实际1.1.1是最后一个广泛预装于CentOS 7/Ubuntu 18.04等长期支持系统的版本且其API如SSL_CTX_set_alpn_protos、SSL_set_tlsext_host_name在嵌入式交叉编译中兼容性极佳而OpenSSL 3.0引入了provider机制和OSSL_PARAM导致SSL_CTX_new(TLS_client_method())这类经典写法需额外初始化provider对资源受限环境属于冗余负担。项目中CMakeLists.txt强制检查find_package(OpenSSL 1.1.1 REQUIRED) if(OpenSSL_VERSION VERSION_LESS 1.1.1) message(FATAL_ERROR OpenSSL 1.1.1 or higher required, found ${OpenSSL_VERSION}) endif()提示若系统默认为OpenSSL 3.x如Ubuntu 22.04请先通过apt install libssl1.1 libssl-dev降级或用-DOPENSSL_ROOT_DIR/path/to/openssl-1.1.1指定路径。别试图用-DOPENSSL_USE_STATIC_LIBSON硬切——静态链接1.1.1的.a文件时libcrypto.a和libssl.a的符号顺序必须严格为-lssl -lcrypto -ldl -pthread否则SSL_connect()会报undefined reference to CRYPTO_malloc。2.2 编译命令与关键宏定义项目采用CMake构建但不生成install规则所有产物直出build/目录。标准流程如下mkdir build cd build cmake -DCMAKE_BUILD_TYPERelease \ -DOPENSSL_ROOT_DIR/usr/local/ssl \ # 若OpenSSL装在非标准路径 -DENABLE_DEBUG_LOGOFF \ # 生产环境关闭调试日志 .. make -j$(nproc)其中ENABLE_DEBUG_LOG宏控制是否启用DEBUG_PRINT()宏定义在utils.h中该宏本质是带时间戳的fprintf(stderr, ...)不依赖iostream或spdlog确保在无C标准库环境下仍可输出关键状态如SSL_do_handshake() returned -1。编译后生成两个可执行文件https_post_demo演示向https://httpbin.org/post发送JSON数据https_custom_auth演示向私有API服务端发送含Authorization: Bearer token头的请求。2.3 目录结构与文件职责划分整个源码包共7个文件结构极度扁平无子模块嵌套. ├── CMakeLists.txt # 构建入口定义target、link_libraries、compile_options ├── https_client.h # 核心接口声明HttpsClient类含init(), post(), cleanup()三方法 ├── https_client.cpp # 实现主体SSL_CTX初始化、BIO建立、握手、HTTP报文构造、读响应 ├── utils.h / utils.cpp # 跨平台工具get_current_time_ms()、hex_dump()、base64_encode() ├── certs/ # 证书目录空需用户自行放入 │ ├── ca-bundle.crt # PEM格式根证书包推荐用curl官网的cacert.pem │ └── client_cert.pem # 可选双向认证所需的客户端证书 └── examples/ # 使用示例非构建目标 └── simple_post.cpp # 最小调用示例new HttpsClient()-post(url, json_body)注意certs/目录为空这是刻意设计——项目不打包任何证书强制用户理解证书来源。若直接运行demo会因SSL_CTX_load_verify_locations()失败而退出这正是为了防止“证书黑盒化”带来的安全盲区。3. 核心模块拆解HttpsClient类的四阶段生命周期与关键代码逐行注释3.1 初始化阶段SSL_CTX创建与安全策略配置HttpsClient::init()是整个流程的起点它不连接网络只准备TLS上下文。关键代码如下bool HttpsClient::init(const std::string ca_path, const std::string cert_path, const std::string key_path) { // 1. 全局OpenSSL初始化仅首次调用生效 SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); // 2. 创建SSL上下文指定TLS客户端方法 m_ctx SSL_CTX_new(TLS_client_method()); // TLS_client_method()自动适配1.2/1.3 if (!m_ctx) { ERR_print_errors_fp(stderr); return false; } // 3. 加载根证书必选否则verify_modeSSL_VERIFY_NONE if (ca_path.empty() || !SSL_CTX_load_verify_locations(m_ctx, ca_path.c_str(), nullptr)) { fprintf(stderr, Failed to load CA certificates from %s\n, ca_path.c_str()); return false; } // 4. 强制证书验证关键绕过常见“跳过验证”陷阱 SSL_CTX_set_verify(m_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); // 5. 启用SNIServer Name Indication解决虚拟主机场景 SSL_CTX_set_tlsext_host_name(m_ctx, m_hostname.c_str()); // 6. 设置ALPN协议列表优先协商h2HTTP/2fallback到http/1.1 const unsigned char alpn_list[] {0x02, h, 2, 0x08, h, t, t, p, /, 1, ., 1}; SSL_CTX_set_alpn_protos(m_ctx, alpn_list, sizeof(alpn_list)); return true; }参数说明与踩坑点ca_path必须是PEM格式的CA bundle文件路径如certs/ca-bundle.crt不能是目录。若传入目录路径SSL_CTX_load_verify_locations()静默失败后续握手必然因证书链不信任而中断。SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT这是双向认证的简化写法。单向认证只需SSL_VERIFY_PEER但加上FAIL_IF_NO_PEER_CERT后若服务端未返回证书如配置错误SSL_do_handshake()会直接失败避免进入“看似成功实则未验证”的玄学状态。SSL_CTX_set_tlsext_host_name()必须在SSL_new()之前调用且m_hostname必须是域名如api.example.com不能是IP。若服务端是IP直连且未配置SNI此处可跳过但绝大多数CDN和云服务必须开启。3.2 连接与握手阶段BIO封装与超时控制HttpsClient::connect()完成TCP连接与TLS握手这里用BIOBasic Input/Output抽象层替代原始socket是OpenSSL的惯用模式bool HttpsClient::connect(const std::string host, int port, int timeout_ms) { m_hostname host; m_port port; // 1. 创建SSL对象并关联BIO m_ssl SSL_new(m_ctx); if (!m_ssl) return false; // 2. 创建TCP连接BIO阻塞模式 m_bio BIO_new_connect((host : std::to_string(port)).c_str()); if (!m_bio) return false; // 3. 设置连接超时单位秒OpenSSL 1.1.1支持毫秒级精度 BIO_set_conn_timeout(m_bio, timeout_ms / 1000.0); // 注意BIO_set_conn_timeout接受double秒 // 4. 执行TCP连接 if (BIO_do_connect(m_bio) 0) { fprintf(stderr, TCP connect failed: %s\n, get_ssl_error_string().c_str()); return false; } // 5. 将BIO关联到SSL对象 SSL_set_bio(m_ssl, m_bio, m_bio); // 6. 执行TLS握手含证书验证 int ret SSL_do_handshake(m_ssl); if (ret 0) { int ssl_err SSL_get_error(m_ssl, ret); if (ssl_err SSL_ERROR_WANT_READ || ssl_err SSL_ERROR_WANT_WRITE) { // 非阻塞场景需轮询但本项目用阻塞BIO此分支不应出现 fprintf(stderr, SSL handshake pending - unexpected in blocking mode\n); } fprintf(stderr, SSL handshake failed: %s\n, get_ssl_error_string().c_str()); return false; } // 7. 验证服务器证书手动触发确保verify_result为X509_V_OK long verify_result SSL_get_verify_result(m_ssl); if (verify_result ! X509_V_OK) { fprintf(stderr, Certificate verification failed: %s\n, X509_verify_cert_error_string(verify_result)); return false; } return true; }关键逻辑说明BIO_new_connect()创建的是阻塞式BIO因此BIO_do_connect()会等待直到连接建立或超时。timeout_ms参数被转换为double传入这是OpenSSL 1.1.1的改进旧版本只支持整数秒。SSL_set_bio(m_ssl, m_bio, m_bio)将同一个BIO同时设为读写通道这是客户端典型用法。若需分离读写如调试抓包可创建两个BIO并分别设置。证书验证必须手动检查SSL_get_verify_result()即使设置了SSL_VERIFY_PEEROpenSSL也不会在SSL_do_handshake()失败时直接暴露验证结果。很多开发者误以为“握手成功证书有效”结果在生产环境遭遇中间人攻击而不自知。3.3 请求发送阶段手写HTTP/1.1报文与SSL写入HttpsClient::post()不依赖任何HTTP解析库直接拼接字符串发送std::string HttpsClient::post(const std::string url, const std::string body, const std::mapstd::string, std::string headers) { if (!m_ssl) return Not connected; // 1. 构造HTTP请求行与头部 std::ostringstream req; req POST url HTTP/1.1\r\n; req Host: m_hostname \r\n; req User-Agent: OpenSSL-Client/1.0\r\n; req Content-Type: application/json\r\n; req Content-Length: body.length() \r\n; // 2. 添加用户自定义header for (const auto h : headers) { req h.first : h.second \r\n; } req \r\n; // 空行分隔header与body // 3. 发送header int sent SSL_write(m_ssl, req.str().c_str(), req.str().length()); if (sent 0) { return Failed to send headers: get_ssl_error_string(); } // 4. 发送body sent SSL_write(m_ssl, body.c_str(), body.length()); if (sent 0) { return Failed to send body: get_ssl_error_string(); } // 5. 读取响应简单版读到EOF或超时 char buf[4096]; std::string response; int len; while ((len SSL_read(m_ssl, buf, sizeof(buf)-1)) 0) { buf[len] \0; response buf; if (response.find(\r\n\r\n) ! std::string::npos) break; // 读到header结束 } return response; }为什么不用HTTP/2虽然SSL_CTX_set_alpn_protos()已设置h2但本项目未实现HPACK压缩、流ID管理、SETTINGS帧交换等HTTP/2必需逻辑。对于简单POST场景HTTP/1.1更稳定——SSL_read()一次读到完整响应体即可无需处理多路复用帧解析。若需HTTP/2应切换至nghttp2库而非在OpenSSL层硬啃。4. 常见问题排查5条真实翻车记录与对应解法4.1 现象SSL_do_handshake()返回-1SSL_get_error()返回SSL_ERROR_SSLERR_print_errors_fp输出error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure原因服务端要求TLS 1.3但客户端OpenSSL版本虽为1.1.1却未启用TLS 1.3支持1.1.1默认编译时禁用TLS 1.3。解决重新编译OpenSSL时添加enable-tls1_3参数或在SSL_CTX_new()后显式设置协议范围// 在init()中SSL_CTX_new()之后添加 const SSL_METHOD* method TLS_client_method(); m_ctx SSL_CTX_new(method); SSL_CTX_set_min_proto_version(m_ctx, TLS1_2_VERSION); // 至少TLS 1.2 SSL_CTX_set_max_proto_version(m_ctx, TLS1_3_VERSION); // 最高支持TLS 1.34.2 现象连接成功但SSL_get_verify_result()返回X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY原因ca_path指向的证书文件格式错误。常见错误包括文件是DER格式二进制但OpenSSL只接受PEMBase64编码-----BEGIN CERTIFICATE-----头尾文件包含多个证书但未用空行分隔文件权限为root-only普通用户进程无法读取。解决用openssl x509 -in ca-bundle.crt -text -noout验证格式用chmod 644 ca-bundle.crt修复权限若为DER格式用openssl x509 -inform DER -in cert.der -outform PEM -out cert.pem转换。4.3 现象向Nginx反向代理发送请求返回421 Misdirected Request原因未设置SNISSL_CTX_set_tlsext_host_name()导致Nginx无法将请求路由到正确server块。解决确认m_hostname变量在connect()前已被正确赋值为最终目标域名非代理IP并在init()中调用SSL_CTX_set_tlsext_host_name(m_ctx, m_hostname.c_str())。注意该函数必须在SSL_new()之前调用否则无效。4.4 现象SSL_write()返回SSL_ERROR_WANT_WRITE程序卡死原因BIO被配置为非阻塞模式但代码未实现select()或poll()轮询逻辑。本项目默认使用阻塞BIO此现象只会在手动修改BIO_set_nbio(m_bio, 1)后出现。解决删除所有BIO_set_nbio()调用或若必须非阻塞则重写post()为事件循环模式参考OpenSSL官方ssl/ssltest.c中的do_handshake()实现。4.5 现象https_post_demo运行时报Segmentation fault (core dumped)GDB显示崩溃在SSL_free(m_ssl)原因m_ssl指针为nullptr时调用了SSL_free()通常因connect()失败后未检查m_ssl有效性就进入析构。解决在HttpsClient::~HttpsClient()中添加空指针检查HttpsClient::~HttpsClient() { if (m_ssl) SSL_free(m_ssl); if (m_ctx) SSL_CTX_free(m_ctx); // BIO会在SSL_free时自动释放无需单独BIO_free(m_bio) }5. 二次开发实战从POST到双向认证、自定义证书校验与HTTP/2支持扩展5.1 支持双向认证mTLS注入客户端证书与密钥双向认证需服务端配置ssl_verify_client on客户端则需提供证书链与私钥。扩展HttpsClient::init()如下// 在init()中证书加载部分后添加 if (!cert_path.empty() !key_path.empty()) { if (SSL_CTX_use_certificate_chain_file(m_ctx, cert_path.c_str()) 0) { fprintf(stderr, Failed to load client certificate from %s\n, cert_path.c_str()); return false; } if (SSL_CTX_use_PrivateKey_file(m_ctx, key_path.c_str(), SSL_FILETYPE_PEM) 0) { fprintf(stderr, Failed to load client private key from %s\n, key_path.c_str()); return false; } // 验证私钥是否匹配证书 if (!SSL_CTX_check_private_key(m_ctx)) { fprintf(stderr, Private key does not match the certificate\n); return false; } }关键点SSL_CTX_use_certificate_chain_file()加载的是证书链文件client_cert.pem内容应包含客户端证书中间CA证书而非单个证书。若服务端只信任根CA此步骤可省略仅需SSL_CTX_set_verify(m_ctx, SSL_VERIFY_PEER, verify_callback)配合自定义回调。5.2 自定义证书校验绕过特定域名的CN检查某些老旧设备证书CN字段不规范如为IP地址但证书本身可信。此时可编写verify_callback替代默认验证static int custom_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) { if (preverify_ok) return 1; // 默认验证已通过 X509* cert X509_STORE_CTX_get_current_cert(ctx); int err X509_STORE_CTX_get_error(ctx); // 若错误为unable to get local issuer certificate且目标域名在白名单中忽略 char common_name[256]; X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, common_name, sizeof(common_name)); std::string target_host legacy-device.local; if (err X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY std::string(common_name) target_host) { return 1; // 强制通过 } return preverify_ok; } // 在init()中替换SSL_CTX_set_verify SSL_CTX_set_verify(m_ctx, SSL_VERIFY_PEER, custom_verify_callback);注意此做法降低安全性仅限内网可控设备。生产环境应推动设备更新证书。5.3 HTTP/2支持集成nghttp2发送HEADERS帧若需真正HTTP/2需放弃手写HTTP报文改用nghttp2库。改造思路如下connect()成功后调用nghttp2_session_client_new()创建session实现send_callback将nghttp2_frame序列化为SSL_write()发送实现on_data_chunk_recv_callback从SSL_read()接收数据后喂给nghttp2_session_mem_recv()构造nghttp2_nv数组设置headers调用nghttp2_submit_request()提交。最小改动示例在post()中// 替换原hand-written HTTP logic nghttp2_nv hdrs[] { MAKE_NV(:method, POST), MAKE_NV(:path, url.c_str()), MAKE_NV(:authority, m_hostname.c_str()), MAKE_NV(content-type, application/json), }; int32_t stream_id nghttp2_submit_request(session, nullptr, hdrs, 4, data_provider, nullptr); nghttp2_session_send(session); // 触发SSL_write代价增加libnghttp2依赖但换来真正的流控、优先级、服务器推送等HTTP/2特性。从那以后我每次在嵌入式项目里做HTTPS通信都会先用这个项目搭个最小原型——不是为了直接上线而是为了快速验证证书链、SNI、ALPN这些底层参数是否配置正确。它像一把手术刀把TLS握手从黑匣子变成可观察、可打断、可单步的确定性过程。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

操作系统结构深度解析:从单体到微内核的工程权衡与设计动机

操作系统结构深度解析:从单体到微内核的工程权衡与设计动机

1. 从"操作系统结构"这个标题里,我读出了什么很多人看到"操作系统结构"这几个字,第一反应是"这不就是课本上那几张图吗"——单体结构、分层结构、微内核、模块化,背完拉倒。我当年学这门课的时候也是这个心态&…

2026/10/17 7:49:14 阅读更多 →
函数调用集成实战:机器学习如何让AI原生应用从聊天到办事

函数调用集成实战:机器学习如何让AI原生应用从聊天到办事

上个月我在重构一个AI原生应用的信息聚合助手时,遇到一个特别典型的困境:模型已经很聪明了,能理解用户的复杂表达,但它只会输出文字。用户问"明天北京适合穿什么出门",它确实可以回答"明天北京有小雨&a…

2026/10/17 7:48:14 阅读更多 →
Python命令行待办清单实战:用标准库串起基础语法与本地持久化

Python命令行待办清单实战:用标准库串起基础语法与本地持久化

简介:这是一份面向 Python 初学者的命令行待办事项练习资源,帮助读者在本地环境中通过实现增删任务、保存与加载数据等核心功能,掌握 CLI 程序的基本开发思路。资源围绕 add_one_task、print_list、delete_task、save_todos、load_todos 五个…

2026/10/17 7:48:14 阅读更多 →

最新新闻

STM32C5开发LSM6DSK320X(7)--自由落体检测

STM32C5开发LSM6DSK320X(7)--自由落体检测

**STM32C5开发LSM6DSK320X .7--自由落体检测**概述视频教学样品申请源码下载硬件准备参考程序串口配置IIC配置CS和SA0设置INT设置生成项目导入STM32CubeIDE设置工程编码串口 printf 重定向参考程序CMake设置驱动接口与中断回调配置传感器接口初始化与设备检查加速度计与中断输出…

2026/10/17 8:23:20 阅读更多 →
TraeCN实战:AI集成IDE重塑Python开发全流程

TraeCN实战:AI集成IDE重塑Python开发全流程

最近这几个月,我把手头的 Python 项目陆续从原来的编辑器切到了TraeCN上,整个开发节奏肉眼可见地快了不少。说实话,最开始我对这种“AI 集成进 IDE”的产品是有点观望态度的,但真正跑完一个从零到交付的完整项目之后,我…

2026/10/17 8:23:20 阅读更多 →
Spring Boot+MyBatis课程网站设计与实现:覆盖资源、作业与答疑

Spring Boot+MyBatis课程网站设计与实现:覆盖资源、作业与答疑

简介:基于网络的操作系统课程教学网站设计与实现源码包,是一套完整的Java毕业设计项目,面向计算机专业学生以及需要快速搭建在线教学平台的开发者。项目围绕课程讲义、视频教程、在线测试、答疑解惑、作业提交和成绩查询等核心功能展开&#…

2026/10/17 8:23:20 阅读更多 →
造像Z-image-Turbo:扩散模型少步推理加速与质感保持实战

造像Z-image-Turbo:扩散模型少步推理加速与质感保持实战

最近在优化一套图像生成服务的延迟预算时,我又跟“速度”和“质感”这对老冤家打了照面。图像生成领域的老朋友应该都有同感:步数加上去,画质是稳了,用户端的等待时间也跟着上去了;步数压到两三次,延迟倒是…

2026/10/17 8:23:20 阅读更多 →
华为eNSP核心诊断命令实战:路由、ARP与STP排障链路

华为eNSP核心诊断命令实战:路由、ARP与STP排障链路

1. 项目概述:为什么“ENSP常用简单命令(二)”不是重复劳动,而是实操进阶的关键一环在某高校网络工程实训室带学生做实验时,我常遇到一个典型现象:刚学完“display ip interface brief”“sysname R1”这类基…

2026/10/17 8:23:20 阅读更多 →
Sidecar模式后训练:让本地大模型持续进化的工程实践

Sidecar模式后训练:让本地大模型持续进化的工程实践

本地大模型最尴尬的处境,不是跑不快,而是“永远长不大”。你辛苦部署好一个开源模型,它回答常识问题头头是道,但一问到你自己的项目笔记、工作文档、私人资料,它立刻露馅。YoungAi 这个思路有意思的地方在于&#xff0…

2026/10/17 8:22:20 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →