Communitygithub.com

harwal2000/skills

当用户需要从他们登录的网站中提取个人数据(如订单历史、行程、预订、账单、观看/收听记录等),且网站没有可用的导出功能,或现有的爬虫仓库已过时、损坏或需要用户密码时使用。

skills 是什么?

该技能专为需要从登录网站提取个人数据的用户设计,适用于网站没有导出功能或现有爬虫方案不可靠的场景。它支持在 Playwright 浏览器中由用户手动登录,然后通过页面内部的会话 Cookie 和真实请求头重放数据接口,将原始响应保存到本地磁盘。整个过程不处理用户凭据,提高了安全性。该技能适用于所有需要用户登录的网页服务,包括订单、旅行记录、账单、收藏等数据源。其工作流程包括:配置 Git 忽略输出目录、引导用户登录、发现数据接口(支持 JSON XHR、GraphQL、服务端渲染 HTML 和分区列表)、在页面内进行后台分页、保存原始数据、解析并验证数据完整性。该技能强调只读操作,只重放页面自身用于显示数据的请求,绝不会执行修改操作(如下单、取消或评分)。

兼容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/harwal2000/skills/tree/HEAD/skills/scraping-account-data

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

抓取账户数据

概述

用户用自己的双手在 Playwright 浏览器中登录;您找到网站自身页面使用的数据源,并在页面内部重放它(会话 Cookie + 真实请求头),将原始响应保存到磁盘。绝不处理凭据。

何时使用

  • “获取我的<服务>历史记录”、“抓取我的订单/行程/预订”、“使用这个爬虫仓库”
  • 旧的爬虫仓库(requests + 密码/OTP 登录):仅在 GitHub 上读取以获取端点名称和选择器。切勿运行它们——机器人检测(HTTP 202 空响应体、验证码)会破坏它们,且它们需要密码。

首先尝试官方导出。 Google 数据导出、“下载您的数据”、GDPR/DPDP 请求、公开 API、电子邮件收据。慢速导出需要几天时间——请让用户先请求一个,然后立即抓取,等导出到达后按 ID 交叉检查。

工作流程

  1. 在写入任何内容之前先配置 Git 忽略输出目录(data/<服务>/ 或项目中的等效目录);用 git check-ignore 确认。原始数据包含地址、电话号码、GPS 信息。
  2. 导航,移交登录。 打开账户页面;让用户在浏览器窗口中输入手机号/密码/OTP,完成后回复。切勿在聊天中要求提供验证码。
  3. 发现数据源(browser-snippets.md §1)。使用监听器重新加载页面并进行分类:
    • JSON XHR/fetch(最佳)——记下列表端点、分页格式(next_url/游标、page_number、offset = 最后一条 ID、endOfList)以及详情端点(打开一个条目)。
    • GraphQL——一个 POST /graphql;记录完整的请求体(operationName、query 或持久化查询 hash、variables)。
    • 服务端渲染 HTML——数据在 document 响应中;在页面内同时获取列表和详情页,用 DOMParser 解析;同时保存原始 HTML 以便后续重新解析。
    • 分区列表——如果列表按某个筛选条件划分(年份下拉框、日期范围、标签页如已归档/已取消/数字),读取每个筛选值并对每个值进行分页。
  4. 身份验证。 首先尝试 fetch(url, {credentials: 'include'})。如果返回 401/403/空响应,则从实时请求中复制非浏览器请求头(§2)——复制,切勿猜测值。仅记录请求头名称;切勿打印或保存值。
  5. 在页面内部进行后台分页(§2):window.__x = {running, pages, error},请求间隔 1.5 秒,失败重试,通过简短 evaluate 轮询。每个响应:如果它是登录页/验证码页面(URL 包含 signin/captcha,或返回的是 HTML 而不是预期的 JSON),设置 error 并停止——这些通常返回 200 状态码。
  6. 在导航前保存(§3)。任何 goto/重新加载都会清除 window。使用带绝对 filename 路径的 browser_evaluate,返回一个对象(JSON.stringify 会双重编码)。每个文件约 5 MB 即可;超过此大小则按批次拆分。
  7. 已签名/不可重放的请求(请求签名头、nonce 请求体、拒绝编辑的持久化查询):访问每个详情页面并被动捕获其响应(§4)。
  8. 构建 + 验证(见下文)——在数据目录外编写解析脚本,然后编写分析笔记。如果已有仓库布局(例如 tools/<服务>/build_db.py,notes 位于数据旁边),则遵循它;否则询问。

只读。 仅重放页面自身请求用于显示数据的请求。GraphQL:通过 operation(query/Get*/List*)判断,绝不使用 mutation。绝不重新排序、取消、评分、归档、删除。

验证——请全部执行

检查项原因
分页因游标/列表耗尽而结束,而非错误或登录重定向静默截断
在末尾查找“在应用中查看更早订单”文本Web 视图限制历史记录(Swiggy:约 11 个月)
不要仅相信站点计数端点或请求头Blinkit 显示 40;实际列表有 83 条
各行组件之和等于总计(商品 + 费用 − 折扣 = 已付)捕获解析漂移;如果站点对旧记录省略了某些行,请说明——不要强行补足
商品价格之和等于商品总计单价 vs 行总计混淆
唯一 ID;对完全重复条目去重导出和收据会重复列出
通过 ID 与另一个来源交叉检查(导出、收据)证明覆盖率
每个列表/标签/筛选条件都已覆盖(已归档、已取消、其他年份、子服务)“全部订单”通常跨越多个列表

解析说明

  • 服务端驱动 UI 的 API(snippets、widgets、widget_type、layout):按顺序遍历 widgets,收集每个 widget 的 text 字段,根据已知标签进行映射。单个文本的 widget 通常是下一个 widget 的标签——将标签名称列入白名单,否则每个字段都会偏移。
  • 金额可能以分/分为单位;“免费”= 0;前导“-”= 折扣;去除货币符号和印度逗号分组。保持货币分开。
  • 时间戳:购买→用户时区;行程/旅行→记录本身的本地时间。
  • 将原始文件按日期命名(orders-raw-YYYY-MM-DD.json),放在构建的 SQLite 旁边。

Git

仅提交:gitignore 行、解析脚本、任何 README/索引行。原始文件和 SQLite 保留在本地。显式暂存路径(绝不在脏状态下执行 git add -A);仅在要求时提交。

常见错误

  • 一个长时间同步的 evaluate 循环——超时;改为后台运行并轮询。
  • 将批量数据返回聊天而非写入 filename。
  • snippet 监听器保持挂载——使用 page.off 移除,否则重复运行会堆叠处理程序。
  • 在仅 HTML 渲染的站点上仅过滤 xhr/fetch 发现方式,并得出“没有数据源”的结论。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相关技能