Update data 9/25-9/27; detect data sources by content
The consumption export keeps changing filename (每日数据 -> Week39...), which broke the glob each time. build_data.py now treats any workbook containing a 平台消耗统计 sheet as a data source and orders them by the latest date they contain, so the fresher file wins on overlapping days. 2026Week39平台消耗.xlsx covers 8/31-9/27 and fully supersedes the 2609 file, which is removed; 2608 stays for the earlier August dates. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
Binary file not shown.
+16
-6
@@ -8,12 +8,14 @@
|
||||
import openpyxl, collections, json, datetime, os, sys, glob
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
# 源文件按月滚动(2608 -> 2609 -> ...)。全部读进来合并:
|
||||
# 同一天出现在多个文件时,以文件名较新的为准(源表会修订历史数据)。
|
||||
SRC_FILES = sorted(glob.glob(os.path.join(HERE, '*每日数据-武汉萌奇熊.xlsx')))
|
||||
# 花名册 投手.xlsx 单独处理,不参与消耗数据合并
|
||||
# 消耗数据源:不认文件名(每月/每周导出的命名一直在变),改为认内容——
|
||||
# 仓库里任何带「平台消耗统计」sheet 的 xlsx 都算数据源。花名册 roster.xlsx
|
||||
# 没有该 sheet,自然被排除。同一天出现在多个文件时,以数据更新的那份为准
|
||||
# (见下方按最大日期排序),因为源表会修订历史数据。
|
||||
SRC_FILES = [f for f in sorted(glob.glob(os.path.join(HERE, '*.xlsx')))
|
||||
if '平台消耗统计' in openpyxl.load_workbook(f, read_only=True).sheetnames]
|
||||
if not SRC_FILES:
|
||||
sys.exit('ERROR: 仓库里找不到 *每日数据-武汉萌奇熊.xlsx')
|
||||
sys.exit('ERROR: 仓库里没有任何含「平台消耗统计」sheet 的 xlsx')
|
||||
_cfg = json.load(open(os.path.join(HERE, 'exclude.json')))
|
||||
EXCL = set(_cfg['packages']) # 按包名剔除
|
||||
EXCL_ADP = set(_cfg.get('adpings', {})) # 按 Adpingid 剔除
|
||||
@@ -27,6 +29,14 @@ def key(v):
|
||||
|
||||
books = [(f, openpyxl.load_workbook(f, data_only=True)) for f in SRC_FILES]
|
||||
|
||||
def _max_date(wb_):
|
||||
ds = [r[1].date() for r in wb_['平台消耗统计'].iter_rows(min_row=2, values_only=True)
|
||||
if isinstance(r[1], datetime.datetime)]
|
||||
return max(ds) if ds else datetime.date.min
|
||||
|
||||
# 按数据最大日期排序:日期更靠后的文件视为更新,其数据覆盖同一天的旧值
|
||||
books.sort(key=lambda fb: (_max_date(fb[1]), fb[0]))
|
||||
|
||||
# --- 投手花名册 ---
|
||||
# 优先用独立的 投手.xlsx(月度数据文件已不再带「投手」sheet);
|
||||
# 没有它时退回到最新一个仍带该 sheet 的月度文件。
|
||||
@@ -193,7 +203,7 @@ data = {
|
||||
}
|
||||
json.dump(data, open(os.path.join(HERE, 'data.json'), 'w'), ensure_ascii=False, indent=2)
|
||||
|
||||
print('源文件:', ', '.join(os.path.basename(f) for f in SRC_FILES))
|
||||
print('源文件(按数据新旧):', ' -> '.join(os.path.basename(f) for f, _ in books))
|
||||
print('投手表取自:', os.path.basename(roster_file))
|
||||
if extra_used:
|
||||
print('roster_extra 补充生效:', ', '.join(f'{a}->{amap[a]}' for a in extra_used))
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"meta": {
|
||||
"week": "Last 3 Days: 9/15-9/17",
|
||||
"week": "Last 3 Days: 9/25-9/27",
|
||||
"source": "萌奇熊日报",
|
||||
"generated_at": "2026-09-28",
|
||||
"date_range": "2026/09/15-2026/09/17",
|
||||
"prev_range": "2026/09/12-2026/09/14",
|
||||
"date_range": "2026/09/25-2026/09/27",
|
||||
"prev_range": "2026/09/22-2026/09/24",
|
||||
"note": "投放人以「投手」表 Media Buyer 列为准,@某某 已与某某合并计算;未填写投放人的 Adpingid 不计入;exclude.json 所列包名已排除。Package 后缀为该 Package 花费最高的投放地区,Adpingid 为该地区内花费最高的 Adping。"
|
||||
},
|
||||
"grand_total": 12748.9417,
|
||||
"week34_id_count": 147,
|
||||
"grand_total": 16775.4769,
|
||||
"week34_id_count": 141,
|
||||
"buyers": [
|
||||
{
|
||||
"name": "黄政",
|
||||
"@name": "黄政",
|
||||
"total": 3513.1061,
|
||||
"prev_total": 3815.0938,
|
||||
"active_ids": 38,
|
||||
"total": 5639.9505,
|
||||
"prev_total": 4673.4343,
|
||||
"active_ids": 35,
|
||||
"owned_ids": 159,
|
||||
"pkgs": [
|
||||
{
|
||||
@@ -23,89 +23,44 @@
|
||||
"geo": "BR",
|
||||
"label": "com.amazon.mShop.android.shopping_BR",
|
||||
"adping": "11892329",
|
||||
"spend": 1608.3855
|
||||
"spend": 3432.6436
|
||||
},
|
||||
{
|
||||
"pkg": "com.king.candycrushsodasaga",
|
||||
"geo": "BR",
|
||||
"label": "com.king.candycrushsodasaga_BR",
|
||||
"adping": "8460883",
|
||||
"spend": 703.74
|
||||
"geo": "DE",
|
||||
"label": "com.king.candycrushsodasaga_DE",
|
||||
"adping": "6951594",
|
||||
"spend": 1000.246
|
||||
},
|
||||
{
|
||||
"pkg": "com.yandex.lavka",
|
||||
"geo": "RU",
|
||||
"label": "com.yandex.lavka_RU",
|
||||
"adping": "8156506",
|
||||
"spend": 465.2049
|
||||
"spend": 442.1183
|
||||
},
|
||||
{
|
||||
"pkg": "tech.jm",
|
||||
"geo": "RU",
|
||||
"label": "tech.jm_RU",
|
||||
"adping": "1745925",
|
||||
"spend": 268.4248
|
||||
"spend": 188.43
|
||||
},
|
||||
{
|
||||
"pkg": "com.king.candycrushsaga",
|
||||
"geo": "VN",
|
||||
"label": "com.king.candycrushsaga_VN",
|
||||
"adping": "91560709",
|
||||
"spend": 189.3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "万科",
|
||||
"@name": "万科",
|
||||
"total": 2669.4344,
|
||||
"prev_total": 2425.9647,
|
||||
"active_ids": 24,
|
||||
"owned_ids": 116,
|
||||
"pkgs": [
|
||||
{
|
||||
"pkg": "com.king.candycrushsaga",
|
||||
"geo": "TH",
|
||||
"label": "com.king.candycrushsaga_TH",
|
||||
"adping": "5497580",
|
||||
"spend": 1262.743
|
||||
},
|
||||
{
|
||||
"pkg": "ru.aliexpress.buyer",
|
||||
"geo": "RU",
|
||||
"label": "ru.aliexpress.buyer_RU",
|
||||
"adping": "6607117",
|
||||
"spend": 950.656
|
||||
},
|
||||
{
|
||||
"pkg": "com.uma.musicvk",
|
||||
"geo": "RU",
|
||||
"label": "com.uma.musicvk_RU",
|
||||
"adping": "2783561",
|
||||
"spend": 163.46
|
||||
},
|
||||
{
|
||||
"pkg": "ru.kinopoisk",
|
||||
"geo": "RU",
|
||||
"label": "ru.kinopoisk_RU",
|
||||
"adping": "10599681",
|
||||
"spend": 120.25
|
||||
},
|
||||
{
|
||||
"pkg": "com.edadeal.android",
|
||||
"geo": "RU",
|
||||
"label": "com.edadeal.android_RU",
|
||||
"adping": "10599157",
|
||||
"spend": 92.75
|
||||
"spend": 166.38
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "谭超",
|
||||
"@name": "谭超",
|
||||
"total": 2482.8178,
|
||||
"prev_total": 3111.69,
|
||||
"active_ids": 30,
|
||||
"total": 3363.9219,
|
||||
"prev_total": 2925.7038,
|
||||
"active_ids": 26,
|
||||
"owned_ids": 140,
|
||||
"pkgs": [
|
||||
{
|
||||
@@ -113,97 +68,59 @@
|
||||
"geo": "ID",
|
||||
"label": "com.kwai.bulldog_ID",
|
||||
"adping": "7815836",
|
||||
"spend": 857.19
|
||||
"spend": 1735.59
|
||||
},
|
||||
{
|
||||
"pkg": "astrum.ent.m2alyona",
|
||||
"geo": "RU",
|
||||
"label": "astrum.ent.m2alyona_RU",
|
||||
"adping": "11690181",
|
||||
"spend": 550.0
|
||||
"spend": 553.2
|
||||
},
|
||||
{
|
||||
"pkg": "asrtum.ent.domovyata",
|
||||
"geo": "RU",
|
||||
"label": "asrtum.ent.domovyata_RU",
|
||||
"adping": "8628042",
|
||||
"spend": 431.26
|
||||
"spend": 405.3
|
||||
},
|
||||
{
|
||||
"pkg": "com.vitastudio.mahjong",
|
||||
"geo": "ID",
|
||||
"label": "com.vitastudio.mahjong_ID",
|
||||
"adping": "91467820",
|
||||
"spend": 337.77
|
||||
"spend": 283.21
|
||||
},
|
||||
{
|
||||
"pkg": "tech.jm",
|
||||
"geo": "RU",
|
||||
"label": "tech.jm_RU",
|
||||
"adping": "9297014",
|
||||
"spend": 149.96
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "詹涵粤",
|
||||
"@name": "詹涵粤",
|
||||
"total": 2130.5011,
|
||||
"prev_total": 1993.0092,
|
||||
"active_ids": 26,
|
||||
"owned_ids": 174,
|
||||
"pkgs": [
|
||||
{
|
||||
"pkg": "com.king.candycrushsaga",
|
||||
"geo": "MY",
|
||||
"label": "com.king.candycrushsaga_MY",
|
||||
"adping": "5464039",
|
||||
"spend": 1353.552
|
||||
},
|
||||
{
|
||||
"pkg": "com.gloriajeans.mobile",
|
||||
"geo": "RU",
|
||||
"label": "com.gloriajeans.mobile_RU",
|
||||
"adping": "9333145",
|
||||
"spend": 161.42
|
||||
},
|
||||
{
|
||||
"pkg": "com.esprit.rpg.lttlefirykng",
|
||||
"geo": "RU",
|
||||
"label": "com.esprit.rpg.lttlefirykng_RU",
|
||||
"adping": "10514860",
|
||||
"spend": 158.0
|
||||
},
|
||||
{
|
||||
"pkg": "ru.kinopoisk",
|
||||
"geo": "RU",
|
||||
"label": "ru.kinopoisk_RU",
|
||||
"adping": "91399821",
|
||||
"spend": 138.31
|
||||
},
|
||||
{
|
||||
"pkg": "com.game.friends.ru",
|
||||
"geo": "RU",
|
||||
"label": "com.game.friends.ru_RU",
|
||||
"adping": "91564896",
|
||||
"spend": 61.95
|
||||
"pkg": "com.kwai.video",
|
||||
"geo": "BR",
|
||||
"label": "com.kwai.video_BR",
|
||||
"adping": "12336897",
|
||||
"spend": 186.3289
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "周梓君",
|
||||
"@name": "周梓君",
|
||||
"total": 1953.0823,
|
||||
"prev_total": 2083.8794,
|
||||
"active_ids": 29,
|
||||
"total": 2922.2554,
|
||||
"prev_total": 2748.3079,
|
||||
"active_ids": 33,
|
||||
"owned_ids": 127,
|
||||
"pkgs": [
|
||||
{
|
||||
"pkg": "com.yandex.bank",
|
||||
"geo": "RU",
|
||||
"label": "com.yandex.bank_RU",
|
||||
"adping": "11511535",
|
||||
"spend": 1004.5605
|
||||
},
|
||||
{
|
||||
"pkg": "ru.ozon.app.android",
|
||||
"geo": "KZ",
|
||||
"label": "ru.ozon.app.android_KZ",
|
||||
"adping": "5963354",
|
||||
"spend": 623.8061
|
||||
"spend": 715.2492
|
||||
},
|
||||
{
|
||||
"pkg": "ru.kinopoisk",
|
||||
@@ -213,11 +130,11 @@
|
||||
"spend": 607.5
|
||||
},
|
||||
{
|
||||
"pkg": "com.yandex.bank",
|
||||
"pkg": "ru.yandex.music",
|
||||
"geo": "RU",
|
||||
"label": "com.yandex.bank_RU",
|
||||
"adping": "11511535",
|
||||
"spend": 283.774
|
||||
"label": "ru.yandex.music_RU",
|
||||
"adping": "8566541",
|
||||
"spend": 202.58
|
||||
},
|
||||
{
|
||||
"pkg": "com.edadeal.android",
|
||||
@@ -225,13 +142,96 @@
|
||||
"label": "com.edadeal.android_RU",
|
||||
"adping": "6395488",
|
||||
"spend": 180.0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "万科",
|
||||
"@name": "万科",
|
||||
"total": 2755.2147,
|
||||
"prev_total": 2650.2467,
|
||||
"active_ids": 25,
|
||||
"owned_ids": 116,
|
||||
"pkgs": [
|
||||
{
|
||||
"pkg": "com.king.candycrushsaga",
|
||||
"geo": "TH",
|
||||
"label": "com.king.candycrushsaga_TH",
|
||||
"adping": "5497580",
|
||||
"spend": 1328.182
|
||||
},
|
||||
{
|
||||
"pkg": "ru.yandex.music",
|
||||
"pkg": "ru.aliexpress.buyer",
|
||||
"geo": "RU",
|
||||
"label": "ru.yandex.music_RU",
|
||||
"adping": "8566541",
|
||||
"spend": 114.07
|
||||
"label": "ru.aliexpress.buyer_RU",
|
||||
"adping": "6607117",
|
||||
"spend": 720.192
|
||||
},
|
||||
{
|
||||
"pkg": "otello.dgis.ru",
|
||||
"geo": "RU",
|
||||
"label": "otello.dgis.ru_RU",
|
||||
"adping": "12541739",
|
||||
"spend": 180.0
|
||||
},
|
||||
{
|
||||
"pkg": "com.uma.musicvk",
|
||||
"geo": "RU",
|
||||
"label": "com.uma.musicvk_RU",
|
||||
"adping": "2783561",
|
||||
"spend": 169.34
|
||||
},
|
||||
{
|
||||
"pkg": "ru.kinopoisk",
|
||||
"geo": "RU",
|
||||
"label": "ru.kinopoisk_RU",
|
||||
"adping": "10599681",
|
||||
"spend": 128.57
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "詹涵粤",
|
||||
"@name": "詹涵粤",
|
||||
"total": 2094.1344,
|
||||
"prev_total": 2143.4783,
|
||||
"active_ids": 22,
|
||||
"owned_ids": 174,
|
||||
"pkgs": [
|
||||
{
|
||||
"pkg": "com.king.candycrushsaga",
|
||||
"geo": "MY",
|
||||
"label": "com.king.candycrushsaga_MY",
|
||||
"adping": "5464039",
|
||||
"spend": 1204.616
|
||||
},
|
||||
{
|
||||
"pkg": "ru.kinopoisk",
|
||||
"geo": "RU",
|
||||
"label": "ru.kinopoisk_RU",
|
||||
"adping": "91399821",
|
||||
"spend": 170.57
|
||||
},
|
||||
{
|
||||
"pkg": "com.oakever.meowdoku",
|
||||
"geo": "RU",
|
||||
"label": "com.oakever.meowdoku_RU",
|
||||
"adping": "91567363",
|
||||
"spend": 130.85
|
||||
},
|
||||
{
|
||||
"pkg": "com.esprit.rpg.lttlefirykng",
|
||||
"geo": "RU",
|
||||
"label": "com.esprit.rpg.lttlefirykng_RU",
|
||||
"adping": "10514860",
|
||||
"spend": 130.8
|
||||
},
|
||||
{
|
||||
"pkg": "sports.caliente.mx.calientedeportes",
|
||||
"geo": "MX",
|
||||
"label": "sports.caliente.mx.calientedeportes_MX",
|
||||
"adping": "5365721",
|
||||
"spend": 124.5
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user