- https://play.google.com/store/account/orderhistory?hl=ja&gl=US を開く
- すべて読み込む(一番下までスクロールする)
- スクリプトを修正する(わからない場合は使わないでください)
- 実行する
- 日本円で購入している前提で作っています
throw new Error("コードを読んでから実行してください。"); | |
const purchases = [...document.querySelectorAll(".U6fuTe")]; | |
const summarizedPurchases = purchases | |
.filter(purchase => !purchase.textContent.includes("キャンセルしました")) | |
.map(purchase => { | |
const imgSrc = purchase.querySelector(".RqCJic img")?.src; | |
const priceText = purchase.querySelector(".mshXob")?.textContent || ""; | |
const itemName = purchase.querySelector(".XqqpEd")?.textContent || "Unknown"; | |
return { | |
imgSrc, | |
priceText, | |
itemName | |
}; | |
}) | |
.filter(({ imgSrc, priceText }) => imgSrc && !["$0.00", "¥0"].includes(priceText)) | |
.reduce((acc, { imgSrc, priceText, itemName }) => { | |
const existingItem = acc.find(item => item.key === imgSrc); | |
const isYen = priceText.startsWith("¥"); | |
const amount = isYen ? parseInt(priceText.slice(1).replace(",", ""), 10) : priceText; | |
if (!existingItem) { | |
acc.push({ | |
key: imgSrc, | |
name: [itemName], | |
total: isYen ? amount : 0, | |
otherCurrencies: isYen ? [] : [amount] | |
}); | |
} else { | |
existingItem.name.push(itemName); | |
if (typeof amount === "number") { | |
existingItem.total += amount; | |
} else { | |
existingItem.otherCurrencies.push(amount); | |
} | |
} | |
return acc; | |
}, []); | |
summarizedPurchases.sort((a, b) => a.total - b.total); | |
const enhancedSummary = await Promise.all( | |
summarizedPurchases.map(async item => { | |
const iconBase64 = await fetch(`https://wsrv.nl/?url=${item.key}&encoding=base64`).then(res => res.text()); | |
return { iconBase64, ...item }; | |
}) | |
); | |
console.log("処理中です (アイコン取得中)..."); | |
enhancedSummary.forEach(({ iconBase64, total, otherCurrencies, name }) => { | |
const tab = " "; | |
const displayPrice = `¥${total.toLocaleString()}` + (otherCurrencies.length ? ` + (${otherCurrencies.join(", ")})` : ""); | |
const groupedNames = name.reduce((acc, n) => { | |
acc[n] = (acc[n] || 0) + 1; | |
return acc; | |
}, {}); | |
const itemNameList = Object.entries(groupedNames).map(([n, count]) => `${tab.repeat(3)}${count} ×「${n}」`).join("\n"); | |
const iconCSS = `line-height:0;padding:24px;background:url(${iconBase64}) no-repeat;`; | |
const namesCSS = `line-height:1;`; | |
console.log(`%c${tab}%c${displayPrice}\n${itemNameList}`, iconCSS, namesCSS); | |
}); |