C#调用OPCDAAuto.dll实战:COM互操作与工业数据采集
简介这份资源是一套用C#实现的OPC客户端示例工程面向从事工业自动化上位机开发、需要与OPC DA服务器进行数据交互的.NET开发者尤其适合刚接触COM组件调用的初中级程序员参考。压缩包共58个文件约223KB以cs源码、exe可执行文件、dll组件、config配置、resx资源及pdb调试文件为主另含sln解决方案、csproj工程文件与setup64.bat注册脚本结构完整可直接编译运行。资源重点解决OPCDAAuto.dll的COM注册与.NET Framework 4目标框架兼容问题读者可据此掌握连接OPC服务器、订阅与读写Tags的完整流程并借鉴其中的错误处理与地址空间组织思路。目前已有526人学习下载适合作为OPC客户端开发的入门模板与排错参考。1. 用 C# 调 OPCDAAuto.dll一个老工控人拆包后的真实判断车间里那台老 PLC 还在跑上位机却要换成新写的 C# 程序这种场面做工业自动化的基本都遇到过。OPC 作为过程控制里最通用的数据交换标准DA 规范又是其中落地最广的一支而 OPCDAAuto.dll 就是当年随 OPC Foundation 分发的一套 COM 自动化封装把底层 COM 接口包成脚本友好的对象模型让 C# 这类托管语言能通过互操作直接读写 PLC 点位。这份资源就是围绕这个 DLL 展开的 C# 客户端实现核心解决的是「不依赖第三方商业库、不装庞大运行时用原生 C# 把 OPC DA 服务端的数据读出来、写回去」这件事。适合手里有老 OPC 服务器、需要快速搭一个轻量采集端或调试工具的工控开发者也适合想搞明白 COM 互操作在工业场景里到底怎么落地的 C# 程序员。它不是什么新潮方案但在存量设备改造里能省掉一大笔授权费和适配时间。2. 环境准备与 DLL 注册为什么 32 位是绕不过去的坎2.1 先搞清楚 OPCDAAuto.dll 的来路和位数OPCDAAuto.dll 是 OPC Foundation 早期提供的自动化包装器本质是一个 COM 组件内部再调用 OPC DA 的 COM 接口。它有两个关键属性必须先确认一是位数二是注册方式。绝大多数现场能拿到的版本是 32 位的因为当年 OPC 服务器和组态软件普遍跑在 32 位进程里。如果你的 C# 程序编译成 AnyCPU 并在 64 位系统上以 64 位进程运行调用这个 DLL 时会直接抛Class not registered或80040154错误这不是代码写错了是位数对不上。常见做法是在 Visual Studio 里把目标平台显式设为 x86而不是 AnyCPU。这一步不做后面所有代码都白搭。我见过太多人卡在这里以为是 DLL 没注册反复折腾注册表其实是进程位数的问题。提示先确认你拿到的 OPCDAAuto.dll 是 32 位还是 64 位。用 dumpbin /headers 看 machine 字段x86 对应 14Cx64 对应 8664。没有 dumpbin 就用 Dependency Walker 或 PowerShell 的[System.Reflection.AssemblyName]看不了COM DLL 得用工具查。2.2 注册 DLL 的正确姿势与权限坑COM 组件必须注册到系统才能被 C# 通过 ProgID 或 CLSID 创建。注册命令本身很简单但权限和路径是两大坑。# 以管理员身份打开命令提示符进入 DLL 所在目录 # 32 位 DLL 必须用 32 位的 regsvr32否则会报错 C:\Windows\SysWOW64\regsvr32.exe OPCDAAuto.dll # 如果成功会弹出对话框提示注册成功 # 如果报「模块已加载但找不到入口点」说明位数用错了逻辑说明SysWOW64目录下的 regsvr32 是 32 位版本专门用来注册 32 位 COM 组件System32下的 regsvr32 是 64 位版本。很多人习惯直接敲regsvr32在 64 位系统上默认调的是 64 位版本注册 32 位 DLL 就会失败。参数上没有任何多余选项就是 DLL 路径路径里有空格要加引号。注册成功后可以在注册表HKEY_CLASSES_ROOT\OPCDAAuto.Auto下看到对应的 CLSID。如果这个键不存在说明注册没成功后面 C# 里用Type.GetTypeFromProgID(OPCDAAuto.Auto)会返回 null。还有一个权限坑如果当前用户不是管理员regsvr32 会静默失败或提示权限不足。必须用管理员身份运行命令行。另外某些安全软件会拦截 COM 注册遇到莫名其妙的失败可以先临时关掉防护再试。2.3 C# 项目里引用 DLL 的两种方式注册完成后C# 项目里引用这个 COM 组件有两种常见做法。第一种是直接在 Visual Studio 里添加引用浏览到 OPCDAAuto.dllVS 会自动生成互操作程序集Interop.OPCDAAuto.dll。这种方式简单但生成的互操作程序集跟环境绑定换一台机器如果 DLL 版本不同可能出问题。第二种是用Type.GetTypeFromProgID动态创建不添加静态引用。这种方式更灵活适合需要部署到多台机器的场景。// 方式二动态创建 COM 对象不依赖静态引用 Type opcType Type.GetTypeFromProgID(OPCDAAuto.Auto); if (opcType null) { Console.WriteLine(OPCDAAuto.Auto 未注册请先注册 DLL); return; } dynamic opcServer Activator.CreateInstance(opcType); // 后续通过 dynamic 调用属性和方法逻辑说明Type.GetTypeFromProgID根据 ProgID 从注册表查找 CLSID返回 Type 对象。如果返回 null说明注册表里没有这个 ProgID要么 DLL 没注册要么注册到了错误的位数视图下。Activator.CreateInstance创建实例用 dynamic 是为了避免引入互操作程序集但代价是失去编译期类型检查方法名拼错要到运行时才发现。参数上ProgID 字符串必须和注册表里完全一致大小写不敏感但拼写不能错。常见的有OPCDAAuto.Auto有些版本可能是OPCDAAuto.OPCServer以实际注册表为准。3. 连接 OPC 服务器与遍历点位从 ProgID 到 ItemID 的完整链路3.1 连接服务器的核心参数与超时控制创建 OPC 服务器对象后第一步是连接目标 OPC 服务器。这里的关键参数是服务器的 ProgID比如某组态软件常见的Kepware.KEPServerEX.V6或Matrikon.OPC.Simulation具体取决于你现场装的是什么。连接方法通常叫Connect传入服务器 ProgID 字符串。dynamic opcServer Activator.CreateInstance(opcType); try { // 连接目标 OPC 服务器参数为服务器 ProgID opcServer.Connect(Matrikon.OPC.Simulation.1); Console.WriteLine(连接成功); } catch (Exception ex) { Console.WriteLine($连接失败: {ex.Message}); // 常见错误服务器未启动、ProgID 拼写错误、DCOM 配置不通 }逻辑说明Connect的参数是 OPC 服务器的 ProgID不是 OPCDAAuto 的 ProgID别搞混。如果服务器在远程机器上还需要配置 DCOM 权限这是另一个大坑后面避坑章节会展开。连接失败时异常信息里通常包含 HRESULT 码0x80040154是类未注册0x80070005是拒绝访问0x800706BA是 RPC 服务器不可用。超时控制方面OPCDAAuto 本身没有直接的超时参数连接超时取决于 DCOM 的底层设置。如果服务器没启动连接可能会卡很久才报错。常见做法是在调用 Connect 前先 ping 一下目标机器或者用异步方式包一层超时。3.2 遍历服务器地址空间拿到 ItemID连接成功后下一步是拿到你要读的点位标识也就是 ItemID。OPC DA 的地址空间是树形结构可以通过OPCBrowser对象逐层遍历。ItemID 的格式因服务器而异常见的有Channel1.Device1.Tag1这种点分格式也有S7:[S7 connection_1]DB1,INT0这种带驱动前缀的格式。// 创建浏览器对象遍历地址空间 dynamic browser opcServer.CreateBrowser(); browser.MoveToRoot(); // 显示根节点下的分支 object names; object itemIds; browser.GetBranchNames(out names, out itemIds); // names 和 itemIds 是 object 类型的数组需要转换 object[] branchNames (object[])names; foreach (var name in branchNames) { Console.WriteLine($分支: {name}); }逻辑说明CreateBrowser返回一个浏览器对象MoveToRoot回到根节点GetBranchNames获取当前节点下的所有分支名称和对应的 ItemID。注意输出参数是object类型实际是object[]数组需要强制转换。遍历时通常用递归或队列逐层深入直到找到叶子节点叶子节点的 ItemID 就是可以读写的点位标识。参数上GetBranchNames的两个输出参数分别返回分支的显示名和 ItemID显示名给人看ItemID 给程序用。有些服务器显示名和 ItemID 相同有些不同写代码时要用 ItemID 而不是显示名去读写。3.3 添加点位并读取数据拿到 ItemID 后通过OPCItems集合添加点位然后调用Read方法读取。OPCDAAuto 的读取是同步的返回一个OPCItem对象里面包含值、质量戳和时间戳。// 添加一个点位到组 dynamic items opcServer.OPCItems; dynamic item items.AddItem(Channel1.Device1.Tag1, 1); // 读取该点位 dynamic readResult item.Read(1); // 1 表示从设备读取2 表示从缓存读取 Console.WriteLine($值: {readResult.Value}, 质量: {readResult.Quality}, 时间: {readResult.TimeStamp});逻辑说明AddItem的第一个参数是 ItemID第二个参数是客户端句柄随便给一个唯一整数即可。Read的参数是数据源1 表示从设备读慢但实时2 表示从缓存读快但可能滞后。返回值是一个对象包含 Value、Quality、TimeStamp 三个核心属性。Quality 是质量戳192 表示 Good其他值表示坏值或不确定具体含义查 OPC 质量码表。参数上AddItem的 ItemID 必须和服务器地址空间里完全一致大小写敏感。如果 ItemID 不存在AddItem 可能返回 null 或抛异常。读取时如果服务器没连上设备Quality 会返回坏值Value 可能是 0 或上一次的缓存值不能只看 Value 不看 Quality。4. 写入数据与订阅回调同步写和异步订阅的取舍4.1 同步写入的步骤与返回值校验写入比读取多一步校验。OPCDAAuto 的写入方法通常叫Write传入值和目标 ItemID返回一个 HRESULT 或布尔值表示成功与否。// 写入一个值到指定点位 dynamic writeItem items.AddItem(Channel1.Device1.Tag1, 2); try { writeItem.Write(123.45); Console.WriteLine(写入成功); } catch (Exception ex) { Console.WriteLine($写入失败: {ex.Message}); }逻辑说明Write的参数是要写入的值类型要和服务器期望的类型匹配。如果服务器期望的是整数你传浮点数可能被截断或报类型错误。写入失败时异常信息里通常有 HRESULT0x80070005是权限不足0xC0040004是值超出范围。参数上写入的值类型建议先用Read读一次看返回的 Value 是什么类型再按同样类型写。不要凭猜测传类型这是血泪经验。另外写入操作是同步阻塞的如果服务器响应慢界面会卡住建议放在后台线程里做。4.2 订阅回调的实现与注意事项轮询读取适合少量点位点位多了就要用订阅。OPCDAAuto 支持IOPCDataCallback接口通过Advise建立订阅服务器在数据变化时主动回调。// 定义一个回调类实现 IOPCDataCallback 接口 // 注意OPCDAAuto 的订阅通常通过 OPCGroup 对象实现 dynamic group opcServer.OPCGroups.Add(MyGroup); group.UpdateRate 1000; // 更新周期 1 秒 group.IsActive true; // 添加点位到组 group.OPCItems.AddItem(Channel1.Device1.Tag1, 1); // 订阅回调需要实现接口这里用简化的动态方式示意 // 实际项目中需要定义一个类实现 IOPCDataCallback逻辑说明订阅的核心是UpdateRate和IsActive。UpdateRate是服务器检查数据变化的周期单位毫秒设太小会增加服务器负担设太大实时性不够。IsActive控制组是否激活不激活的组不产生回调。回调接口IOPCDataCallback有OnDataChange、OnReadComplete、OnWriteComplete等方法需要在 C# 里定义一个类实现这些方法然后通过Advise注册。参数上UpdateRate的实际生效值取决于服务器的最小刷新周期你设 100 毫秒服务器可能只支持 500 毫秒实际以服务器返回的为准。回调是在 COM 的线程池线程上执行的不能直接更新 UI 控件需要Invoke到 UI 线程。4.3 同步读和订阅的选型对比对比项同步轮询读取订阅回调实时性取决于轮询周期通常较慢服务器主动推送较快服务器压力每次读取都产生请求只在数据变化时回调实现复杂度简单直接调用 Read需实现回调接口处理线程适用场景少量点位、调试、低频采集大量点位、实时监控断线恢复容易控制重连后重新读需重新建立订阅选型建议点位少于 50 个且对实时性要求不高用同步轮询就够了代码简单好维护。点位多或要求秒级以内响应用订阅。但订阅的坑在于回调线程和 UI 线程的交互以及断线后订阅失效需要重建这些在避坑章节细说。5. 避坑与排查那些让我加班到凌晨的 OPC 连接问题5.1 现象Connect 报 0x80040154类未注册原因OPCDAAuto.dll 没有注册或者注册到了错误的位数视图下。32 位 DLL 用 64 位 regsvr32 注册注册表里写到了 64 位视图32 位程序读不到。解决确认 DLL 位数用对应位数的 regsvr32 重新注册。32 位 DLL 用C:\Windows\SysWOW64\regsvr32.exe64 位 DLL 用C:\Windows\System32\regsvr32.exe。注册后在注册表对应视图下确认 ProgID 存在。5.2 现象远程连接报 0x80070005拒绝访问原因DCOM 权限没配好。OPC DA 依赖 DCOM 通信远程访问需要在服务器和客户端两侧都配置 DCOM 身份验证级别和访问权限。解决在服务器端运行dcomcnfg找到 OPC 服务器对应的 COM 组件设置身份验证级别为「无」访问权限和启动权限里加入客户端机器上的用户账号。客户端侧同样配置。这一步因系统版本差异较大常见做法是先用本地连接验证代码没问题再逐步放开远程权限。5.3 现象Read 返回的 Quality 一直是坏值原因ItemID 拼写错误、服务器没连上设备、或者读取的数据源选错了。ItemID 大小写敏感差一个字符就找不到。服务器没连上 PLC 时所有点位质量都是坏值。解决先用 OPC 客户端工具如 Matrikon OPC Explorer连上服务器确认 ItemID 和实时值正常再把同样的 ItemID 抄到代码里。读取时先用数据源 2缓存读如果缓存有值但设备读没有说明服务器到设备的链路有问题。5.4 现象订阅回调不触发或触发一次就停原因组没有激活、UpdateRate 设得太小被服务器忽略、或者回调对象被 GC 回收了。C# 里 COM 回调对象如果没有保持强引用垃圾回收可能把它收走回调就断了。解决确认IsActive为 trueUpdateRate设一个服务器支持的合理值。回调对象用静态变量或成员变量持有不要用局部变量。另外回调线程里不要做耗时操作否则会阻塞后续回调。5.5 现象程序运行一段时间后内存持续增长原因COM 对象没有释放。OPCDAAuto 创建的每个 COM 对象都占用非托管资源C# 的 GC 不会自动释放 COM 对象需要显式调用Marshal.ReleaseComObject或Marshal.FinalReleaseComObject。解决对每个创建的 COM 对象在不再使用时调用Marshal.FinalReleaseComObject并置为 null。尤其是循环里反复创建的对象不释放会快速累积。常见做法是用 try-finally 包住确保异常时也能释放。6. 进阶技巧用 C# 封装一个可复用的 OPC 采集类把前面的代码整理成一个可复用的类是实际项目里迟早要做的事。我一般会封装一个OpcDaClient类把连接、读、写、订阅、释放都包进去对外暴露简单的方法。下面是一个精简版的骨架重点看释放逻辑和异常处理。public class OpcDaClient : IDisposable { private dynamic _server; private dynamic _items; private bool _disposed false; public bool Connect(string progId) { try { Type t Type.GetTypeFromProgID(OPCDAAuto.Auto); _server Activator.CreateInstance(t); _server.Connect(progId); _items _server.OPCItems; return true; } catch (Exception ex) { Console.WriteLine($连接失败: {ex.Message}); return false; } } public object ReadItem(string itemId) { dynamic item _items.AddItem(itemId, 1); dynamic result item.Read(2); // 从缓存读 Marshal.FinalReleaseComObject(item); return result.Value; } public void Dispose() { if (_disposed) return; if (_server ! null) { try { _server.Disconnect(); } catch { } Marshal.FinalReleaseComObject(_server); _server null; } _disposed true; } }逻辑说明Connect里把创建服务器和获取 Items 集合封装在一起失败返回 false 而不是抛异常方便调用方处理。ReadItem每次创建 item 后立即释放避免累积。Dispose里先断开连接再释放 COM 对象用 try-catch 包住 Disconnect 是因为断开时可能抛异常但不影响释放。参数上ReadItem的数据源我默认用 2缓存因为大多数监控场景对实时性要求没那么苛刻缓存读更快。如果确实需要实时值改成 1 即可。AddItem的客户端句柄这里固定用 1因为每次都是新建 item 再释放不存在句柄冲突。验证封装是否可靠我一般会写一个简单的测试连接模拟服务器读一个已知点位写一个值再读回来对比然后连续跑 1000 次读写看内存是否稳定。如果内存曲线平稳说明释放逻辑没问题如果持续上涨就是哪里漏了FinalReleaseComObject。从那以后我每次封装 COM 组件都强制在 Dispose 里走一遍释放流程并且在循环里创建的对象绝不等到 GC 去收。这个习惯帮我省掉了好几次半夜被叫起来查内存泄漏的麻烦。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

嵌入式开发新平台评估:STM32C5与CubeMX2的迁移实践与思考

嵌入式开发新平台评估:STM32C5与CubeMX2的迁移实践与思考

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

2026/10/11 2:59:19 阅读更多 →
MySQL批量更新性能优化:逐条UPDATE与CASE WHEN的取舍

MySQL批量更新性能优化:逐条UPDATE与CASE WHEN的取舍

我接手过的系统里,凡是运营后台带“批量”两个字的功能,十有八九最后都要落到数据库的批量 UPDATE 上。比如刚才还在群里有人问:勾选了几百个商品要改价格,一条条 UPDATE 太慢了,有没有办法一条 SQL 全改完&#xff1f…

2026/10/11 2:59:19 阅读更多 →
2026最新6款AI编程软件基础版免费深度对比

2026最新6款AI编程软件基础版免费深度对比

我所在的五人创业团队最近接了个车联网数据平台的单子——接口多、数据量大、工期紧。以前人手充足时,技术选型可以慢慢试,现在每分钱都得花在刀刃上。花了两个周末,我把主流的几款AI编程工具挨个装了一遍,同一个项目用不同的工具…

2026/10/11 2:59:19 阅读更多 →

最新新闻

Java面试翻车现场:HashMap、线程池、JVM深度拆解

Java面试翻车现场:HashMap、线程池、JVM深度拆解

“严肃面试官 vs 搞笑水货程序员谢飞机(本名王大瓜)——互联网大厂 Java 面试实录与技术拆解”,光看这个标题你可能觉得是个段子,但我在现场的感觉是:这简直就是一场喜剧外壳下的技术解剖课。谢飞机,简历上…

2026/10/11 3:58:54 阅读更多 →
RT-Thread—STM32—环境搭建

RT-Thread—STM32—环境搭建

RT-Thread——STM32——环境搭建 概述 本教程主要根据官方推荐的教程进行环境搭建,但是在打包方面按照自己的习惯进行了打包。 RT-Thread官网有特别详细的教程,这儿就不详细说明RT-Thread官网 软件准备 MDK528a (Keil5)CubeMx_v5-2-0STM32CubeMx的支持…

2026/10/11 3:58:54 阅读更多 →
智能工厂建设方案全解析:从ISA-95架构到MES/SCADA系统选型

智能工厂建设方案全解析:从ISA-95架构到MES/SCADA系统选型

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

2026/10/11 3:58:54 阅读更多 →
JavaScript核心考点索引:从原型链到事件循环的面试体系

JavaScript核心考点索引:从原型链到事件循环的面试体系

做前端面试辅导这几年,我收到最多的问题不是“这道题答案是什么”,而是“面对这么多考点,到底哪些才值得深学”。JavaScript知识体系太庞杂了,从语言基础到浏览器原理,从手写代码到性能优化,随便拉一个列表…

2026/10/11 3:58:53 阅读更多 →
第1章,[Win32 章节]:编程环境与 MSDN

第1章,[Win32 章节]:编程环境与 MSDN

专栏导航 上一篇:第1章,[Win32 章节]:编程语言与框架选择 回到目录 下一篇:第1章 :第一个 Win32 程序,头文件 本专栏课件 关于本专栏课件的获取方法,请参考下述课节。 参考课节&#xff1a…

2026/10/11 3:58:53 阅读更多 →
开源吐槽大会:开发者从项目吐槽中学到的避坑与成长之道

开源吐槽大会:开发者从项目吐槽中学到的避坑与成长之道

1. 这个标题是怎么“火”起来的:开源吐槽大会的由来与定位如果你混迹开发者社区有一阵子,大概率见过这类帖子:“某某开源项目到底能不能用”“维护者又跑路了”“README吹得天花乱坠,一跑就崩”。这些帖子往往评论区最热闹&#x…

2026/10/11 3:57:53 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

2026/10/11 0:00:27 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 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/10 5:23:50 阅读更多 →
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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/10 10:38:42 阅读更多 →