SUMO TraCI函数调用深度解析:从轮询到订阅的性能优化实战
1. 从一次仿真卡死说起为什么必须吃透TraCI的函数调用去年帮一个做交通流优化的朋友排查问题他的SUMO仿真跑到第300秒左右就彻底卡住日志里没有任何报错CPU占用率也正常但仿真就是不再推进。我让他把TraCI的调用日志打出来翻了不到二十行就找到了病根——他在每个仿真步里都调了一次traci.vehicle.getIDList()然后对返回的每一辆车依次调用traci.vehicle.getPosition()和traci.vehicle.getSpeed()车辆数在高峰期突破了8000辆单步的通信往返次数直接飙到两万多次。TraCI是基于Socket的同步通信协议每一次函数调用都是一次请求-响应往返这个量级的调用频率把通信开销推到了不可接受的地步。这件事让我意识到很多人用SUMO做仿真Python脚本写得挺溜但对TraCI这层接口的内部机制和函数设计逻辑其实是一知半解的。知道怎么调但不知道为什么这样调更不知道什么情况下不该这样调。这篇内容就围绕TraCI中那些高频使用的函数把它们的底层逻辑、参数含义、返回值结构、性能特征和常见坑点逐一拆开讲清楚。不管你是刚接触SUMO仿真的新手还是已经写过几个项目但总觉得脚本跑得不够快的老手应该都能从中找到一些之前忽略的细节。SUMO本身是一个微观交通仿真器车辆、信号灯、车道、路口这些实体都在仿真内核里维护状态。TraCITraffic Control Interface本质上是一套客户端-服务端协议SUMO作为服务端在某个端口上监听你的Python脚本作为客户端通过TCP连接过去用一套约定好的命令格式来查询状态或下发指令。Python侧的traci模块把这套协议封装成了看起来像本地函数调用的形式但底层每一次调用都涉及序列化、网络传输、反序列化这几个步骤。理解这一点是理解后面所有性能问题和设计取舍的前提。2. 车辆模块的核心查询函数返回值里藏着什么2.1 getIDList与车辆过滤的时机选择traci.vehicle.getIDList()返回当前仿真中所有车辆ID的列表看起来简单但用起来有几个容易踩的坑。第一这个列表的顺序是不确定的SUMO内部用哈希表管理车辆不同版本、不同仿真步返回的顺序可能不一样。如果你的逻辑依赖车辆顺序比如按顺序分配车道一定要自己排序或者用其他方式建立索引。第二这个函数返回的是当前仿真步所有活跃车辆的ID包括那些已经到达目的地但还没被移除的车辆。在某些配置下车辆到达后会有一个短暂的滞留期这时候getIDList()仍然会返回它但getPosition()可能返回一个无效值或者最后一帧的位置。如果你在做统计分析最好配合traci.vehicle.getArrivalTime()或者订阅机制来判断车辆是否真正完成了行程。第三性能问题。前面提到的那个案例就是典型getIDList()本身开销不大但它是很多其他操作的前置步骤。如果你在每个仿真步都要遍历所有车辆做统计更好的做法是用TraCI的订阅机制traci.vehicle.subscribe()一次性订阅你关心的变量SUMO会在每个仿真步主动推送数据而不是你反复去拉取。订阅机制和轮询机制的差异在车辆数超过2000辆之后会变得非常明显。2.2 getPosition与坐标系的那些事traci.vehicle.getPosition(vehID)返回一个(x, y)元组单位是米。这个坐标是基于SUMO路网文件的坐标系默认情况下原点在路网的最左下角附近但具体位置取决于你的net.xml文件是怎么生成的。如果你用netconvert从OpenStreetMap数据转换路网坐标系可能是经纬度投影后的结果x和y的数值范围会很大。这里有一个实际项目中经常遇到的问题你想把SUMO的仿真结果可视化到地图上但发现车辆位置和地图对不上。原因通常是坐标系没有对齐。SUMO支持在路网文件中通过location标签定义坐标转换参数包括偏移量和缩放因子。如果你需要和GIS数据对齐必须在生成路网时就把这些参数配置好而不是在TraCI脚本里做后处理。另外getPosition()返回的是车辆参考点的位置通常是车辆前保险杠的中点。如果你需要车辆中心或者后轴的位置需要用getPosition3D()配合车辆长度参数自己计算或者用traci.vehicle.getDistance()结合路网几何来推算。2.3 getSpeed与速度获取的精度陷阱traci.vehicle.getSpeed(vehID)返回车辆当前速度单位是米每秒。这个值来自SUMO的车辆跟驰模型输出精度取决于你设置的仿真步长。步长越大速度更新的粒度越粗。默认步长是1秒如果你做的是微观行为分析建议把步长调到0.1秒甚至更小否则速度曲线会呈现明显的阶梯状。还有一个容易被忽略的点getSpeed()返回的是标量速度不带方向。如果你需要速度矢量得用getSpeed()配合getAngle()来构造。getAngle()返回车辆朝向的角度正北为0度顺时针增加。这两个函数配合使用的时候要注意角度是车辆纵轴的方向不是速度方向。在车辆倒车或者侧滑的情况下虽然SUMO默认模型不太会出现侧滑两者会有差异。2.4 getRoadID与车道级定位traci.vehicle.getRoadID(vehID)返回车辆当前所在的道路ID字符串。如果车辆在路口内部也就是不在任何一条具体的道路上返回值会是一个以冒号开头的特殊字符串比如:junction_5。这个细节在做路径分析的时候很关键因为路口内部的车辆不属于任何一条边如果你直接用道路ID做统计这些车辆会被漏掉。和它配套的是traci.vehicle.getLaneID(vehID)返回的是车道ID格式通常是道路ID_车道索引比如edge_12_0表示edge_12的第0条车道最右侧。车道索引从0开始从右往左递增。这个索引顺序和很多人的直觉相反我第一次用的时候也搞混过。3. 信号灯与路口控制从查询到干预3.1 getPhase与相位查询的时序问题traci.trafficlight.getPhase(tlsID)返回当前信号灯的相位索引是一个整数。这个索引对应你在这个信号灯的逻辑文件也就是additional文件里定义的tlLogic中相位的排列顺序。看起来很简单但有一个时序上的坑TraCI返回的相位是上一个仿真步结束时的状态而不是当前时刻的瞬时状态。如果你在仿真步的中间查询得到的可能是即将过期的值。更稳妥的做法是用traci.trafficlight.getRedYellowGreenState(tlsID)它返回一个字符串每个字符对应一个受控车道连接的状态G表示绿灯g表示保护性绿灯y表示黄灯r表示红灯。这个字符串是当前时刻的准确状态不受相位切换时序的影响。3.2 setPhase与setProgram的配合使用traci.trafficlight.setPhase(tlsID, phaseIndex)用来强制切换信号灯相位。这个函数在自适应信号控制中很常用但直接调用它有几个注意事项。第一切换是立即生效的不会等待当前相位的最小绿灯时间结束。如果你在做一个需要保证最小绿灯时间的控制策略必须自己在脚本里维护计时器判断当前相位已经持续了多久再决定是否切换。第二setPhase()只对当前激活的信号灯方案program有效。如果你的信号灯有多个方案需要先用traci.trafficlight.setProgram(tlsID, programID)切换到你想要的方案再调用setPhase()。这两个函数的调用顺序不能反否则setPhase()可能作用在你不想控制的那个方案上。第三切换相位后信号灯的周期计时会重置。如果你在做周期级的统计分析这个重置会影响你的数据。建议在切换前后记录时间戳自己维护一套独立的周期计数。3.3 信号灯订阅与批量查询和车辆模块类似信号灯也支持订阅机制。traci.trafficlight.subscribe(tlsID, varIDs)可以订阅你关心的变量比如当前相位、下一个切换时间、当前状态字符串等。在一个有几百个信号灯的路网里轮询所有信号灯的状态开销很大订阅机制可以把这部分开销降到最低。订阅的变量ID在traci.constants模块里有定义比如VAR_PHASE、VAR_NEXT_SWITCH、VAR_RED_YELLOW_GREEN_STATE等。订阅之后在每个仿真步调用traci.simulationStep()之后用traci.trafficlight.getAllSubscriptionResults()一次性获取所有订阅信号灯的最新数据。这个字典的结构是{tlsID: {varID: value}}遍历起来很方便。4. 仿真控制与步进时间管理的核心逻辑4.1 simulationStep的阻塞与非阻塞行为traci.simulationStep()是TraCI脚本里最核心的函数它告诉SUMO推进一个仿真步。这个函数是阻塞的也就是说它会等待SUMO完成当前步的所有计算把结果返回给客户端之后才继续执行下一行代码。这个阻塞特性保证了你在调用simulationStep()之后查询到的所有状态都是同一个仿真步的不会出现数据不一致的问题。但阻塞也意味着你的脚本执行速度和SUMO的仿真速度是串行的。如果你的脚本里有耗时的计算比如复杂的路径规划或者机器学习推理SUMO会一直等着你算完才推进下一步。在做实时仿真或者硬件在环测试的时候这个问题尤其突出。解决方案是把耗时计算放到单独的线程或者进程中用队列和主仿真循环通信。4.2 getTime与getCurrentTime的区别traci.simulation.getTime()返回当前仿真时间单位是秒是一个浮点数。这个值等于已经执行的仿真步数乘以步长。traci.simulation.getCurrentTime()返回的是毫秒为单位的整数两者本质上是同一个值只是单位不同。这里有一个精度问题如果你的步长是0.1秒仿真跑了10000步getTime()返回1000.0看起来没问题。但如果步长是0.3秒浮点累加误差会逐渐显现到后面getTime()返回的值可能和步数 × 0.3有微小偏差。如果你需要精确的时间对齐建议用步数来推算时间而不是直接依赖getTime()的返回值。4.3 仿真结束条件的判断traci.simulation.getMinExpectedNumber()返回的是仿真中剩余车辆数的下界估计。当这个值降到0的时候说明所有车辆都已经到达目的地或者被移除了仿真可以安全结束。这个函数比直接判断getIDList()是否为空更可靠因为它考虑了正在进入路网但还没出现的车辆。另一个常用的结束条件是仿真时间达到预设值。这时候你需要在循环里判断traci.simulation.getTime() endTime然后调用traci.close()关闭连接。注意traci.close()之后不能再调用任何TraCI函数否则会抛出异常。如果你需要在关闭后保存数据确保所有数据都已经在关闭前取出来了。5. 路网与车道查询被低估的高频操作5.1 lane.getShape与几何信息获取traci.lane.getShape(laneID)返回车道的几何形状是一个由(x, y)坐标点组成的列表。这个函数在路径可视化和车道级地图匹配中很有用但它的返回值可能非常长。一条几百米长的车道如果路网生成时没有做简化可能有上百个坐标点。如果你只需要车道的起终点用traci.lane.getShape()然后取首尾两个点就够了不需要遍历整个列表。更高效的做法是用traci.lane.getLength(laneID)获取车道长度用traci.lane.getLinks(laneID)获取车道的连接关系。getLinks()返回的是一个列表每个元素包含下游车道ID、通过方向、以及是否有信号灯控制等信息。这个函数在做路网拓扑分析的时候非常关键但文档里对返回值的结构描述得不太清楚我第一次用的时候花了不少时间才搞明白每个字段的含义。5.2 edge.getTraveltime与路段行程时间traci.edge.getTraveltime(edgeID)返回路段上的平均行程时间单位是秒。这个值是基于路段上所有车辆的实际行驶时间计算的但有一个重要的前提只有当路段上有车辆完成通行后这个值才会被更新。如果路段上一直没有车辆返回值可能是默认值或者上一次的旧值。在做路网性能评估的时候这个函数很有用但要注意它的统计窗口。SUMO默认使用一个滑动窗口来计算平均行程时间窗口大小可以在仿真配置里调整。如果你需要更精确的行程时间统计建议自己用车辆级的轨迹数据来计算而不是依赖这个聚合值。5.3 junction与connection的查询traci.junction.getPosition(junctionID)返回路口中心点的坐标。traci.junction.getShape(junctionID)返回路口的几何形状。这两个函数在做路口冲突分析的时候会用到。连接connection层面的查询用traci.connection.getIDList()获取所有连接的ID然后用traci.connection.getFromLane()、traci.connection.getToLane()等函数查询具体信息。连接是SUMO里比较底层的概念表示从一条车道到另一条车道的通行关系。在做信号灯配时优化的时候理解连接和相位的关系是基础中的基础。6. 性能优化实战从轮询到订阅的迁移路径6.1 轮询模式的性能瓶颈在哪里前面提到的那个案例问题根源是轮询模式下的通信开销。每一次traci.vehicle.getPosition()调用底层都是一次完整的TCP请求-响应。请求需要序列化函数名和参数响应需要反序列化返回值。在本地回环网络上单次往返大约0.1到0.5毫秒看起来不多但乘以两万次就是2到10秒。如果SUMO的仿真步长是1秒仿真推进300步只需要300秒的仿真时间但实际墙钟时间可能因为通信开销翻倍甚至更多。更严重的是频繁的通信会导致SUMO的仿真内核和TraCI服务端之间频繁切换上下文CPU缓存命中率下降进一步拖慢速度。在车辆数超过5000辆的场景下轮询模式的脚本几乎不可能做到实时仿真。6.2 订阅机制的实现细节订阅机制的核心思想是变拉为推。你在仿真开始前告诉SUMO你关心哪些变量SUMO在每个仿真步结束后主动把这些变量的值打包发给你。这样通信次数从“车辆数 × 变量数 × 步数”降到了“步数”开销降低了几个数量级。具体实现上用traci.vehicle.subscribe(vehID, varIDs)订阅单辆车或者用traci.vehicle.subscribeLeader()订阅跟驰关系。订阅之后在每个simulationStep()之后调用traci.vehicle.getAllSubscriptionResults()获取所有订阅车辆的数据。返回的字典结构是{vehID: {varID: value}}你可以按需提取。订阅的变量ID需要从traci.constants里取常用的有VAR_POSITION、VAR_SPEED、VAR_ANGLE、VAR_ROAD_ID、VAR_LANE_ID等。注意不是所有变量都支持订阅具体支持列表可以查SUMO的官方文档。订阅的变量越多每个仿真步传输的数据量越大但通信次数不变。所以订阅也不是越多越好只订阅你真正需要的变量。6.3 批量查询与缓存策略有些场景下订阅机制不太适用比如你需要在仿真过程中动态决定查询哪些车辆。这时候可以用批量查询来减少通信次数。traci.vehicle.getIDList()返回所有车辆ID后你可以用traci.vehicle.getPosition()逐个查询但更好的做法是用traci.vehicle.getPosition()的批量版本如果SUMO版本支持或者用traci.vehicle.getAllSubscriptionResults()配合动态订阅。缓存策略也很重要。如果你在同一个仿真步内多次查询同一辆车的同一个变量第一次查询后把结果缓存起来后续直接读缓存避免重复通信。这个简单的优化在复杂脚本里能省下不少时间。7. 那些文档里不会写的踩坑记录7.1 车辆ID的生命周期管理SUMO里的车辆ID在车辆离开路网后会被回收新的车辆可能会复用旧的ID。如果你在脚本里用字典维护车辆状态车辆离开后一定要及时清理对应的条目否则新车辆出现时你会读到旧数据。判断车辆是否离开可以用traci.simulation.getArrivedIDList()它返回上一个仿真步内到达目的地的车辆ID列表。7.2 浮点数比较的精度问题TraCI返回的浮点数在序列化和反序列化过程中会有精度损失。如果你用来比较两个浮点数是否相等很可能会失败。正确的做法是判断差值是否小于一个阈值比如abs(a - b) 1e-6。这个问题在判断车辆是否到达某个位置、速度是否为零等场景下经常遇到。7.3 多线程环境下的TraCI连接TraCI的Python客户端不是线程安全的。如果你在多个线程里同时调用TraCI函数可能会出现数据错乱或者连接断开。如果确实需要多线程建议把TraCI调用集中在一个线程里其他线程通过队列和这个线程通信。或者用多进程每个进程维护自己的TraCI连接但要注意SUMO实例的资源开销。7.4 仿真步长与函数调用频率的匹配不是每个仿真步都需要查询所有变量。如果你的控制策略是秒级的而仿真步长是0.1秒你不需要在每个步都做决策。可以每10个步执行一次控制逻辑中间步只做数据记录。这样能显著降低脚本的计算负担同时不影响控制效果。8. 从函数调用到仿真思维一些个人体会用了几年SUMO和TraCI之后我最大的体会是不要把它当成一个普通的Python库来用。TraCI的函数调用背后是一个完整的微观交通仿真引擎每个函数的行为都受到仿真模型、路网配置、车辆类型参数等多重因素的影响。同一个函数在不同的仿真场景下可能表现出完全不同的特征。举个例子traci.vehicle.getSpeed()在自由流状态下返回的就是车辆的实际速度但在拥堵状态下由于跟驰模型的作用速度变化会非常剧烈相邻两个仿真步的速度差可能很大。如果你用这个速度去做数值积分来估算位置误差会累积得很快。更好的做法是直接用getPosition()来获取位置而不是用速度去推算。另一个体会是TraCI的函数设计其实反映了SUMO仿真内核的数据组织方式。理解了车辆、车道、路口、连接这些实体之间的关系就能更自然地理解为什么有些函数需要传额外的参数为什么有些返回值是嵌套结构。这种理解不是看文档能看出来的需要在实际项目中反复调试和验证。最后说一个实用的小技巧在开发阶段把TraCI的调用日志打开看看每个仿真步实际发生了多少次通信、传输了多少数据。SUMO的TraCI接口支持设置日志级别把日志写到文件里用脚本分析一下调用频率和耗时分布。这个习惯帮我定位过好几次性能问题比盲目猜测有效得多。

相关新闻

LLM_端到端自动驾驶

LLM_端到端自动驾驶

EAI:Embodied Artificial Intelligent,E2E:End to End,LLM:Large Language Mode 端到端自动驾驶专题:多模态输入融合、开源框架、头部企业与性能对比核心定义:端到端自动驾驶分为两类 纯端到端&…

2026/10/14 2:36:26 阅读更多 →
小模型干活,大模型出主意:Anthropic 新 API 让成本降 12%、性能反升 2.7%

小模型干活,大模型出主意:Anthropic 新 API 让成本降 12%、性能反升 2.7%

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

2026/10/14 2:36:26 阅读更多 →
【单片机毕设案例分享】基于STM32的智能婴儿床环境监测与摄像头云端监护装置设计 基于物联网的婴儿监护环境调节与阿里云联动控制系统设计(032708)

【单片机毕设案例分享】基于STM32的智能婴儿床环境监测与摄像头云端监护装置设计 基于物联网的婴儿监护环境调节与阿里云联动控制系统设计(032708)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于单片机,STM32单片机,51单片机,J…

2026/10/14 2:36:26 阅读更多 →

最新新闻

Virglrenderer 虚拟化技术深入解析 · 专栏目录

Virglrenderer 虚拟化技术深入解析 · 专栏目录

一套面向工程师的 virglrenderer 源码级技术专栏。从概述与演进讲起,再深入核心抽象、各后端实现、部署集成与工程实践。所有内容以仓库源码为准。 这里讲一下我为什么关注 virglrenderer,因为国产 GPU 的虚拟化需求。 随着国产化替代的推进&#xff0c…

2026/10/14 3:23:34 阅读更多 →
Kestrel_VLLM_CUDA - 04 · 分组量化 GEMM 内核

Kestrel_VLLM_CUDA - 04 · 分组量化 GEMM 内核

04 分组量化 GEMM 内核 一句话:一个内核同时服务 decode(M1)与 prefill(M32),用「每线程固定几列、沿 K 扫」的映射让权重按 warp 满事务读、激活广播;用 z-split 把小 M 的欠填充网格补满&…

2026/10/14 3:23:34 阅读更多 →
Spring Boot 单元测试怎么写?物联网平台 MockMvc 接口测试与 Mockito 消息链路测试实战(附 JaCoCo 覆盖率报告)

Spring Boot 单元测试怎么写?物联网平台 MockMvc 接口测试与 Mockito 消息链路测试实战(附 JaCoCo 覆盖率报告)

真实运行截图:一、功能都写完了,为什么还要写测试? 我这个物联网设备接入平台(Spring Boot 3.5 EMQX MySQL),从设备注册、MQTT 接入、消息入库到密钥轮换,功能主线已经跑通了。但每次面试话题…

2026/10/14 3:23:34 阅读更多 →
宁波执业律师张娟:配偶背的债你要还吗——夫妻共同债务认定规则拆解

宁波执业律师张娟:配偶背的债你要还吗——夫妻共同债务认定规则拆解

结论先行:配偶单方所负的债务,并不天然由你连带承担。民法典第1064条确立了共债共签原则——共同签字或事后追认、为家庭日常生活需要所负的债务才是共同债务;超出日常生活需要的,原则上由举债方自担,除非债权人能证明…

2026/10/14 3:23:34 阅读更多 →
铝制小青瓦筑就江南院墅 复刻黛瓦白墙的东方栖居

铝制小青瓦筑就江南院墅 复刻黛瓦白墙的东方栖居

坐落于苏州的拙政江南,以拙政园为文脉基底,打造连片式低密新中式院墅群落。白墙围合私家庭院,黛瓦错落铺陈屋面,亭廊婉转、叠石理水,将苏州园林的雅致意境藏进每一方栖居空间。项目全线屋面采用铝制小青瓦,以现代建材工艺复刻传统江南小青瓦的形与韵,更从根源破解传统陶瓦的运维…

2026/10/14 3:23:34 阅读更多 →
中国起名服务正在发生什么变化?从“大师经验”到专业化、品牌化服务

中国起名服务正在发生什么变化?从“大师经验”到专业化、品牌化服务

很长时间里,人们对于“找人起名”的想象都非常简单: 找一位有经验的老师, 报出生时间, 老师根据经验给出几个名字。 整个服务高度依赖: “这个大师厉不厉害”。 但今天再观察国内专业起名市场,会发现它已经…

2026/10/14 3:22:34 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →