mdbq 3.8.3__py3-none-any.whl → 3.8.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mdbq/__version__.py +1 -1
- mdbq/aggregation/query_data.py +35 -21
- mdbq/log/spider_logging.py +4 -5
- mdbq/other/download_sku_picture.py +3 -1
- mdbq/redis/getredis.py +2 -1
- mdbq/spider/aikucun.py +20 -7
- {mdbq-3.8.3.dist-info → mdbq-3.8.5.dist-info}/METADATA +1 -1
- {mdbq-3.8.3.dist-info → mdbq-3.8.5.dist-info}/RECORD +10 -11
- mdbq/pbix/refresh_all_old.py +0 -177
- {mdbq-3.8.3.dist-info → mdbq-3.8.5.dist-info}/WHEEL +0 -0
- {mdbq-3.8.3.dist-info → mdbq-3.8.5.dist-info}/top_level.txt +0 -0
mdbq/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
VERSION = '3.8.
|
1
|
+
VERSION = '3.8.5'
|
mdbq/aggregation/query_data.py
CHANGED
@@ -22,7 +22,9 @@ import sys
|
|
22
22
|
|
23
23
|
"""
|
24
24
|
|
25
|
-
|
25
|
+
dir_path = os.path.expanduser("~")
|
26
|
+
config_file = os.path.join(dir_path, 'spd.txt')
|
27
|
+
content = config.read_config(file_path=config_file)
|
26
28
|
username, password, host, port = content['username'], content['password'], content['host'], content['port']
|
27
29
|
m_engine = mysql.MysqlUpload(username=username, password=password, host=host, port=port, charset='utf8mb4')
|
28
30
|
|
@@ -2919,9 +2921,11 @@ class MysqlDatasQuery:
|
|
2919
2921
|
start_date, end_date = self.months_data(num=self.months)
|
2920
2922
|
projection = {
|
2921
2923
|
'日期': 1,
|
2922
|
-
'
|
2924
|
+
'平台': 1,
|
2925
|
+
'店铺名称': 1,
|
2926
|
+
'spuid': 1,
|
2923
2927
|
'商品名称': 1,
|
2924
|
-
'
|
2928
|
+
'品牌名': 1,
|
2925
2929
|
'商品款号': 1,
|
2926
2930
|
'一级类目名称': 1,
|
2927
2931
|
'二级类目名称': 1,
|
@@ -2934,7 +2938,7 @@ class MysqlDatasQuery:
|
|
2934
2938
|
'成交gmv': 1,
|
2935
2939
|
'供货额': 1,
|
2936
2940
|
'供货价': 1,
|
2937
|
-
'销售爱豆人数
|
2941
|
+
'销售爱豆人数': 1,
|
2938
2942
|
'支付人数_交易': 1,
|
2939
2943
|
'支付人数_成交': 1,
|
2940
2944
|
'销售量_成交': 1,
|
@@ -2947,34 +2951,44 @@ class MysqlDatasQuery:
|
|
2947
2951
|
'售罄率': 1,
|
2948
2952
|
'在架sku数': 1,
|
2949
2953
|
'可售sku数': 1,
|
2950
|
-
'sku
|
2951
|
-
'sku
|
2952
|
-
'
|
2953
|
-
'
|
2954
|
-
'店铺名称': 1,
|
2954
|
+
'下单sku': 1,
|
2955
|
+
'成交sku': 1,
|
2956
|
+
'图片': 1,
|
2957
|
+
'更新时间': 1,
|
2955
2958
|
}
|
2956
2959
|
projection = {}
|
2957
2960
|
df = self.download.data_to_df(
|
2958
2961
|
db_name='爱库存2',
|
2959
|
-
table_name='
|
2962
|
+
table_name='spu榜单',
|
2960
2963
|
start_date=start_date,
|
2961
2964
|
end_date=end_date,
|
2962
2965
|
projection=projection,
|
2963
2966
|
)
|
2964
|
-
df.
|
2965
|
-
|
2966
|
-
|
2967
|
-
|
2968
|
-
|
2969
|
-
|
2970
|
-
|
2971
|
-
|
2972
|
-
|
2973
|
-
|
2967
|
+
idx = df.groupby(['日期', '店铺名称', 'spuid'])['更新时间'].idxmax()
|
2968
|
+
df = df.loc[idx]
|
2969
|
+
# df.drop_duplicates(
|
2970
|
+
# subset=[
|
2971
|
+
# '日期',
|
2972
|
+
# '店铺名称',
|
2973
|
+
# 'spuid',
|
2974
|
+
# '访客量',
|
2975
|
+
# '浏览量',
|
2976
|
+
# '下单gmv',
|
2977
|
+
# '成交gmv',
|
2978
|
+
# ], keep='last', inplace=True, ignore_index=True)
|
2979
|
+
|
2980
|
+
# 调整列顺序, 定义需要前置的列
|
2981
|
+
cols_to_move = ['日期','平台','店铺名称','品牌名','商品名称', '商品款号','spuid', '一级类目名称', '二级类目名称', '三级类目名称']
|
2982
|
+
# 生成新的列顺序:前置列 + 剩余列(保持原顺序)
|
2983
|
+
new_columns = cols_to_move + [col for col in df.columns if col not in cols_to_move]
|
2984
|
+
# 调整DataFrame列顺序
|
2985
|
+
df = df[new_columns]
|
2986
|
+
df['更新时间'] = df.pop('更新时间')
|
2987
|
+
df = df.astype({'日期': 'datetime64[ns]'}, errors='ignore')
|
2974
2988
|
set_typ = {
|
2975
2989
|
'日期': 'date',
|
2976
2990
|
'店铺名称': 'varchar(100)',
|
2977
|
-
'
|
2991
|
+
'spuid': 'varchar(100)',
|
2978
2992
|
'图片': 'varchar(255)',
|
2979
2993
|
'序号': 'smallint',
|
2980
2994
|
'商品名称': 'varchar(255)',
|
mdbq/log/spider_logging.py
CHANGED
@@ -10,12 +10,11 @@ def setup_logging(reMoveOldHandler=True):
|
|
10
10
|
"""
|
11
11
|
reMoveOldHandler: 替换根日志记录器的所有现有处理器
|
12
12
|
"""
|
13
|
-
|
13
|
+
dir_path = os.path.expanduser("~")
|
14
|
+
if not os.path.isdir(os.path.join(dir_path, 'logfile')):
|
15
|
+
os.makedirs(os.path.join(dir_path, 'logfile'))
|
14
16
|
|
15
|
-
|
16
|
-
os.makedirs(os.path.join(D_PATH, 'logfile'))
|
17
|
-
|
18
|
-
log_file = os.path.join(D_PATH, 'logfile', 'spider_tg.log')
|
17
|
+
log_file = os.path.join(dir_path, 'logfile', 'spider_tg.log')
|
19
18
|
file_handler = RotatingFileHandler(
|
20
19
|
filename=log_file,
|
21
20
|
maxBytes=3*1024*1024, # 3MB
|
@@ -47,7 +47,9 @@ upload_path = os.path.join(D_PATH, '数据上传中心') # 此目录位于下
|
|
47
47
|
if not os.path.exists(upload_path): # 数据中心根目录
|
48
48
|
os.makedirs(upload_path)
|
49
49
|
|
50
|
-
|
50
|
+
dir_path = os.path.expanduser("~")
|
51
|
+
config_file = os.path.join(dir_path, 'spd.txt')
|
52
|
+
content = config.read_config(file_path=config_file)
|
51
53
|
username, password, host, port = content['username'], content['password'], content['host'], content['port']
|
52
54
|
m_engine = mysql.MysqlUpload(username=username, password=password, host=host, port=port, charset='utf8mb4')
|
53
55
|
|
mdbq/redis/getredis.py
CHANGED
@@ -17,7 +17,8 @@ import orjson
|
|
17
17
|
logger = logging.getLogger(__name__)
|
18
18
|
|
19
19
|
# 创建一个文件处理器,用于将日志写入文件
|
20
|
-
dir_path = os.path.
|
20
|
+
dir_path = os.path.expanduser("~")
|
21
|
+
# config_file = os.path.join(dir_path, 'spd.txt')
|
21
22
|
log_file = os.path.join(dir_path, 'logfile', 'redis.log')
|
22
23
|
if not os.path.isdir(os.path.join(dir_path, 'logfile')):
|
23
24
|
os.mkdir(os.path.join(dir_path, 'logfile'))
|
mdbq/spider/aikucun.py
CHANGED
@@ -22,8 +22,9 @@ from mdbq.mysql import s_query
|
|
22
22
|
from mdbq.config import config
|
23
23
|
from mdbq.other import ua_sj
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
dir_path = os.path.expanduser("~")
|
26
|
+
config_file = os.path.join(dir_path, 'spd.txt')
|
27
|
+
content = config.read_config(file_path=config_file)
|
27
28
|
username, password, host, port = content['username'], content['password'], content['host'], content['port']
|
28
29
|
|
29
30
|
m_engine = mysql.MysqlUpload(username=username, password=password, host=host, port=port, charset='utf8mb4')
|
@@ -68,6 +69,7 @@ class AikuCun:
|
|
68
69
|
self.today = datetime.date.today()
|
69
70
|
self.start_date = (self.today - datetime.timedelta(days=7)).strftime('%Y-%m-%d')
|
70
71
|
self.end_date = (self.today - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
|
72
|
+
self.error_count = 0
|
71
73
|
|
72
74
|
def logining(self, shop_name='aikucun', headless=False):
|
73
75
|
option = webdriver.ChromeOptions()
|
@@ -195,6 +197,9 @@ class AikuCun:
|
|
195
197
|
)
|
196
198
|
|
197
199
|
def get_data_from_bbx(self, start_date=None, end_date=None, item_type='spu', page_num=1, page_size=300):
|
200
|
+
"""
|
201
|
+
这里获取的数据等同于"查询"按钮的数据, 没有"营销后供货额/供货价" 这2个字段, 如果通过下载按钮的报表则有两个字段
|
202
|
+
"""
|
198
203
|
if start_date:
|
199
204
|
self.start_date = start_date
|
200
205
|
if end_date:
|
@@ -238,6 +243,9 @@ class AikuCun:
|
|
238
243
|
num = 1
|
239
244
|
results = []
|
240
245
|
for date in date_list:
|
246
|
+
if self.error_count > 5:
|
247
|
+
print('已退出请求 -> self.error_count > 5')
|
248
|
+
break
|
241
249
|
req_date = re.sub('-', '', date)
|
242
250
|
data = {
|
243
251
|
'beginDate': req_date,
|
@@ -265,11 +273,15 @@ class AikuCun:
|
|
265
273
|
print(f'正在获取数据({num}/{len(date_list)}): {item_type}榜单 {date}')
|
266
274
|
# print(res.json())
|
267
275
|
if not res.json()['success']:
|
268
|
-
print('requests 请求不成功, success 返回值应为 True')
|
276
|
+
print('没有获取到数据, requests 请求不成功, success 返回值应为 True')
|
277
|
+
num += 1
|
278
|
+
self.error_count += 1
|
269
279
|
time.sleep(1)
|
270
280
|
continue
|
271
281
|
if not res.json()['data']['rows']:
|
272
|
-
print("
|
282
|
+
print("返回的数据字典异常, ['data']['rows'] 不能为空")
|
283
|
+
num += 1
|
284
|
+
self.error_count += 1
|
273
285
|
time.sleep(1)
|
274
286
|
continue
|
275
287
|
results += [(date, res.json()['data']['rows'])]
|
@@ -389,7 +401,7 @@ class AikuCun:
|
|
389
401
|
'图片': 'varchar(255)',
|
390
402
|
'浏览量': 'INT',
|
391
403
|
'序号': 'INT',
|
392
|
-
'
|
404
|
+
'spuid': 'varchar(50)',
|
393
405
|
'商品名称': 'varchar(50)',
|
394
406
|
'供货额': 'decimal(10,2)',
|
395
407
|
'供货价': 'decimal(10,2)',
|
@@ -468,6 +480,7 @@ def main(start_date, end_date, item_type=['spu']):
|
|
468
480
|
if not data_list:
|
469
481
|
ak.logining()
|
470
482
|
ak.save_token()
|
483
|
+
ak.error_count = 0 # 重置错误计数器
|
471
484
|
else:
|
472
485
|
break
|
473
486
|
|
@@ -481,7 +494,7 @@ def main(start_date, end_date, item_type=['spu']):
|
|
481
494
|
|
482
495
|
if __name__ == '__main__':
|
483
496
|
main(
|
484
|
-
start_date='2025-03-
|
485
|
-
end_date='2025-03-
|
497
|
+
start_date='2025-03-01',
|
498
|
+
end_date='2025-03-12',
|
486
499
|
item_type=['spu', 'sku']
|
487
500
|
)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
|
2
|
-
mdbq/__version__.py,sha256=
|
2
|
+
mdbq/__version__.py,sha256=FbrHE5dCkeXrcGtVfIXS2SdQe0n1QBEKhU3bP4mfMtM,17
|
3
3
|
mdbq/aggregation/__init__.py,sha256=EeDqX2Aml6SPx8363J-v1lz0EcZtgwIBYyCJV6CcEDU,40
|
4
|
-
mdbq/aggregation/query_data.py,sha256=
|
4
|
+
mdbq/aggregation/query_data.py,sha256=nCdo2Qr6159-yuRGYYO7kcIStV2tv5UEQC4dfBl9kic,181075
|
5
5
|
mdbq/bdup/__init__.py,sha256=AkhsGk81SkG1c8FqDH5tRq-8MZmFobVbN60DTyukYTY,28
|
6
6
|
mdbq/bdup/bdup.py,sha256=hJs815hGFwm_X5bP2i9XugG2w2ZY_F0n3-Q0hVpIPPw,4892
|
7
7
|
mdbq/config/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
|
@@ -11,26 +11,25 @@ mdbq/dataframe/__init__.py,sha256=2HtCN8AdRj53teXDqzysC1h8aPL-mMFy561ESmhehGQ,22
|
|
11
11
|
mdbq/dataframe/converter.py,sha256=lETYhT7KXlWzWwqguqhk6vI6kj4rnOBEW1lhqKy2Abc,5035
|
12
12
|
mdbq/log/__init__.py,sha256=Mpbrav0s0ifLL7lVDAuePEi1hJKiSHhxcv1byBKDl5E,15
|
13
13
|
mdbq/log/mylogger.py,sha256=oaT7Bp-Hb9jZt52seP3ISUuxVcI19s4UiqTeouScBO0,3258
|
14
|
-
mdbq/log/spider_logging.py,sha256=
|
14
|
+
mdbq/log/spider_logging.py,sha256=KX9TTUn9naZNBACCEFhyTktnWhr5JaSNQLppLGyrm9Y,1645
|
15
15
|
mdbq/mongo/__init__.py,sha256=SILt7xMtQIQl_m-ik9WLtJSXIVf424iYgCfE_tnQFbw,13
|
16
16
|
mdbq/mysql/__init__.py,sha256=A_DPJyAoEvTSFojiI2e94zP0FKtCkkwKP1kYUCSyQzo,11
|
17
17
|
mdbq/mysql/mysql.py,sha256=tR6l4Zzn9j6zKaFcy0Ktw2oL8OoX3QB6jDoDp1l2fiM,95474
|
18
18
|
mdbq/mysql/s_query.py,sha256=09Dp7DrVXui6dAI6zFDfrsUOdjPblF_oYUpgqbZMhXg,8757
|
19
19
|
mdbq/mysql/year_month_day.py,sha256=VgewoE2pJxK7ErjfviL_SMTN77ki8GVbTUcao3vFUCE,1523
|
20
20
|
mdbq/other/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
|
21
|
-
mdbq/other/download_sku_picture.py,sha256=
|
21
|
+
mdbq/other/download_sku_picture.py,sha256=YU8DxKMXbdeE1OOKEA848WVp62jYHw5O4tXTjUdq9H0,44832
|
22
22
|
mdbq/other/porxy.py,sha256=UHfgEyXugogvXgsG68a7QouUCKaohTKKkI4RN-kYSdQ,4961
|
23
23
|
mdbq/other/pov_city.py,sha256=AEOmCOzOwyjHi9LLZWPKi6DUuSC-_M163664I52u9qw,21050
|
24
24
|
mdbq/other/ua_sj.py,sha256=JuVYzc_5QZ9s_oQSrTHVKkQv4S_7-CWx4oIKOARn_9U,22178
|
25
25
|
mdbq/pbix/__init__.py,sha256=Trtfaynu9RjoTyLLYBN2xdRxTvm_zhCniUkVTAYwcjo,24
|
26
26
|
mdbq/pbix/pbix_refresh.py,sha256=JUjKW3bNEyoMVfVfo77UhguvS5AWkixvVhDbw4_MHco,2396
|
27
27
|
mdbq/pbix/refresh_all.py,sha256=OBT9EewSZ0aRS9vL_FflVn74d4l2G00wzHiikCC4TC0,5926
|
28
|
-
mdbq/pbix/refresh_all_old.py,sha256=_pq3WSQ728GPtEG5pfsZI2uTJhU8D6ra-htIk1JXYzw,7192
|
29
28
|
mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
|
30
|
-
mdbq/redis/getredis.py,sha256=
|
29
|
+
mdbq/redis/getredis.py,sha256=Uk8-cOWT0JU1qRyIVqdbYokSLvkDIAfcokmYj1ebw8k,24104
|
31
30
|
mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
|
32
|
-
mdbq/spider/aikucun.py,sha256=
|
33
|
-
mdbq-3.8.
|
34
|
-
mdbq-3.8.
|
35
|
-
mdbq-3.8.
|
36
|
-
mdbq-3.8.
|
31
|
+
mdbq/spider/aikucun.py,sha256=bUjjPjNoW3EL6H89nnBdFEwnWgGuEB2CENuBxcvx0Kw,20284
|
32
|
+
mdbq-3.8.5.dist-info/METADATA,sha256=kBSQW0qeIfkw7V8GWiRRRlb_QMfz5NZFYq6xpwrHhy0,363
|
33
|
+
mdbq-3.8.5.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
34
|
+
mdbq-3.8.5.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
35
|
+
mdbq-3.8.5.dist-info/RECORD,,
|
mdbq/pbix/refresh_all_old.py
DELETED
@@ -1,177 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import sys
|
3
|
-
import win32com.client
|
4
|
-
import time
|
5
|
-
import multiprocessing
|
6
|
-
import psutil
|
7
|
-
from pywinauto.application import Application
|
8
|
-
import warnings
|
9
|
-
from mdbq.config import set_support
|
10
|
-
|
11
|
-
warnings.filterwarnings('ignore')
|
12
|
-
top_path = os.path.realpath(os.path.dirname(sys.argv[0])) # 程序运行目录, 打包时使用
|
13
|
-
sys.path.append(top_path)
|
14
|
-
|
15
|
-
|
16
|
-
class RefreshAll:
|
17
|
-
def __init__(self):
|
18
|
-
self.my_conf = os.path.join(set_support.SetSupport(dirname='support').dirname, '.my_conf')
|
19
|
-
self.pbix_path = os.path.join(set_support.SetSupport(dirname='support').dirname, 'ref_list.txt')
|
20
|
-
self.excel_path = os.path.join(set_support.SetSupport(dirname='support').dirname, 'ref_list.txt')
|
21
|
-
self.run_py_path = 'run_py'
|
22
|
-
self.procname = 'PBIDesktop.exe'
|
23
|
-
|
24
|
-
def refresh_pbix(self):
|
25
|
-
# 刷新 PBI
|
26
|
-
if not os.path.exists(self.pbix_path):
|
27
|
-
print(f'{self.pbix_path}: PBIxx file not found. ')
|
28
|
-
return
|
29
|
-
with open(self.pbix_path, 'r', encoding='utf-8') as f:
|
30
|
-
content = f.readlines()
|
31
|
-
content = [item.strip() for item in content if not item.strip().startswith('#') and not item.strip().startswith('[')]
|
32
|
-
pbix_list = [item for item in content if item]
|
33
|
-
|
34
|
-
if not pbix_list:
|
35
|
-
return
|
36
|
-
for filename in pbix_list:
|
37
|
-
if filename.endswith('.pbix'):
|
38
|
-
newfile = os.path.join(self.run_py_path, filename)
|
39
|
-
"""刷新程序"""
|
40
|
-
for es in range(4):
|
41
|
-
try:
|
42
|
-
print(f'正在刷新 >>>{filename}')
|
43
|
-
self.pbi(path=newfile)
|
44
|
-
print('文件刷新 >>>' + filename)
|
45
|
-
break
|
46
|
-
except Exception as e:
|
47
|
-
print(e)
|
48
|
-
print('报错的文件 >>>' + filename + ' >> ' + str(es + 1))
|
49
|
-
|
50
|
-
def refresh_excel(self):
|
51
|
-
# 刷新 excel
|
52
|
-
if not os.path.exists(self.excel_path):
|
53
|
-
print(f'{self.excel_path}: Excel file not found. ')
|
54
|
-
return
|
55
|
-
with open(self.excel_path, 'r', encoding='utf-8') as f:
|
56
|
-
content = f.readlines()
|
57
|
-
content = [item.strip() for item in content if not item.strip().startswith('#')]
|
58
|
-
excel_list = [item for item in content if item]
|
59
|
-
|
60
|
-
if not excel_list:
|
61
|
-
return
|
62
|
-
for filename in excel_list:
|
63
|
-
if filename.endswith('.xlsx'):
|
64
|
-
try:
|
65
|
-
print(f'正在刷新 >>>{filename}')
|
66
|
-
path = os.path.join(top_path, self.run_py_path, filename) # 拼接文件路径
|
67
|
-
xlapp = win32com.client.Dispatch('Excel.Application') # 创建Excel程序App
|
68
|
-
xlapp.Visible = False # 窗口是否可见
|
69
|
-
xlapp.DisplayAlerts = False # 是否显示警告信息
|
70
|
-
wb = xlapp.Workbooks.Open(path)
|
71
|
-
conjuncts = wb.Connections.Count # 统计工作簿含有多少外部链接
|
72
|
-
if conjuncts == 0:
|
73
|
-
wb.Close(SaveChanges=False)
|
74
|
-
xlapp.Quit()
|
75
|
-
else:
|
76
|
-
time.sleep(2)
|
77
|
-
wb.RefreshAll()
|
78
|
-
xlapp.CalculateUntilAsyncQueriesDone()
|
79
|
-
time.sleep(2)
|
80
|
-
wb.Save()
|
81
|
-
wb.Close(SaveChanges=True)
|
82
|
-
xlapp.Quit()
|
83
|
-
print('文件刷新 >>>' + filename)
|
84
|
-
except Exception as e:
|
85
|
-
print(e)
|
86
|
-
|
87
|
-
def refresh_excel2(self, excel_file):
|
88
|
-
# 刷新 excel
|
89
|
-
if excel_file.endswith('.xlsx'):
|
90
|
-
try:
|
91
|
-
print(f'正在刷新 >>>{excel_file}')
|
92
|
-
xlapp = win32com.client.Dispatch('Excel.Application') # 创建Excel程序App
|
93
|
-
xlapp.Visible = False # 窗口是否可见
|
94
|
-
xlapp.DisplayAlerts = False # 是否显示警告信息
|
95
|
-
wb = xlapp.Workbooks.Open(excel_file)
|
96
|
-
conjuncts = wb.Connections.Count # 统计工作簿含有多少外部链接
|
97
|
-
if conjuncts == 0:
|
98
|
-
wb.Close(SaveChanges=False)
|
99
|
-
xlapp.Quit()
|
100
|
-
else:
|
101
|
-
time.sleep(2)
|
102
|
-
wb.RefreshAll()
|
103
|
-
xlapp.CalculateUntilAsyncQueriesDone()
|
104
|
-
time.sleep(2)
|
105
|
-
wb.Save()
|
106
|
-
wb.Close(SaveChanges=True)
|
107
|
-
xlapp.Quit()
|
108
|
-
print('文件刷新 >>>' + excel_file)
|
109
|
-
except Exception as e:
|
110
|
-
print(e)
|
111
|
-
|
112
|
-
def pbi(self, path, _timeout=300):
|
113
|
-
"""
|
114
|
-
这是原本属于独立的库模块: pbix_refresh
|
115
|
-
path: pbi文件路径
|
116
|
-
_timeout: 刷新等待时间
|
117
|
-
如果连接失败,请将 power bi 文件名的特殊字符(空格等)去掉或改为英文文件名试试
|
118
|
-
"""
|
119
|
-
# 关闭已打开的 power bi进程
|
120
|
-
for proc in psutil.process_iter():
|
121
|
-
if proc.name() == self.procname:
|
122
|
-
proc.kill()
|
123
|
-
time.sleep(1)
|
124
|
-
|
125
|
-
# 启动 Power bi
|
126
|
-
os.system('start "" "' + path + '"')
|
127
|
-
time.sleep(5)
|
128
|
-
|
129
|
-
# 通过 connect 方法连接进程
|
130
|
-
app = Application(backend='uia').connect(path=self.procname)
|
131
|
-
# title_re可以通过正则表达式连接:".*Power BI Desktop", 仅限 2023年9月之前的 Power bi版本
|
132
|
-
# 2023年10月之后的版本没有此窗口后缀, 因此需用文件名找窗口
|
133
|
-
# 如果同时打开了其他同名的文件(非 power bi文件时), 可能会引发错误
|
134
|
-
_filename = os.path.splitext(os.path.basename(path))[0] # 文件名不含后缀
|
135
|
-
win = app.window(title_re=f'{_filename}.*?') # 连接 pbi 窗口
|
136
|
-
time.sleep(10)
|
137
|
-
# win.print_control_identifiers() # 打印窗口全部信息, 推荐使用 inspect 开发工具查询窗口句柄信息
|
138
|
-
num = 0
|
139
|
-
while True:
|
140
|
-
try:
|
141
|
-
win['刷新'].wait("enabled", timeout=_timeout)
|
142
|
-
time.sleep(3)
|
143
|
-
win['刷新'].click()
|
144
|
-
break
|
145
|
-
except:
|
146
|
-
print(f'{path}, 未识别窗口句柄, 连接超时')
|
147
|
-
num += 1
|
148
|
-
if num > 1:
|
149
|
-
break
|
150
|
-
|
151
|
-
num = 0
|
152
|
-
while True:
|
153
|
-
try:
|
154
|
-
win['保存'].wait("enabled", timeout=_timeout) # timeout 通过"保存"按键状态, 等待刷新窗口关闭, 时间不要设置太短
|
155
|
-
time.sleep(3)
|
156
|
-
win['保存'].click()
|
157
|
-
break
|
158
|
-
except:
|
159
|
-
print(f'{path}, 未识别窗口句柄, 文件未保存')
|
160
|
-
num += 1
|
161
|
-
if num > 1:
|
162
|
-
break
|
163
|
-
# win.type_keys("^s")
|
164
|
-
win.wait("enabled", timeout=15)
|
165
|
-
win.close()
|
166
|
-
|
167
|
-
# 关闭进程
|
168
|
-
for proc in psutil.process_iter():
|
169
|
-
if proc.name() == self.procname:
|
170
|
-
proc.kill()
|
171
|
-
|
172
|
-
|
173
|
-
if __name__ == '__main__':
|
174
|
-
# r = RefreshAll()
|
175
|
-
# # r.refresh_pbix()
|
176
|
-
# r.refresh_excel()
|
177
|
-
pass
|
File without changes
|
File without changes
|