PhantomJS无头浏览器:从核心原理到爬虫实战与替代方案
1. 项目概述一个被时代铭记的“无头”浏览器如果你在2015年到2018年间接触过Python网络爬虫那么“PhantomJS”这个名字对你来说一定如雷贯耳。它曾被誉为爬虫界的“暗夜骑士”是无数开发者在对抗动态网页渲染、处理复杂JavaScript逻辑时的首选利器。简单来说PhantomJS是一个基于WebKit内核的“无头浏览器”。所谓“无头”就是没有图形用户界面你无法像使用Chrome或Firefox那样看到窗口、点击按钮但它却能在后台完整地加载网页、执行脚本、渲染页面并允许你通过脚本控制一切。这对于爬虫开发者而言意味着可以直接获取到JavaScript执行后的最终HTML完美解决了传统requests库只能获取静态源码的痛点。然而今天再谈PhantomJS更像是在回顾一段技术史。它的核心价值在于其开创性——在Selenium等工具对无头模式支持尚不完善的年代PhantomJS提供了一个轻量、可编程的完整浏览器环境。尽管如今其官方开发已经停止并被更现代的Headless Chrome等方案取代但理解PhantomJS的工作原理、使用逻辑以及它最终面临的挑战对于深入理解浏览器自动化与爬虫技术的演进依然具有不可替代的学习价值。这篇文章我将带你重回那个时代拆解PhantomJS的核心机制手把手复现其典型应用场景并深入分析它为何会逐渐退出历史舞台以及我们从中学到的技术选型经验。2. PhantomJS核心架构与工作原理拆解要理解PhantomJS为何强大必须先弄明白它的“五脏六腑”。它的设计哲学是“将完整的浏览器能力封装成一个可脚本控制的服务”。2.1 基于WebKit的渲染引擎PhantomJS的内核是WebKit这是Safari浏览器和旧版Chrome所使用的渲染引擎。这意味着PhantomJS对网页的解析、布局、渲染逻辑与这些浏览器高度一致。当它加载一个URL时其内部流程可以概括为以下几个步骤网络请求发起HTTP请求下载HTML文档、CSS样式表、JavaScript文件以及图片等资源。构建DOM树解析HTML构建文档对象模型树。应用CSS并构建渲染树解析CSS将样式应用到DOM节点上形成渲染树。布局计算每个渲染节点在页面中的确切位置和大小。绘制与渲染将渲染树绘制到内存中的位图上。JavaScript执行在渲染的各个阶段响应并执行页面中的JavaScript代码这可能动态地修改DOM、发起新的网络请求。关键在于所有这些步骤都在后台静默完成最终输出的是经过完整渲染后的“快照”。爬虫脚本可以通过PhantomJS提供的API在任何一步之后获取到当时的页面状态。2.2 独特的脚本控制模式PhantomJS与CasperJSPhantomJS本身通过JavaScript进行控制。你编写一个JS脚本在其中调用PhantomJS的API来创建页面对象、导航、操作DOM。一个最基础的脚本框架如下// example.js var page require(webpage).create(); // 创建一个页面对象 var url http://example.com; page.open(url, function(status) { if (status success) { // 页面加载成功后的回调函数 console.log(Page title is: page.evaluate(function() { return document.title; // 在页面上下文中执行JavaScript })); // 可以在这里进行截图、获取HTML等操作 phantom.exit(); // 必须调用否则脚本不会结束 } else { console.log(Page failed to load.); phantom.exit(1); } });然后在命令行执行phantomjs example.js。这里有一个非常重要的概念page.evaluate()。这个方法允许你在页面的上下文中执行一段JavaScript代码就像在浏览器的开发者控制台里输入一样并且可以返回执行结果到外部脚本环境。这是爬取动态生成数据的核心手段。注意在page.evaluate()内部执行的代码无法直接访问外部脚本定义的变量。通信需要通过参数传递和返回值进行。为了更方便地编写测试或爬虫脚本社区诞生了CasperJS。它构建在PhantomJS之上提供了更高级、更语义化的API例如链式调用、步骤队列、自动等待、断言等极大地简化了复杂流程的编写。// 使用CasperJS的示例片段 casper.start(http://example.com); casper.then(function() { this.echo(Page title: this.getTitle()); }); casper.run();2.3 与Python的桥接Selenium与Ghost.py虽然PhantomJS原生用JS控制但在Python生态中我们主要通过两个桥梁来使用它Selenium WebDriver这是最主流的方式。Selenium是一个浏览器自动化框架它定义了WebDriver协议。PhantomJS实现了这个协议因此可以通过Selenium的Python绑定来驱动。from selenium import webdriver driver webdriver.PhantomJS(executable_path/path/to/phantomjs) driver.get(http://example.com) print(driver.title) driver.quit()这种方式让Python开发者能够用熟悉的Selenium API来控制PhantomJS包括查找元素、点击、输入等。Ghost.py这是一个更轻量级、更Pythonic的库它直接通过进程间通信与PhantomJS交互而不是通过WebDriver协议。它的API设计更贴近PhantomJS的原生JS API在某些场景下更直接高效但生态和普及度远不及Selenium。选择考量对于大多数需要与现有Selenium测试套件集成或需要丰富社区支持的爬虫项目通过Selenium驱动是标准做法。如果你追求极致的控制效率和更底层的操作且项目纯粹基于PhantomJS那么研究Ghost.py或直接编写JS脚本可能是选项。3. 核心应用场景与实战操作解析了解了原理我们来看看PhantomJS当年是如何大显身手的。以下场景即使放在今天其解决思路也具有借鉴意义。3.1 场景一爬取动态渲染的单页应用数据这是PhantomJS的“主场”。假设我们要爬取一个使用React或Vue构建的电商网站产品列表是通过AJAX滚动加载的。传统requests库的困境直接requests.get()只能拿到一个几乎空的HTML外壳真正的产品数据在后续的JavaScript请求中动态填入数据可能来自复杂的API接口并伴有加密参数直接模拟难度大。PhantomJS解决方案模拟真实用户行为让浏览器“跑”完所有JS逻辑。实操步骤使用Selenium PhantomJS环境准备确保已安装Python的Selenium库pip install selenium并下载了PhantomJS可执行文件放到系统路径或指定位置。初始化驱动并加载页面from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time # 创建驱动可指定路径 driver webdriver.PhantomJS(executable_path./phantomjs) driver.set_window_size(1920, 1080) # 设置视窗大小某些页面布局依赖于此 target_url https://your-spa-website.com/products driver.get(target_url)等待关键内容加载动态页面加载需要时间。使用“显式等待”是最佳实践它比固定的time.sleep更高效可靠。try: # 等待某个标志性元素出现比如第一个产品卡片 wait WebDriverWait(driver, 10) first_product wait.until( EC.presence_of_element_located((By.CSS_SELECTOR, .product-item)) ) print(初始产品列表加载完成。) except Exception as e: print(等待超时或元素未找到, e) driver.quit()模拟滚动加载许多单页应用采用滚动到底部加载更多的方式。last_height driver.execute_script(return document.body.scrollHeight) while True: # 滚动到底部 driver.execute_script(window.scrollTo(0, document.body.scrollHeight);) # 等待新内容加载 time.sleep(2) # 此处可根据网络情况调整或改用等待特定新元素出现 new_height driver.execute_script(return document.body.scrollHeight) if new_height last_height: print(已滚动至页面底部加载完毕。) break last_height new_height提取数据此时页面DOM已包含所有动态加载的产品信息。products driver.find_elements(By.CSS_SELECTOR, .product-item) data_list [] for product in products: # 假设产品名称在 .name 类元素内 name_elem product.find_element(By.CSS_SELECTOR, .name) price_elem product.find_element(By.CSS_SELECTOR, .price) data_list.append({ name: name_elem.text, price: price_elem.text }) print(f共爬取到 {len(data_list)} 条产品数据。) # 后续可以进行数据存储...资源清理driver.quit() # 务必退出释放资源实操心得PhantomJS在处理这类页面时最耗时的往往是等待JavaScript执行和网络请求。合理设置超时时间、利用显式等待精准判断加载状态是提升爬取效率和稳定性的关键。另外注意PhantomJS的user-agent可能被一些网站识别必要时需要自定义。3.2 场景二网页截图与PDF生成这个功能在自动化测试报告、网页归档、服务端渲染预览等场景非常有用。PhantomJS原生支持高质量的截图和PDF渲染。核心APIpage.render(screenshot.png)将当前页面渲染为PNG图片。page.render(output.pdf, {format: pdf})将当前页面渲染为PDF文件。Python实战示例通过Selenium间接实现截图PDF生成需用原生JS脚本截图from selenium import webdriver driver webdriver.PhantomJS() driver.get(http://example.com) # Selenium的save_screenshot方法底层调用了PhantomJS的render driver.save_screenshot(full_page_screenshot.png) driver.quit()生成PDF需编写并调用JS脚本文件 创建一个generate_pdf.js文件var page require(webpage).create(); var system require(system); var url system.args[1]; // 从命令行参数获取URL var output system.args[2]; // 输出PDF路径 page.open(url, function(status) { if (status success) { // 可以设置PDF的纸张尺寸、边距等 page.paperSize { format: A4, orientation: portrait, margin: 1cm }; window.setTimeout(function() { page.render(output, {format: pdf}); phantom.exit(); }, 500); // 给予页面额外渲染时间 } else { console.error(Unable to load the URL!); phantom.exit(1); } });在Python中调用import subprocess subprocess.run([phantomjs, generate_pdf.js, http://example.com, output.pdf])注意事项截图和PDF的质量高度依赖于页面的最终渲染状态。对于含有复杂CSS动画或WebGL的页面可能需要更长的等待时间window.setTimeout以确保渲染完成。此外PhantomJS的PDF渲染对某些CSS属性如flexbox的支持可能不如现代浏览器完美。3.3 场景三自动化测试与网络监控在持续集成环境中PhantomJS常被用于运行前端单元测试如通过QUnit、Jasmine、Mocha或进行页面功能回归测试。其无头特性使得它可以在服务器命令行环境中无缝运行。基本流程测试框架如Karma启动一个PhantomJS实例。将测试用例代码注入到PhantomJS打开的页面中执行。收集测试结果并反馈给构建系统。网络监控PhantomJS可以监听页面的所有网络请求和响应用于分析页面性能、检测错误请求或抓取API数据。page.onResourceRequested function(requestData, networkRequest) { console.log(Request (# requestData.id ): JSON.stringify(requestData)); }; page.onResourceReceived function(response) { console.log(Response (# response.id ): JSON.stringify(response)); };这个功能在分析复杂单页应用的资源加载瀑布图、逆向工程其API调用链时极其有用。4. PhantomJS的局限性、衰落原因与现代替代方案尽管PhantomJS曾风光无限但其自身缺陷和外部环境变化共同导致了它的衰落。4.1 主要局限性内核陈旧基于较老版本的WebKit对最新的ES6 JavaScript语法、CSS3特性如Grid布局支持不佳导致其渲染的页面可能与用户实际在Chrome/Firefox中看到的存在差异。性能与内存相比于Chrome的V8引擎其JavaScript执行效率较低。在处理复杂页面时内存占用可能失控甚至发生内存泄漏长时间运行的稳定性堪忧。功能缺失不支持现代Web API如WebRTC、部分HTML5特性等。其开发者工具支持也非常有限调试困难。维护停滞2018年核心维护者宣布退出停止了主要开发。这意味着安全漏洞无法及时修复新特性无法添加项目实质上进入了“维护模式”并最终停止。4.2 衰落的关键节点与替代方案关键节点2017年Google Chrome 59版本推出了稳定的无头模式。这意味着开发者可以直接使用功能完整、性能强劲、与用户浏览器高度一致的Chrome浏览器进行无头操作。同时Selenium等工具迅速跟进支持。相比之下PhantomJS的所有优势瞬间化为乌有。现代替代方案Chrome/Chromium in Headless Mode (通过Selenium)from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options Options() chrome_options.add_argument(--headless) # 启用无头模式 chrome_options.add_argument(--disable-gpu) # 早期在Windows上需要 chrome_options.add_argument(--no-sandbox) # 在Linux容器内运行时可能需要 driver webdriver.Chrome(optionschrome_options)优势功能最全、性能最佳、调试方便可通过--remote-debugging-port启用开发者工具、生态繁荣。Puppeteer (Node.js)由Chrome团队直接开发维护提供比Selenium更底层、更强大的API来控制Headless Chrome。它几乎能实现所有浏览器操作是Node.js生态下的首选。const puppeteer require(puppeteer); (async () { const browser await puppeteer.launch(); const page await browser.newPage(); await page.goto(https://example.com); await page.screenshot({path: example.png}); await browser.close(); })();Playwright (多语言支持)由微软开发支持Chromium、Firefox和WebKit三大内核。它的API设计现代化跨浏览器一致性做得非常好并且原生支持Python、Node.js、Java、.NET。from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() page.goto(http://example.com) print(page.title()) browser.close()4.3 技术选型经验总结从PhantomJS的兴衰我们可以提炼出几条宝贵的技术选型经验紧跟核心生态当一个工具是某个巨大生态的“副产品”或“兼容层”时如PhantomJS之于WebKit其发展潜力往往受制于上游。而直接拥抱核心生态的主流方案如Headless Chrome之于Chrome通常能获得更持久的技术红利和社区支持。性能与标准兼容性是硬通货在工具选型时对最新Web标准的支持度和运行时性能是必须重点考量的指标。PhantomJS在这两方面的落后是其被淘汰的根本内因。活跃的社区是生命线一个无人维护的工具即使曾经再辉煌也会因为安全、兼容性问题迅速变得不可用。选择那些有明确维护团队和活跃社区的项目。“无头”只是特性不是产品PhantomJS本质上是一个完整的浏览器产品。当Chrome、Firefox这些“正主”自己具备了无头能力后专门的、功能缩水的无头浏览器产品就失去了存在必要。这提醒我们在技术架构上是选择“全能选手的细分模式”还是选择“单一功能的专业工具”需要深思。5. 常见问题与排查技巧实录即使使用现代替代方案当年在PhantomJS上遇到的许多问题及其排查思路今天依然通用。5.1 页面加载不全或元素找不到问题现象脚本执行find_element时超时或报错但手动打开浏览器页面是正常的。排查思路检查等待策略是否使用了固定的time.sleep强烈建议改用WebDriverWait配合expected_conditions。确保等待的条件是准确的例如等待元素可见(visibility_of_element_located)而不仅仅是存在(presence_of_element_located)。验证元素选择器使用浏览器的开发者工具确保你的CSS选择器或XPath在当前渲染出的DOM中是唯一且准确的。页面的动态结构可能发生变化。查看页面源码在出错时让脚本将当前页面的HTML源码或截图保存下来。with open(debug_page.html, w, encodingutf-8) as f: f.write(driver.page_source) driver.save_screenshot(debug_screenshot.png)对比你看到的和脚本“看到”的页面是否一致。检查浏览器环境无头模式下的user-agent、视窗大小、Cookie状态等可能与带界面的模式不同这可能影响服务端返回的页面内容。尝试在无头模式下设置一个常见的user-agent和合理的窗口大小。5.2 内存占用过高或进程僵死问题现象脚本运行一段时间后系统内存耗尽或PhantomJS进程无响应。排查与解决循环引用与资源释放确保在循环中创建的对象如页面对象被正确关闭。对于Selenium每次循环后考虑使用driver.execute_script(window.open();)和driver.switch_to.window来切换到新标签页并关闭旧标签页有时比直接driver.get能更好地释放内存。限制并发与页面数量避免同时打开过多页面或浏览器实例。一个进程一个实例通常是安全的选择。设置超时与强制退出为网络请求和脚本执行设置合理的超时时间。同时在主程序中使用try...finally块或信号处理确保在异常情况下也能调用driver.quit()或phantom.exit()。升级与替代如果问题持续存在这很可能是PhantomJS本身的内存管理问题。最根本的解决方案是迁移到Headless Chrome或Playwright。5.3 执行效率低下问题现象爬取速度很慢远低于预期。优化技巧禁用无关功能在启动PhantomJS时通过命令行参数或Selenium的DesiredCapabilities禁用图片加载、CSS渲染、Web安全检测等不需要的功能可以大幅提升加载速度。from selenium.webdriver.common.desired_capabilities import DesiredCapabilities dcap DesiredCapabilities.PHANTOMJS dcap[phantomjs.page.settings.loadImages] False dcap[phantomjs.page.settings.resourceTimeout] 10000 driver webdriver.PhantomJS(desired_capabilitiesdcap)优化等待逻辑用精准的显式等待替代全局的固定等待。只等待必要的元素出现而不是每步都sleep。评估技术方案对于纯数据接口优先尝试用requests模拟API调用这比启动一个完整的浏览器引擎要快几个数量级。只有当页面逻辑极其复杂、无法简单模拟时才动用无头浏览器这个“重型武器”。回顾PhantomJS的整个生命周期它更像是一个特定技术过渡时期的英雄。它教会了我们如何以编程方式与一个完整的浏览器环境交互解决了当时爬虫与前端测试领域的核心痛点。虽然它已退役但其思想被后来的Headless Chrome、Puppeteer和Playwright完美继承并大幅发展。今天当我们轻松地使用--headlessnew参数启动Chrome时不应忘记PhantomJS在“无头浏览”这条路上所做的开拓性贡献。对于学习者而言通过它理解浏览器自动化的工作原理依然是一条有价值的路径。而在实际项目中请毫不犹豫地选择那些活跃在当下、代表着未来的现代工具。

相关新闻

3分钟上手Blender 3MF插件:免费导入导出3MF格式的完整指南

3分钟上手Blender 3MF插件:免费导入导出3MF格式的完整指南

3分钟上手Blender 3MF插件:免费导入导出3MF格式的完整指南 【免费下载链接】Blender3mfFormat Blender add-on to import/export 3MF files 项目地址: https://gitcode.com/gh_mirrors/bl/Blender3mfFormat 设计师老张花了一下午给模型上好了材质和颜色&…

2026/10/11 5:21:14 阅读更多 →
FFmpeg自动化视频剪辑:批量裁剪片头片尾的脚本实现

FFmpeg自动化视频剪辑:批量裁剪片头片尾的脚本实现

在实际的视频剪辑工作中,我们常常会遇到一些看似简单的需求,比如“把这段视频的片头和片尾去掉”、“把中间这段静音的部分剪掉”或者“把几个短视频合并成一个”。对于有经验的剪辑师,这些操作可能确实“一秒都不用剪”,因为他们…

2026/10/10 4:30:34 阅读更多 →
数学建模竞赛零基础通关指南:从算法到论文的实战方法论

数学建模竞赛零基础通关指南:从算法到论文的实战方法论

1. 项目概述:从零到一的数学建模竞赛通关手册如果你点开这篇文章,大概率是刚听说“数学建模”这个词,或者已经报名了比赛,正对着一堆“算法”、“编程”、“论文写作”感到无从下手。别慌,这种感觉我太熟悉了。十年前&…

2026/10/11 9:24:33 阅读更多 →

最新新闻

Spring Boot汽车销售服务管理系统:从数据库设计到前后端部署全解析

Spring Boot汽车销售服务管理系统:从数据库设计到前后端部署全解析

最近有不少同学在挑毕业设计题目,我的建议是别一上来就找那种花里胡哨的“人工智能区块链”标题,先问问自己:这系统我能不能完整讲清楚、能不能真正跑起来。汽车销售服务管理系统就是这么个经典选题——业务脉络清晰,技术栈主流&a…

2026/10/13 17:31:43 阅读更多 →
DAX度量值嵌套实战:上下文传递、VAR与CALCULATE的应用

DAX度量值嵌套实战:上下文传递、VAR与CALCULATE的应用

很多人第一次接触度量值的嵌套使用,都会觉得它不过是在公式里多套几层函数、多引用几个度量值。直到某零售项目的看板里,销售额、达成率、环比、同比、健康度评分全挤在一起时,才发现嵌套真正的难点根本不是“怎么写公式”,而是“…

2026/10/13 17:31:43 阅读更多 →
AnyPS5项目解析:PS5手柄跨平台兼容性与蓝牙HID技术实现

AnyPS5项目解析:PS5手柄跨平台兼容性与蓝牙HID技术实现

我无法根据当前输入内容生成符合要求的博文。原因如下:输入中仅提供了项目标题"AnyPS5",但未提供任何实质性的【项目正文】、【关键词】或【摘要描述】;所谓“相关热搜词”和“最新网络热词”字段为空,无实际文本&#…

2026/10/13 17:31:43 阅读更多 →
R语言无监督聚类实战:K-means与层次聚类核心原理及调参指南

R语言无监督聚类实战:K-means与层次聚类核心原理及调参指南

1. 为什么无监督聚类值得你花时间搞明白做数据分析的人迟早会撞上这样一个场景:手里攥着一份数据,有几十个甚至上百个特征列,但偏偏没有标签。你没法做分类,也没法做回归,因为压根不知道“正确答案”长什么样。这时候聚…

2026/10/13 17:31:43 阅读更多 →
2022美赛C题完整解题链路:从预测建模到回测避坑指南

2022美赛C题完整解题链路:从预测建模到回测避坑指南

简介:这是一份面向美赛参赛者和数模爱好者的2022年C题完整资料包,针对“数据建模与预测”类赛题提供从问题分析、模型构建到代码落地的全流程参考。资源共31个文件,以Python脚本、可视化图表、模型权重及说明文档为主,压缩包大小约…

2026/10/13 17:31:43 阅读更多 →
高效离职面谈:四种实战方法搞定主动与被动离职

高效离职面谈:四种实战方法搞定主动与被动离职

离职面谈这事儿,说大不大,说小不小。很多业务负责人和刚入行的HR伙伴把它当成一个“过场”,员工提离职了,约个时间聊二十分钟,问问“为啥走啊”“下家去哪啊”,然后填张表就算交差了。但真正在组织里待久了…

2026/10/13 17:30:42 阅读更多 →

日新闻

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

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

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

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/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/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/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 阅读更多 →