新闻详情

新闻详情

首页 / 资讯中心 / 详情

拼多多订单数据导出 CSV 实战:接口分页、字段平铺与 5 个数据坑,多多开票助手

发布时间:2026/10/2 12:32:21来源:尧图网络
拼多多订单数据导出 CSV 实战:接口分页、字段平铺与 5 个数据坑,多多开票助手
这篇讲的是导出之前那一段我在做一个浏览器扩展处理拼多多电商买家侧的订单和发票订单导出 CSV 是其中一块功能名字叫多多开票助手duoduoke.net。这一篇不聊 CSV 格式本身的毛病编码、科学计数法、逗号转义那些是另一个话题。这里只讲前面那一段也是很多人以为最简单、实际最容易翻车的地方这些数据从哪来怎么变成表格里的一行。写完之后我的感受是收尾那一步拼字符串、触发保存大概二十行就写完了前面取数和清洗的部分写了十几倍。数据别从页面上抠从接口拿第一版我试过从 DOM 里读。订单列表就在页面上一张卡片对应一单取它的文本和链接就行。跑起来才发现拿不全。这种列表是懒加载加分页的往下滚才把后面的渲染出来为了省内存滚过去的部分又会被回收。你从 DOM 里能读到的永远只有当前视口附近那几条。想靠“一直滚到底”来收集中间还会碰上重新渲染前面已经取到的节点变成悬空引用textContent拿回来一个空字符串。我的做法是绕开 DOM直接读页面请求订单列表用的那个接口返回的 JSON。判断依据很简单DOM 结构会随改版变接口的字段名相对稳定而且一次能拿到一整页。const resp await chrome.runtime.sendMessage({ action: FETCH_ORDERS, data: { order_type: all, offset: } }); const orders resp?.data?.orders || []; const hasMore resp?.data?.hasMore;这里要做一次中转不能让内容脚本直接发这个请求。一是跨域和站点上下文的问题二是所有请求收在同一个入口后面加统一的重试和错误处理方便。代价是多定义一个消息类型多一层转发。翻页的逻辑不难难的是两个数不是一个数接口是游标分页一页五十条返回里带一个 offset 指向下一页。看起来就是个 while 循环。第一个坑在这里你要的是一段时间范围内的单接口给的是“最近 N 条”所以每一页拿回来之后还要按时间筛一遍筛掉的直接丢。于是会出现一种很别扭的情况翻了三页一共一百五十条原始数据真正进到结果里的只有十二单。这两个数必须分开记。我一开始用一个计数器结果进度显示是错的明明还在往下翻界面已经报了一百多条而且“翻完了”这个判断也提前触发了。state.rawScannedCount page.length; // 一共翻过多少条原始数据 state.loadedCount usable.length; // 其中多少条进了结果 state.offset resp.data.offset; // 下一页游标 state.hasMore resp.data.hasMore;第二个坑是中断。几百单翻到一半页面刷新了或者用户自己点了别的按钮这一轮就断在这里。重新点一次查询又从第一页开始前面翻的全白翻。翻页要串行别并发游标分页和 page 参数分页不一样offset 是有状态的返回的下一页游标只有在你确实拿到这一页之后才是有效的。所以我不并发一页一页串着请求。试过一次并发三页结果两页的数据有重叠还有几条直接跳过去了。原因在于服务端那边会把当前进度往前推哪个请求先回来并不确定后回来的那一页已经不是你发请求时的位置了。串行的代价是慢一点。一页五十条几百单就是十几次请求多花的那几秒比事后去重和排错省事。中断之后接着跑靠的是首页指纹断点续跑本身不复杂把当前游标和时间范围存下来下次先读它对得上就从那儿接着走。麻烦在“对得上”这三个字。用户中间又下了两单订单列表顺序就变了上次存的那个游标指向的位置已经不是你离开的地方。硬接着跑要么漏要么重。我的做法是给第一页算一个指纹把订单号拼起来取个值。续跑之前先请求一次第一页指纹一致才按断点走不一致就把整份断点丢掉从头开始。const fingerprint orders.slice(0, 3).map(o o.order_sn).join(|); if (saved.fingerprint ! fingerprint) return null; // 数据变了断点作废只取前三单算指纹是有意的。全量算要遍历一遍而订单列表的排序基本由最新的几单决定前三单足够反映变化。这是个取舍没有标准答案。嵌套结构平铺成一行数组、缺值、算出来的字段接口返回的是嵌套 JSONCSV 要的是一行一条记录中间得平铺。三个具体的点。物流轨迹是个数组每项是{ time, info }。我要把它塞进一个单元格做法是拼成多行文本const trace (o.express_traces || []) .map(t [t.time, t.info].filter(Boolean).join( )) .join(\n);这里要留神拼完之后这个字段里是有换行的。CSV 一行一条记录字段内部的换行必须用双引号包住不包就会被当成三条记录读。所以平铺和转义的调用顺序不能反反了这份文件直接是坏的。第二个是缺值。接口没给的字段是 null 或 undefined直接塞进去表里就会出现字符串 “null”。我统一兜了一层但要分两种给人看的列填「未知」给脚本读的列留空字符串。区别在于脚本拿到「未知」还得再判断一次留空可以直接按没值处理。第三个是算出来的字段。表里有一列叫「单价」这个值接口不给是拿实付金额除以数量算的const qty o.quantity || 1; const unitPrice qty 0 ? (o.amount || 0) / qty : 0;数量为 0 的情况一定要挡。不挡会得到 Infinity写进表里就是一个谁也不知道怎么来的字符串。用字段名取别用下标平铺的时候容易图省事写成一组位置映射或者更省事的Object.values(o)直接摊开。这两种写法在接口加字段、调字段顺序的时候会直接错位值都还在但串行了而且不报错。我的写法是每个值都明确写出取的是哪个字段哪怕啰嗦const row [ orderNo(o), // 订单号 formatTime(o.order_time), // 下单时间 money(o.amount), // 实付金额 ];多写这三行等哪天接口多返回一个字段这份表还是对的。同一个语义接口给了两个字段订单的最新物流状态接口里有两个地方都有一个是直接给的logistics_status另一个藏在extra_info.order_hint.message里。哪个有值用哪个。这种同义字段并存的情况在电商类接口里很常见通常是不同业务线各自加的。写死只取一个等接口一改就取不到值整列空白。所以我写成回退链const lastTrace o.logistics_status || o.last_trace || ;代价要说清楚。这么写之后“为什么这行有物流状态、那行没有”就不好解释了值的来源不固定。这个代价我接受对“有没有最新状态”这件事来说有值比来源统一更重要。导出之前还剩两件事到这一步数据已经平了剩下的就是拼字符串和触发保存。有两件小事还是提一下。一是金额的单位。我这边接口给的直接是元所以要处理的只是保留两位小数。这不是通行规则接别的平台之前先确认它给的金额是元还是分。这一处错了整张表的金额全是错的而且数值看起来很正常不容易第一时间发现。二是时间的格式。同一个接口里下单时间和支付时间有可能是时间戳也有可能已经是格式化好的字符串。统一在平铺这一层转好别让两种格式混进同一列不然下游一做排序就乱。小结拼多多订单导出 CSV表格收尾那步拼字符串、建Blob、触发保存确实只要二十来行。真正的工作量在前面从哪个数据源取、怎么翻页、断点怎么接、嵌套怎么平、缺值怎么兜。这几件事没有一件是难的但它们有个共同点出问题的时候不报错只是表里的数据悄悄不对。等你发现往往已经拿着这份表做完对账了。关键词订单数据导出, CSV 导出, 接口分页, 浏览器扩展, 数据处理
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

用Go语言自建个人网盘:Cloudreve云存储接入与部署实战 2026/10/2 14:11:40

用Go语言自建个人网盘:Cloudreve云存储接入与部署实战

简介:Cloudreve个人网盘系统源码是一套基于Go语言打造的开源免费网盘项目,面向需要自建云盘的个人开发者、中小企业及对数据隐私要求较高的用户,可解决商业网盘限速、涨价和文件管控不便等问题。项目后端采用GoGin,前端使用ReactR…

阅读更多 →
JSP+Servlet+JDBC+MySQL共享租车系统完整开发实践 2026/10/2 14:11:39

JSP+Servlet+JDBC+MySQL共享租车系统完整开发实践

最近接手维护一个老牌的课程设计项目——基于 JSP Servlet JDBC MySQL 的共享租车信息管理系统,技术栈一看就是典型的 JavaWeb 教学案例:没有 Spring、没有 MyBatis,甚至连 Maven 都没用,就是最原始的 Java JSP Servlet JDB…

阅读更多 →
缠论交易的Python工程化:基于Backtrader的量化回测实战 2026/10/2 14:11:38

缠论交易的Python工程化:基于Backtrader的量化回测实战

简介:这是一套基于Python与Backtrader框架实现的缠论交易系统源码,适合熟悉Python、对量化交易与缠论技术分析感兴趣的开发者研究学习。系统将缠论中的分型、笔、线段、中枢等规则转化为可执行策略,覆盖数据处理、信号生成、回测与接口对接等…

阅读更多 →
VMware虚拟机安装Ubuntu屏幕太小?教你解决下一步按钮看不见的问题 2026/10/2 14:11:37

VMware虚拟机安装Ubuntu屏幕太小?教你解决下一步按钮看不见的问题

你在VMware里新建了一台Ubuntu虚拟机,镜像也加载好了,点开电源准备一路Next装完收工。结果进到安装界面就傻眼:窗口比屏幕还大,鼠标滑到边角就停住,那个“下一步”按钮死活看不见,跟躲在屏幕外头似的。这问…

阅读更多 →
数组基础与二分查找双指针实战:从连续存储到O(1)随机访问 2026/10/2 14:11:37

数组基础与二分查找双指针实战:从连续存储到O(1)随机访问

今天是代码随想录算法训练营的 Day01,主题是数组 part01。说实话,数组这个知识点我自认为早就“会了”,但真跟着训练营重新过一遍,才发现从前很多理解都是浮在表面——比如为什么数组的增删是 O(n) 但查询是 O(1)?为什…

阅读更多 →
从“过境免签”开题开始:移民管理论文的 AI 工具选择清单 [特殊字符] 2026/10/2 14:11:29

从“过境免签”开题开始:移民管理论文的 AI 工具选择清单 [特殊字符]

移民管理专业的同学,大概都懂一种“跨界的痛”:我们写的不是单纯的法学论文,也不是只讲流程的行政报告,而是要在出入境便利化、移民服务、口岸安全、涉外执法、身份与签证管理之间找平衡。 比如一个很典型的毕业论文任务&#xff…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉