京东网页批量删除订单
背景
电商平台订单中心往往会积累大量历史订单,其中不少包含收件人姓名、电话、地址等隐私信息。平台自带的删除入口只能逐条点击,遇到几十甚至上百条订单时效率极低。本文介绍一种通过浏览器控制台脚本实现先扫描、后删除的两步法,既安全又高效。
核心思路是:第一步只读取页面文本并解析出订单号、收件人、商品、金额等关键字段,以表格形式展示供你核对;第二步根据你指定的关键字(如收件人姓名)逐条匹配、弹窗确认后再执行删除,避免误操作。
前置准备
在电脑端浏览器登录电商平台的订单中心页面
按 F12 打开开发者工具,切换到 Console(控制台)面板
确保当前页面已加载出订单列表(滚动一遍让所有订单渲染完毕)
安全原则
第一步脚本只读取页面文本,不执行任何删除或点击操作
第二步脚本每个订单都会弹出 confirm 确认框,你逐个点"确定"才删,随时可点"取消"中止
所有操作在本地浏览器完成,不发送任何外部请求
第一步:扫描当前页订单(只读)
在控制台粘贴以下脚本并回车。它会从页面正文中按时间戳切分订单块,提取订单号、收件人、商品名称、金额、状态等信息,以表格形式输出。
(() => {
const PROV = '北京|上海|天津|重庆|河北|山西|内蒙古|辽宁|吉林|黑龙江|江苏|浙江|安徽|福建|江西|山东|河南|湖北|湖南|广东|广西|海南|四川|贵州|云南|西藏|陕西|甘肃|青海|宁夏|新疆|香港|澳门|台湾';
const text = document.body.innerText;
const chunks = text.split(/(?=\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})/)
.filter(c => c.trim().length > 50);
const orders = chunks.map((c, i) => {
const orderId = (c.match(/\b(\d{15,16})\b/) || [])[1] || '未知';
const recv = (c.match(new RegExp(
'([\\\\u4e00-\\\\u9fa5]{2,4})(?=(?:' + PROV + '))'
)) || [])[1] || '未知';
const goods = (c.match(/[^\\n]*【[^\\n]*/g) || [])
.map(s => s.trim()).filter(s => s.length > 4)
.slice(0, 2).join(' / ') || '未知';
const amt = (c.match(/¥\s*([\d.]+)/) || [])[1] || '?';
const status = (c.match(/(已完成|已取消|等待收货|待付款|待评价)/) || [])[1] || '?';
const canDelete = c.includes('删除订单') ? '是' : '否';
return { 序号: i + 1, 订单号: orderId, 收件人: recv,
商品: goods.slice(0, 40), 金额: '¥' + amt,
状态: status, 可删除: canDelete };
});
console.log('📄 本页共解析出 ' + orders.length + ' 个订单');
console.table(orders);
const summary = {};
orders.forEach(o => summary[o.收件人] = (summary[o.收件人] || 0) + 1);
console.log('👥 收件人汇总:', summary);
window.__orders = orders;
console.log('💡 已缓存到 window.__orders');
return orders;
})();运行后控制台会输出一个表格,形如:
| 序号 | 订单号 | 收件人 | 商品 | 金额 | 状态 | 可删除 |
|---|---|---|---|---|---|---|
| 1 | 361XXXXXXX042696 | 收件人A | 某餐饮店【套餐A】 | ¥12.90 | 已完成 | 是 |
| 2 | 360XXXXXXX218661 | 收件人A | 某咖啡店【招牌咖啡】 | ¥8.45 | 已完成 | 是 |
| 3 | 361XXXXXXX550449 | 收件人B | 某矿泉水【整箱装】 | ¥33.00 | 等待收货 | 否 |
同时会输出收件人汇总,例如:收件人A 7个、收件人B 11个、收件人C 1个、未知 4个。此时你只需确认:要删除哪个收件人(或关键字)的订单。
如果扫描结果大量显示"未知",说明页面 DOM 结构与预期不符。常见原因是订单容器选择器不匹配,需要改用页面正文按时间戳切分的方式(即上方脚本的逻辑)。
第二步:按条件确认删除
确认第一步扫描结果无误后,修改脚本中的 KEYWORD 变量为目标关键字(如收件人姓名),粘贴到控制台运行。脚本会逐个查找匹配的订单,每个订单都会弹出确认框,你点"确定"才删除,点"取消"即停止。
(async () => {
const KEYWORD = '收件人A';
const sleep = ms => new Promise(r => setTimeout(r, ms));
const findOrderId = (el) => {
let node = el;
for (let up = 0; up < 10 && node; up++) {
const m = (node.innerText || '').match(/\b(\d{15,16})\b/);
if (m) return { id: m[1], container: node };
node = node.parentElement;
}
return null;
};
let deleted = 0, skipped = 0;
for (let round = 1; round <= 15; round++) {
const leaves = [...document.querySelectorAll('*')]
.filter(el => el.children.length === 0
&& (el.textContent || '').trim() === '删除订单');
const seen = new Set();
const targets = [];
for (const el of leaves) {
const info = findOrderId(el);
if (!info || seen.has(info.id)) continue;
seen.add(info.id);
targets.push({ ...info, el });
}
const match = targets.find(t =>
t.container.innerText.includes(KEYWORD));
if (!match) {
console.log('第' + round + '轮:没有匹配的订单了');
break;
}
const ok = confirm('确认删除?\n订单号:' + match.id
+ '\n' + match.container.innerText.split('\n')
.slice(0, 8).join('\n'));
if (!ok) { skipped++; break; }
match.el.click();
await sleep(800);
const confirmBtn = [...document.querySelectorAll('*')]
.find(el => el.children.length === 0
&& ['确定', '确认'].includes(
(el.textContent || '').trim())
&& el.offsetParent !== null);
if (confirmBtn) {
confirmBtn.click(); deleted++;
console.log('🗑️ 已删除 ' + match.id);
} else {
console.log('⚠️ ' + match.id + ' 请手动检查');
}
await sleep(1500);
}
console.log('✅ 完成:删除' + deleted + '个,跳过' + skipped + '个');
})();这版脚本的关键设计:
全标签搜索:用
querySelectorAll('*')遍历所有叶子节点,不限标签类型,适配各平台不同的 DOM 结构每轮重新查询:删除一个订单后页面会重渲染(如使用 React),旧 DOM 引用会失效,所以每轮都重新查找
逐条确认:每个订单删除前都弹 confirm,你随时可点"取消"中止
自动处理确认弹窗:点击"删除订单"后,脚本自动查找并点击弹窗中的"确定/确认"按钮
常见问题排查
扫描结果全是"未知"
最常见的原因是页面 DOM 结构与预期不符。早期的尝试用 .order-item 等选择器查找订单容器,但很多平台的订单容器 class 名称并非如此,导致兜底成了"整个 body 当 1 个订单",正则就乱匹配了。
解决方案:改用从页面正文 document.body.innerText 按时间戳切分的方式。大多数平台的订单都以"YYYY-MM-DD HH:MM:SS"格式的时间开头,按此正则切分可靠性最高。
找不到"删除订单"按钮
脚本提示"找到 0 个可删除订单",但页面上明明有删除按钮。原因是删除按钮的文字可能不在 a、span、button 标签上,而是在 div 或其他元素中。
解决方案:用 querySelectorAll('*') 遍历所有叶子节点,按 textContent 精确匹配"删除订单"四个字,不限标签类型。
(() => {
const all = [...document.querySelectorAll('*')];
const hits = [];
all.forEach(el => {
if (el.children.length > 0) return;
const t = (el.textContent || '').trim();
if (t.includes('删除')) {
hits.push({
text: t, tag: el.tagName,
cls: (el.className || '').toString().slice(0, 60),
visible: el.offsetParent !== null
});
}
});
console.log('找到 ' + hits.length + ' 个含"删除"的叶子元素');
console.log(hits.slice(0, 40));
return hits;
})();重点看两个信息:visible 是否为 true(false 说明按钮在折叠或懒加载区域,需先滚动页面);tag 和 cls 是什么(用于确认选择器策略)。
如果全是 visible: false,先跑滚动加载再试:
(async () => {
for (let i = 0; i < 10; i++) {
window.scrollBy(0, 800);
await new Promise(r => setTimeout(r, 400));
}
window.scrollTo(0, 0);
console.log('滚动完成,重新尝试删除脚本');
})();删除时提示 0 个匹配
扫描阶段能解析出订单,但删除脚本却找不到匹配。这通常是因为删除脚本用 a, span, button 选择器找不到按钮(文字在别的标签上),或者按钮文字不是"删除订单"而是"删除"等。
解决方案:先跑上方诊断脚本确认按钮的真实标签和文字,然后用 * 全标签匹配。如果按钮文字被拆成多个节点(如"删除订"+“单”),需要改用拼接文本匹配。
注意事项
多页订单需手动翻页:脚本只处理当前页已加载的订单,翻页是整页跳转,脚本无法自动跨页。每页跑完第一步扫描和第二步删除后,手动点下一页再重复
待付款和等待收货的订单无法删除:平台只允许删除"已完成"或"已取消"的订单,脚本中的
canDelete字段会标注"是/否"不同平台 DOM 结构不同:本文脚本基于正文文本解析,通用性较高,但选择器、正则可能需要根据实际平台微调
删除不可恢复:订单删除后无法找回,建议先用少量订单测试,确认脚本行为符合预期后再批量操作
注意风控:脚本中设置了 800ms~1500ms 的操作间隔,避免过快触发平台风控。如遇到异常可适当增大延迟