Skip to content

Instantly share code, notes, and snippets.

@eai04191
Last active September 7, 2023 18:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eai04191/b65f555d1bbb478521538137fbaae8ba to your computer and use it in GitHub Desktop.
Save eai04191/b65f555d1bbb478521538137fbaae8ba to your computer and use it in GitHub Desktop.
Google Playの注文履歴ページをパースしてアプリごとの課金額を見るやつ

Google Playの注文履歴ページをパースしてアプリごとの課金額を見るやつ

image

使い方

  1. https://play.google.com/store/account/orderhistory?hl=ja&gl=US を開く
  2. すべて読み込む(一番下までスクロールする)
  3. スクリプトを修正する(わからない場合は使わないでください)
  4. 実行する

note

  • 日本円で購入している前提で作っています
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);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment