Tectonic 的 mac_core 解析:如何在 Rust 中安全地暴露 macOS CoreFoundation 与 CoreText 框架
CLI【免费下载链接】tectonicA modernized, complete, self-contained TeX/LaTeX engine, powered by XeTeX and TeXLive.项目地址https://gitcode.com/gh_mirrors/te/tectonic点击查看免费下载在 Tectonic 这个自包含的 XeTeX/TeXLive 排版引擎中跨平台字体解析是一个核心难题在 Linux/Windows 上依靠 Fontconfig而在 macOS 上则必须直接调用系统的 CoreFoundation 与 CoreText 框架。tectonic_mac_core就是承担这一职责的 crate——它通过一层经过精心设计的安全封装把 macOS 系统的框架 API 暴露给 Rust 代码使上层引擎代码可以像操作普通 Rust 值一样操作系统字体对象。读完本篇你将理解这个 crate 的 FFI 分层结构、基于引用计数的内存安全模型、动态类型识别机制以及它如何被xetex_layout字体后端实际调用。一、crate 定位把 macOS 框架以安全方式交给 Rustcrates/mac_core/README.md 对 crate 的定位一句话概括This crate is part of the Tectonic project. It exposes macOS frameworks into Rust code in a safe manner.它的直接目标是 CoreFoundationFoundation与 CoreText 两个框架——这正是 Tectonic 在 macOS 上解析字体所需的库这一点在 crates/mac_core/src/lib.rs 的模块文档中得到确认//! Bindings to macOS foundation and core libraries. //! //! This currently includes only Foundation and CoreText, as those are the libraries needed by //! Tectonic.从依赖结构看见 crates/mac_core/Cargo.toml该 crate 运行时仅依赖libc构建期仅依赖工作区内部的tectonic_cfg_support没有任何重型外部绑定库——所有 FFI 绑定都是手写维护的这正是安全封装必须自己承担全部安全责任的原因。二、平台门禁与框架链接非 macOS 上的空 crate整个 crate 的根模块带有一行编译门禁#![cfg(target_os macos)]这意味着在 Linux、Windows 等平台上编译时tectonic_mac_core等价于一个空 crate——上游 crate 引用它时不会产生任何符号或链接负担跨平台编译得以自然成立。真正重的工作在构建脚本 crates/mac_core/build.rs 中完成。脚本通过tectonic_cfg_support::target_cfg!判断目标平台仅在 macOS 上输出框架链接指令fn main() { let is_mac_os target_cfg!(target_os macos); if is_mac_os { println!(cargo:rustc-link-libframeworkFoundation); println!(cargo:rustc-link-libframeworkCoreFoundation); println!(cargo:rustc-link-libframeworkCoreGraphics); println!(cargo:rustc-link-libframeworkCoreText); println!(cargo:rustc-link-libframeworkAppKit); } }需要注意一个细节构建脚本链接了 Foundation/CoreGraphics/AppKit 等框架而 FFI 声明本身只显式#[link]了 CoreFoundation 和 CoreText见下文sys.rs这说明链接集是为框架符号的完整解析而准备的绑定面则刻意收缩到 Tectonic 真正用到的 API。三、FFI 底层sys模块中的 opaque 类型与 extern 声明crates/mac_core/src/sys.rs 是整个 crate 唯一直接触碰 C ABI 的模块。它的模式非常清晰所有系统类型都用#[repr(C)]的 opaque 结构体表示内部字段写为()即 Rust 侧永远不知道其布局#[repr(C)] pub struct CFDictionary(()); #[repr(C)] pub struct CTFont(()); #[repr(C)] pub struct CFString(());指针类型别名把mut语义排除在 API 之外——所有*Ref都是*constpub type CTFontDescriptorRef *const CTFontDescriptor; pub type CFDictionaryRef *const CFDictionary; pub type CFTypeRef *const (); pub type CTFontRef *const CTFont;这与 CoreFoundation 的 C 约定一致*Ref类型本身并不可变可变性由引用计数管理而非由指针可写性表达。两个extern C块分别用#[link(name CoreFoundation, kind framework)]和#[link(name CoreText, kind framework)]指定框架来源crates/mac_core/src/sys.rs。CoreFoundation 块覆盖引用计数核心CFRetain/CFRelease/CFGetTypeID、容器创建CFArrayCreate、CFDictionaryCreate、CFSetCreate、字符串编解码CFStringCreateWithBytes、CFStringGetBytes、CFStringGetCString等和 URL 的文件路径解析CFURLGetFileSystemRepresentationCoreText 块则覆盖字体描述符匹配CTFontDescriptorCreateWithAttributes、CTFontDescriptorCreateMatchingFontDescriptors、字体构建CTFontCreateWithFontDescriptor、字体属性/名称读取CTFontCopyAttribute、CTFontCopyName、CTFontCopyLocalizedName以及若干静态属性键kCTFontNameAttribute、kCTFontFamilyNameKey、kCTFontURLAttribute等。编码常量也集中在此如kCFStringEncodingUTF8: CFStringEncoding 0x08000100、kCFStringEncodingUnicode 0x0100等供上层CFString的编解码选择使用。四、内存安全模型CoreTypetrait 与引用计数CoreFoundation 的对象生命周期由CFRetain/CFRelease引用计数控制这是 Rust 封装最需要处理的正确性风险。crate 在 crates/mac_core/src/lib.rs 中定义了核心 traitpub unsafe trait CoreType: Sized { type SysTy; fn type_id() - CFTypeId; unsafe fn new_owned(ptr: NonNullSelf::SysTy) - Self; unsafe fn new_borrowed(ptr: NonNullSelf::SysTy) - Self; fn as_type_ref(self) - *const Self::SysTy; fn into_type_ref(self) - *const Self::SysTy { ... } fn into_ty(self) - CFType; }其中两个构造入口划定了所有权语义new_owned接收的指针已经归调用者所有来自...Create系列函数的返回值包装后由 Rust 的Drop在值消失时调用CFReleasenew_borrowed接收一个借用引用实现内部先执行一次CFRetain把借用转为自有再走new_owned——Clone的语义即由此而来。配套的cfty!宏crates/mac_core/src/macros.rs为每个具体类型统一生成#[repr(transparent)]的NonNull指针包装结构体、unsafe impl CoreType、以及关键的Clone/Drop实现——clone时CFRetaindrop时CFRelease。宏还通过 PhantomData 参数支持带类型参数的泛型容器如CFArrayT同时保持零开销repr(transparent)保证内存布局就是裸指针本身。基类类型CFTypecrates/mac_core/src/lib.rs是所有 CoreFoundation 类型的动态类型根注释里类比它为Java 中的Object。它持有NonNull()Drop时调用CFRelease并实现了CoreType。这样任何静态类型未知的返回值例如CTFontCopyAttribute返回的CFTypeRef都可以安全地包成CFType由其 Rust 值语义接管生命周期。五、动态类型识别CFTypeId与 upcast/downcastCoreFoundation 提供了运行时的类型 ID 机制CFGetTypeID及各类型的...GetTypeID函数crate 将其封装为pub struct CFTypeId(libc::c_ulong); impl CFTypeId { pub fn ofT: CoreType() - CFTypeId { T::type_id() } pub fn of_valT: CoreType(val: T) - CFTypeId { ... } }在此基础上实现了两个方向的安全转换upcastCoreType::into_ty(self) - CFType。实现用ManuallyDrop放弃原值的Drop避免重复释放把裸指针转交给新的CFType拥有——所有权精确交接一次不产生额外的 retain/releasedowncastunsafe fn CFType::downcastT(self) - ResultT, Self。先用CFTypeId::of_val(self) CFTypeId::of::T()做运行时类型 ID 比对匹配才转交所有权否则把原值作为Err原样退回不丢引用。crates/mac_core/src/lib.rs 的单元测试把这套机制的边界都钉住了值得特别关注三条断言的语义assert_eq!(CFTypeId::of::CFArrayCFString(), CFTypeId::of::CFArrayCFUrl()); assert_ne!(CFTypeId::of::CFString(), CFTypeId::of::CFUrl());由于CFArrayT的类型 ID 与元素类型T无关C 层就是同一个CFArrayGetTypeIDdowncast 到CFArrayCFType是安全的但从CFStringdowncast 到CFArrayCFString会因类型 ID 不等而失败。文档因此在downcast上显式标注CFArrayT → CFType → CFArrayU这种容器泛型参数丢失的情形无法由类型 ID 保证需要调用者自行负责——这是 FFI 场景下安全边界在哪里的典型诚实标注。六、容器与基础类型的安全 APIcrate 导出的公共类型共七个见 crates/mac_core/src/lib.rs 的pub use列表CFArray、CFDictionary、CFSet、CFString、CFUrl、CTFont、CTFontDescriptor。它们的 API 设计都有同一个特点只暴露创建即拥有的语义杜绝裸指针逃逸。6.1CFArrayT像Vec一样的只读序列crates/mac_core/src/array.rs 提供empty()、new(values: [T])、len/is_empty/get(index)。get的实现值得细看CFArrayGetValueAtIndex返回的是容器内存储的CFTypeRef本身并非指向 T 的指针因此代码用T::new_borrowed对返回值做一次CFRetain把从容器中借出的引用转化为调用者自有的独立引用越界则直接 panic。测试test_array_index验证了存取后元素与源对象指向同一底层 CF 对象且内容一致。6.2CFDictionaryK, V以Pairs抽象统一数组与 Vec 构造crates/mac_core/src/dict.rs 定义了AsPtr与Pairs两个内部 trait让CFDictionary::new同时接受[ (K, V); N ]定长数组和Vec(K, V)——底层统一拆成平行的键数组与值数组后调用CFDictionaryCreate并使用系统默认的kCFTypeDictionaryKeyCallBacks/ValueCallBacks。CFSetTcrates/mac_core/src/set.rs则只有new(values: [T])语义与HashSet构造一致测试以不崩溃为验证标准。6.3CFString多编码字符串与零拷贝读取crates/mac_core/src/string.rs 是最复杂的一个封装。它首先定义StrLiketraitencoding/len/as_ptr并为str恒按 UTF-8 编码与CStr合法 UTF-8 按 UTF-8否则退回 ASCII 编码实现使得CFString::new能接受多种 Rust 字符串来源。读取侧提供三档 API性能与语义递进get_string() - String先以零长度缓冲调用CFStringGetBytes探测所需长度再分配精确缓冲二次拷贝强制转 UTF-8保证总能拿到 RustStringas_str() - Cowstr先用CFStringGetCStringPtr试探字符串是否原生 UTF-8是则零拷贝Cow::Borrowed否则退化为get_string的所有型拷贝get_cstring() - OptionCString/as_cstr() - OptionCowCStr面向 C 字符串消费场景遇到含 NUL 的字符串会返回None测试test_as_non_cstr覆盖了CFString::new(fo\0o)这一边界。文档注释里特别强调CFString不保证是 UTF-8与 RustString的语义差异被显式写进 API——这类差异标注是阅读该 crate 时理解其安全哲学的好切入点。6.4CFUrlURL 到文件路径crates/mac_core/src/url.rs 只暴露一个方法fs_representation() - OptionCString用PATH_MAX大小的栈缓冲承接CFURLGetFileSystemRepresentation的结果不能表示为文件系统路径的 URL 返回None。这个 API 正是 macOS 上从系统字体对象拿到字体文件真实路径的关键一环。七、CoreText 封装CTFontDescriptor与CTFont字体侧的两个类型共同构成了 macOS 字体解析的完整链路。CTFontDescriptorcrates/mac_core/src/font_desc.rs代表字体描述符——一组属性约束尚未绑定字号new_with_attrs(CFDictionaryCFString, CFType)从属性字典构造CTFontDescriptorCreateWithAttributes未识别属性被系统忽略matching_font_descriptors(CFSetCFString)在已加载字体中查找满足强制属性集的全部匹配无匹配时安全地回退为空数组而非空指针attr(FontAttribute) - OptionCFType读取单个属性值。CTFontcrates/mac_core/src/font.rs则是描述符 字号 变换的具体字体提供new_descriptor(descriptor, size)包装CTFontCreateWithFontDescriptor传入空指针表示不施加仿射矩阵name(FontNameKey)/localized_name(FontNameKey)分别读取 PostScript/Full/Family/Style 四类名称含本地化版本attr(FontAttribute)读取 Name、FamilyName、DisplayName、URL、CascadeList字形回退列表五类属性。FontAttribute与FontNameKey两个枚举把 CoreText 的静态属性键如kCTFontNameAttribute、kCTFontFamilyNameKey从裸*const静态量提升为类型安全的枚举值其to_str()用new_borrowed对系统静态CFString做 retain保证生命周期正确。八、实战调用xetex_layout的MacBackend上述封装的最终消费方是排版引擎的字体管理层。FontManager::init_font_manager在 crates/xetex_layout/src/manager.rs 中按平台选择后端#[cfg(target_os macos)] { backend Box::new(mac::MacBackend::new()); } #[cfg(not(target_os macos))] { backend Box::new(fc::FcBackend::new()); }macOS 侧的 crates/xetex_layout/src/manager/mac.rs 完整演示了mac_core的典型组合用法。以按名查找字体为例fn find_fonts_with_name(name: CFString, key: FontAttribute) - CFArrayCTFontDescriptor { let attributes CFDictionary::new([(key.to_str(), name.into_ty())]); let descriptor CTFontDescriptor::new_with_attrs(attributes); let mandatory_attributes CFSet::new([key.to_str()]); descriptor.matching_font_descriptors(mandatory_attributes) }注意name.into_ty()这里把静态类型的CFStringupcast 成CFType塞进泛型字典CFDictionaryCFString, CFType——正是第五节 upcast 机制的实战用法。search_for_host_platform_fonts则展示了 Tectonic 特有的字体名回退策略先按 Display Name 精确匹配再把名称按第一个连字符切出家族名如HelveticaNeue→ 尝试Helvetica按 Family Name 匹配整个家族最后退回按 PostScript Name 匹配。命中单个字体时还会通过FontAttribute::FamilyName读出其家族名把同家族的所有兄弟字体一并加入缓存——这条单字体命中后拉入整个家族的逻辑保证了pdflatex/xelatex风格字体名切换时字重族的一致性。另一条链路是字体路径反查get_platform_font_desc用CTFont::new_descriptor(font, 0.0)构造零字号字体取FontAttribute::URL属性unsafe { url.downcast::CFUrl() }转成CFUrl后调用fs_representation()得到磁盘路径crates/xetex_layout/src/manager/mac.rs——这里的 downcast 之所以标注 unsafe原因即第六节所述CFType的动态类型 ID 可以挡住URL 根本不是 CFUrl但无法阻止未来 API 误用责任在调用方。而在 crates/xetex_layout/src/c_api.rs 中C 侧XeTeX C 引擎看到的平台字体句柄就是 Rust 封装类型的裸指针投影pub(crate) type RawPlatformFontRef tectonic_mac_core::sys::CTFontDescriptorRef; pub(crate) type PlatformFontRef tectonic_mac_core::CTFontDescriptor;即 C 引擎持有裸CTFontDescriptorRefRust 侧按需以new_borrowed语义重建带所有权的CTFontDescriptor再参与查询——这体现了整个 crate Rust 值拥有生命周期、C 边界只做引用传递的契约。九、小结这个 crate 教给我们的 FFI 封装要点回顾tectonic_mac_core的设计可以提炼出四条在 Rust 封装引用计数式 C 框架时通用、且在该仓库中得到源码验证的做法分层收缩 FFI 面sys模块集中所有extern C与 opaque 类型公共 API 一律不暴露裸指针as_type_ref等标注了#[doc(hidden)]用 trait 宏固化所有权约定new_owned/new_borrowed二选一的构造契约加上cfty!宏统一生成Cloneretain/Droprelease把 CoreFoundation 的 1/-1 规则编译进类型系统运行时类型 ID 支撑安全的 upcast/downcast并对类型 ID 无法保证泛型容器一致性这一残余风险做显式 unsafe 标注与文档说明平台门禁零成本化#![cfg(target_os macos)] build.rs 条件链接让上层 crate 无需为 macOS 特殊处理就能跨平台编译。对于想深入源码的读者建议的入口顺序是crates/mac_core/README.md定位→ crates/mac_core/src/lib.rsCoreType/CFType/CFTypeId核心模型与测试→ crates/mac_core/src/sys.rsFFI 声明全集→ crates/xetex_layout/src/manager/mac.rs真实消费场景。需要注意的是该 crate 仅在 macOS 目标上生成实质代码非 macOS 平台上以上 API 均不存在文中对xetex_layout调用链的分析同样基于当前仓库源码实际行为以 macOS 环境下编译运行结果为准。赞分享CLI【免费下载链接】tectonicA modernized, complete, self-contained TeX/LaTeX engine, powered by XeTeX and TeXLive.项目地址https://gitcode.com/gh_mirrors/te/tectonic点击查看免费下载相关推荐extern Rust 完全指南在 CXX 中将 Rust 类型与函数安全地暴露给 Cextern Rust 完全指南在 CXX 中将 Rust 类型与函数安全地暴露给 C extern Rust 是 CXX 桥接 cxx::br开发工具如何在互联网安全地暴露Ollama-WebUI-Lite服务如何在互联网安全地暴露Ollama WebUI Lite服务 背景介绍 Ollama WebUI Lite是一个基于Web的用户界面用于与Ollama模型服务前端AI 应用本地部署交互助手PyO3 实战如何将带 trait bound 的 Rust 函数安全地暴露给 Python 调用PyO3 实战如何将带 trait bound 的 Rust 函数安全地暴露给 Python 调用 导读 PyO3 为绝大多数 Rust 函数与类提供了开箱即开发工具上一篇常见问题解决RS_ASIO连接失败、无声音等10大故障排除指南下一篇微信聊天记录永久保存指南如何完整备份和分析你的珍贵对话创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

GDAL OGR ODBC 驱动详解:通过 Open Database Connectivity 访问空间与非空间数据库

GDAL OGR ODBC 驱动详解:通过 Open Database Connectivity 访问空间与非空间数据库

GIS遥感数据工程 【免费下载链接】gdal GDAL is an open source MIT licensed translator library for raster and vector geospatial data formats. 项目地址: https://gitcode.com/gh_mirrors/gd/gdal 点击查看 免费下载 ODBC(Open Database Connecti…

2026/10/13 5:54:39 阅读更多 →
syzkaller 仓库依赖库 TagAlign 源码解读:Go Struct Tag 对齐与排序的完整实现

syzkaller 仓库依赖库 TagAlign 源码解读:Go Struct Tag 对齐与排序的完整实现

测试操作系统网络安全 【免费下载链接】syzkaller syzkaller is an unsupervised coverage-guided kernel fuzzer 项目地址: https://gitcode.com/gh_mirrors/syz/syzkaller 点击查看 免费下载 本文以 syzkaller 仓库中 vendored 的 vendor/github.com/4meepo/taga…

2026/10/13 5:54:39 阅读更多 →
一套Python序列处理函数:从FASTA解析到蛋白质翻译

一套Python序列处理函数:从FASTA解析到蛋白质翻译

/* 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 5:53:39 阅读更多 →

最新新闻

链栈实验避坑指南:头歌数据结构实训全解析

链栈实验避坑指南:头歌数据结构实训全解析

简介:头歌数据结构链栈基本操作与应用学习资料包,面向正在学习数据结构与C实现的学生,以链栈这一动态栈结构为主线展开讲解。内容详细梳理链表节点定义、链栈结构体设计,以及初始化、销毁、清空、判空、求长、取栈顶、入栈、出栈、…

2026/10/13 6:40:49 阅读更多 →
ISCTF2025 MISC题目解析与CTF技巧总结

ISCTF2025 MISC题目解析与CTF技巧总结

1. ISCTF2025-MISC合集解题思路解析作为一名CTF老手,最近参加了ISCTF2025比赛,在MISC方向收获颇丰。下面我将详细记录每道题的解题过程,分享其中的技术要点和踩坑经验。1.1 Guess!数字解密题目分析:提示明确指向经典的…

2026/10/13 6:40:49 阅读更多 →
Hudi Metadata 表 Bloom Index 与 Column Stats 索引:基于元数据表的记录定位加速方案(RFC-37 深度解析)

Hudi Metadata 表 Bloom Index 与 Column Stats 索引:基于元数据表的记录定位加速方案(RFC-37 深度解析)

大数据数据湖数据工程 【免费下载链接】hudi Upserts, Deletes And Incremental Processing on Big Data. 项目地址: https://gitcode.com/gh_mirrors/hu/hudi 点击查看 免费下载 导读 本文基于 Apache Hudi 的 RFC-37(Metadata based Bloom Index&…

2026/10/13 6:40:49 阅读更多 →
直流电机调速PID参数整定实战:速度环调试与工程细节

直流电机调速PID参数整定实战:速度环调试与工程细节

/* 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 6:40:49 阅读更多 →
暴力破解原理与合法防御实践指南

暴力破解原理与合法防御实践指南

我不能按照您的要求生成关于“暴力破解实验步骤”的内容。原因如下:安全与合规底线不可逾越:暴力破解(Brute-force Attack)属于典型的未授权访问尝试行为,其技术原理虽在网络安全教学中作为攻击面分析的理论案例存在&a…

2026/10/13 6:40:49 阅读更多 →
HTML5新特性:音视频、画布、地理定位、本地存储

HTML5新特性:音视频、画布、地理定位、本地存储

HTML5 新增大量原生API,摆脱插件依赖,实现前端多媒体、绘图、定位、本地数据存储等能力,是现代前端开发的基础。1. 音视频标签(audio / video)原生支持音视频播放,无需flash插件,兼容性良好audi…

2026/10/13 6:39:49 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

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

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

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

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

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

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

2026/10/12 0:16:38 阅读更多 →
影刀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/12 21:05:09 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →