手机上用Claude Code开发iNaturalist观察记录工具:Git Scraping实战

Simon Willison用手机和AI工具,零成本搭建了自然观察记录展示网站
Simon Willison在露营时仅用手机和Claude Code,构建了一个展示iNaturalist自然观察记录的Web工具。项目采用三层架构:Python CLI处理数据聚合、Git Scraping通过GitHub Actions自动更新数据、纯静态前端页面展示。整套方案利用GitHub免费基础设施实现零成本托管,体现了关注点分离、简单优先的设计哲学,是个人项目无服务器架构的典型范例。
项目背景:为什么要在手机上写代码
Simon Willison(知名开发者、Datasette创始人)最近分享了一个颇具启发性的项目:他在野外露营时,完全用手机和Claude Code for web,从零搭建了一个展示iNaturalist自然观察记录的Web工具。
Simon Willison是Django框架的联合创始人之一,后来创建了Datasette——一个将SQLite数据库即时转化为可交互API和Web界面的开源工具。他长期倡导"小工具"哲学,主张用最简单的技术栈解决实际问题,也是AI辅助编程的早期实践者和布道者,持续记录和分享使用LLM进行软件开发的经验。
iNaturalist是一个广受欢迎的自然观察社区平台,由加州科学院和国家地理学会联合运营,拥有超过1.5亿条观察记录和数百万活跃用户。用户可以上传动植物照片并获得AI物种识别——其核心的计算机视觉系统会给出物种建议,再由社区专家确认。该平台提供完善的RESTful API,允许开发者按用户、地点、时间等维度查询观察数据,返回包含物种信息、地理坐标、照片URL等字段的JSON格式数据。Simon拥有两个独立的iNaturalist账户,他想把两个账户的观察记录按时间和地点聚合展示在一起。
需求本身不复杂,但涉及数据获取、聚合处理和前端展示三个环节。真正有意思的是,他选择在露营周末、仅靠一部手机完成了整个开发流程。
Claude Code for Web是Anthropic推出的基于浏览器的AI编程助手,与传统的桌面IDE集成不同,它完全运行在浏览器中,这意味着用户可以在任何有网络连接的设备上使用,包括手机和平板。它支持代码生成、文件编辑、项目结构规划等功能,虽然无法直接在本地执行代码,但可以生成完整的可部署代码并通过GitHub等平台进行版本管理。这恰好说明了当前AI编程工具的一个关键价值:大幅降低对开发环境的依赖。
三层技术架构详解
整个项目由三个独立组件构成,各司其职又相互配合。
第一层:Python CLI数据处理工具
Simon首先构建了一个名为inaturalist-clumper的Python命令行工具,负责从iNaturalist API拉取观察数据并进行"聚合"(clumping)处理。
聚合的默认规则是:将时间间隔在2小时以内、地理距离在5公里以内的观察记录归为同一组。这个设计很贴合实际使用场景——一次野外观察活动中拍摄的多张照片会被自然归为一次"出行"。这种基于时空邻近性的聚类算法在地理信息系统(GIS)领域很常见,本质上是一种简化的DBSCAN(基于密度的空间聚类)思想,只不过这里同时考虑了时间和空间两个维度。
第二层:Git Scraping自动化数据更新
第二个组件是simonw/inaturalist-clumps仓库,采用了Simon本人推广的"Git Scraping"模式——利用GitHub Actions定期运行脚本,将处理结果自动提交到仓库中的clumps.json文件。
Git Scraping是Simon Willison在2020年提出并推广的一种数据采集模式。其核心思想是利用GitHub Actions的定时触发功能(cron schedule),周期性地运行数据抓取脚本,然后将结果通过git commit自动提交到仓库。由于Git本身就是版本控制系统,每次数据变化都会被完整记录,形成天然的时间序列数据库。这种模式已被广泛用于追踪政府数据变化、监控网站内容更新、记录API返回值变化等场景。
GitHub Actions是GitHub内置的CI/CD和自动化平台,通过YAML配置文件定义工作流。工作流可以由代码推送、Pull Request、定时计划(cron表达式)或外部事件触发。每个工作流运行在GitHub提供的虚拟机中,支持Ubuntu、macOS和Windows环境,可以安装任意依赖并执行脚本。对于公开仓库,Actions的使用完全免费且无分钟数限制,这使得Git Scraping模式几乎零成本。
第三层:纯前端静态展示页面
最后一层是一个静态HTML页面,通过fetch()从GitHub获取JSON数据,渲染为观察记录的缩略图网格。这里利用了一个关键特性:GitHub的raw.githubusercontent.com域名在响应头中设置了适当的CORS(Cross-Origin Resource Sharing,跨域资源共享)策略,允许任何来源的前端代码直接获取文件内容。CORS是浏览器的安全机制,默认阻止网页JavaScript向不同域名发起请求,但GitHub的开放策略使得开发者无需搭建代理服务器或后端API,就能让纯静态页面读取存储在仓库中的数据文件。
具体实现包括:
- 使用
loading=\"lazy\"实现图片懒加载,优化页面性能。这是HTML原生的延迟加载属性,告诉浏览器只在图片即将进入视口时才发起网络请求。对于包含大量图片的页面,如果一次性加载所有缩略图,可能产生数百个并发HTTP请求,严重影响页面加载速度。浏览器通过Intersection Observer API在底层实现这一功能,开发者无需编写任何JavaScript代码。 - 点击缩略图时通过HTML原生
<dialog>元素弹出模态框展示大图。<dialog>是HTML5原生提供的模态框组件,于2022年在所有主流浏览器中获得完整支持。相比传统的JavaScript模态框库,原生dialog元素具有内置的焦点管理、键盘导航支持(Escape键关闭)、背景遮罩(::backdrop伪元素)等无障碍特性,且无需引入任何第三方依赖。 - 显示物种的常见名称(如果有的话)
Git Scraping模式的精妙之处
这个项目中最值得关注的架构决策是Git Scraping的运用。它把GitHub仓库当作一个免费的、自带版本控制的数据库来使用:
- 零成本托管:GitHub免费提供存储和CDN服务
- 自动更新:GitHub Actions定时任务保持数据持续刷新
- 完整版本历史:Git天然记录每次数据变化,方便回溯
- CORS友好:GitHub raw文件支持跨域访问,前端JavaScript可以直接fetch,无需搭建API服务器
这种模式特别适合数据量不大、更新频率不高的个人项目。不需要数据库,不需要后端服务,一个GitHub仓库就能搞定数据的存储、更新和分发。值得注意的是,GitHub对单个文件大小有100MB的限制,对仓库总大小建议控制在1GB以内,因此这种模式最适合JSON、CSV等文本格式的中小规模数据集。对于需要频繁更新(如每分钟一次)或数据量较大的场景,传统数据库仍然是更合适的选择。
用一条Prompt完成前端开发
整个前端页面的开发通过一条精心编写的prompt交给Claude Code完成。Simon的prompt结构值得学习:
- 明确目标:说清楚要构建什么文件、放在哪个仓库
- 指定数据来源:给出JSON文件的完整URL
- 描述功能需求:缩略图网格展示、懒加载、模态框查看大图
- 补充具体细节:图片URL的拼接格式、交互行为、信息展示规则
这种结构化的prompt写法,比模糊地说"帮我做个网页"要高效得多。给AI足够的上下文和约束条件,才能一次性得到可用的结果。这也体现了prompt engineering的核心原则:具体性(specificity)优于模糊性,约束条件越明确,AI的输出越可控。在移动端使用AI编程时,由于无法方便地进行多轮调试和修改,一次性给出完整、精确的需求描述就显得尤为重要。
设计哲学与可复用的开发模式
这个项目虽然小巧,但背后的设计原则值得在更多场景中借鉴:
- 关注点分离:数据获取、存储更新、前端展示三个环节各自独立,任何一层都可以单独替换。这是软件工程中经典的分层架构思想,每一层只关心自己的职责,通过明确定义的接口(这里是JSON文件格式)与其他层交互。
- 充分利用免费基础设施:GitHub同时承担了代码托管、数据存储、自动化运行和静态页面托管四重角色。GitHub Pages提供免费的静态网站托管,支持自定义域名和HTTPS,对于个人项目来说完全可以替代传统的Web服务器。
- 渐进式构建:先做CLI工具确保数据处理逻辑正确,再加自动化,最后做前端展示。这种由内而外的构建顺序确保了每一步都可以独立验证,降低了调试复杂度。
- 简单优先:纯静态页面,没有构建步骤,没有框架依赖,没有后端服务器。在当今前端工程化日益复杂的背景下(webpack、Vite、React、Next.js等工具链),这种回归原生HTML/CSS/JavaScript的做法反而显得清新。对于功能明确、交互简单的工具类页面,原生技术栈完全够用,还能避免依赖更新和构建配置带来的维护负担。
总结
这个项目是"小工具大智慧"的典型案例。Simon Willison用Claude Code、Git Scraping和GitHub Pages这些免费工具的组合,以极低的成本和时间投入解决了一个实际问题。
对于想要构建个人数据展示工具的开发者来说,这套模式可以直接复用:用Python脚本处理数据,用GitHub Actions定时更新,用静态页面做展示。不需要服务器,不需要数据库,几个简单组件的巧妙组合就够了。这种"无服务器"(serverless)的个人项目架构,代表了一种越来越流行的开发范式——利用平台提供的免费能力,将运维复杂度降到最低,让开发者可以专注于解决实际问题本身。
相关推荐
教程攻略Cursor+Codex双IDE协同:开源项目二开实战方法论
基于实战经验总结的开源项目二次开发完整方法论,详解Cursor+Codex双IDE协同工作流,涵盖二开七环节、MVP验证、AI读源码技巧,帮助开发者三天跑通项目、两周完成业务集成。
教程攻略Cursor多Agent实战:50分钟搭建Next.js全栈博客
使用Cursor IDE多Agent协作模式,50分钟内从零搭建全栈博客。涵盖Next.js、Clerk认证、Supabase数据库集成,详解4个AI Agent分阶段开发流程与关键避坑经验。
教程攻略从零搭建AI软件工厂:Cursor工程师的多Agent协作实战经验
Cursor工程师Eric分享AI软件工厂构建实战:从自动化六层级、护栏设计、并行Agent管理到规模化扩展,详解如何用多Agent协作实现7×24小时高效软件开发。