qrpa 1.1.35__py3-none-any.whl → 1.1.36__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.
Potentially problematic release.
This version of qrpa might be problematic. Click here for more details.
- qrpa/mysql_module/new_product_analysis_model.py +7 -1
- qrpa/shein_lib.py +253 -2
- {qrpa-1.1.35.dist-info → qrpa-1.1.36.dist-info}/METADATA +1 -1
- {qrpa-1.1.35.dist-info → qrpa-1.1.36.dist-info}/RECORD +6 -6
- {qrpa-1.1.35.dist-info → qrpa-1.1.36.dist-info}/WHEEL +0 -0
- {qrpa-1.1.35.dist-info → qrpa-1.1.36.dist-info}/top_level.txt +0 -0
|
@@ -236,7 +236,13 @@ class NewProductAnalysisManager:
|
|
|
236
236
|
prom_detail = prom.get('promDetail', [])
|
|
237
237
|
|
|
238
238
|
# 根据promId长度判断取哪些字段
|
|
239
|
-
if len(str(prom_id))
|
|
239
|
+
if len(str(prom_id)) >= 11 and prom_detail:
|
|
240
|
+
# 营销工具:取第一个detail的数据
|
|
241
|
+
detail = prom_detail if prom_detail else {}
|
|
242
|
+
prom_info['attend_num_sum'] = detail.get('act_stock_num')
|
|
243
|
+
prom_info['supply_price'] = detail.get('sku_price')
|
|
244
|
+
prom_info['product_act_price'] = detail.get('act_sku_price')
|
|
245
|
+
elif len(str(prom_id)) >= 8 and prom_detail:
|
|
240
246
|
# 营销工具:取第一个detail的数据
|
|
241
247
|
detail = prom_detail[0] if prom_detail else {}
|
|
242
248
|
prom_info['attend_num_sum'] = detail.get('attend_num_sum')
|
qrpa/shein_lib.py
CHANGED
|
@@ -1236,7 +1236,10 @@ class SheinLib:
|
|
|
1236
1236
|
for prom_inf_ing in skc_item['promCampaign'].get('promInfIng') or []:
|
|
1237
1237
|
prom_id = prom_inf_ing['promId']
|
|
1238
1238
|
log('prom_id:', prom_id, len(prom_id))
|
|
1239
|
-
if len(prom_id) >=
|
|
1239
|
+
if len(prom_id) >= 11:
|
|
1240
|
+
# 托管活动
|
|
1241
|
+
prom_inf_ing['promDetail'] = self.get_skc_activity_price_info(skc, prom_id)
|
|
1242
|
+
elif len(prom_id) >= 8:
|
|
1240
1243
|
# 营销工具
|
|
1241
1244
|
prom_inf_ing['promDetail'] = self.query_goods_detail(prom_id)
|
|
1242
1245
|
else:
|
|
@@ -1246,7 +1249,9 @@ class SheinLib:
|
|
|
1246
1249
|
for prom_inf_ready in skc_item['promCampaign'].get('promInfReady') or []:
|
|
1247
1250
|
prom_id = prom_inf_ready['promId']
|
|
1248
1251
|
log('prom_id:', prom_id, len(prom_id))
|
|
1249
|
-
if len(prom_id) >=
|
|
1252
|
+
if len(prom_id) >= 11:
|
|
1253
|
+
prom_inf_ready['promDetail'] = self.get_skc_activity_price_info(skc, prom_id)
|
|
1254
|
+
elif len(prom_id) >= 8:
|
|
1250
1255
|
prom_inf_ready['promDetail'] = self.query_goods_detail(prom_id)
|
|
1251
1256
|
else:
|
|
1252
1257
|
prom_inf_ready['promDetail'] = self.get_partake_activity_detail(prom_id, skc)
|
|
@@ -2373,6 +2378,7 @@ class SheinLib:
|
|
|
2373
2378
|
list_item += response_text['info']['data']
|
|
2374
2379
|
time.sleep(0.1)
|
|
2375
2380
|
|
|
2381
|
+
log(list_item)
|
|
2376
2382
|
write_dict_to_file(cache_file, list_item)
|
|
2377
2383
|
return list_item
|
|
2378
2384
|
|
|
@@ -2398,6 +2404,7 @@ class SheinLib:
|
|
|
2398
2404
|
raise send_exception(json.dumps(response_text, ensure_ascii=False))
|
|
2399
2405
|
list_item = response_text['info']['data']
|
|
2400
2406
|
|
|
2407
|
+
log(list_item)
|
|
2401
2408
|
write_dict_to_file(cache_file, list_item)
|
|
2402
2409
|
return list_item
|
|
2403
2410
|
|
|
@@ -3930,3 +3937,247 @@ class SheinLib:
|
|
|
3930
3937
|
log('临时下载文件已清理')
|
|
3931
3938
|
|
|
3932
3939
|
return output_file_path
|
|
3940
|
+
|
|
3941
|
+
def query_hosting_info_list(self):
|
|
3942
|
+
"""
|
|
3943
|
+
查询店铺活动托管规则列表
|
|
3944
|
+
|
|
3945
|
+
Returns:
|
|
3946
|
+
list: 托管规则列表,每个元素包含:
|
|
3947
|
+
- hosting_id: 托管规则ID
|
|
3948
|
+
- scene_type: 场景类型
|
|
3949
|
+
- state: 状态
|
|
3950
|
+
- hosting_name: 托管规则名称
|
|
3951
|
+
- hosting_tools_id: 托管工具ID
|
|
3952
|
+
- hosting_tools_state: 托管工具状态
|
|
3953
|
+
- time_zone: 时区
|
|
3954
|
+
- create_user: 创建用户
|
|
3955
|
+
- last_update_user: 最后更新用户
|
|
3956
|
+
- insert_time: 创建时间
|
|
3957
|
+
- last_update_time: 最后更新时间
|
|
3958
|
+
- exist_act_goods: 是否存在活动商品
|
|
3959
|
+
"""
|
|
3960
|
+
log(f'正在获取 {self.store_name} 店铺活动托管规则列表')
|
|
3961
|
+
|
|
3962
|
+
cache_file = f'{self.config.auto_dir}/shein/cache/hosting_info_list_{self.store_username}_{TimeUtils.today_date()}.json'
|
|
3963
|
+
hosting_list = read_dict_from_file_ex(cache_file, self.store_username, 3600 * 8)
|
|
3964
|
+
if len(hosting_list) > 0:
|
|
3965
|
+
log('返回缓存数据')
|
|
3966
|
+
return hosting_list
|
|
3967
|
+
|
|
3968
|
+
url = "https://sso.geiwohuo.com/mrs-api-prefix/promotion/hosting/query_hosting_info_list"
|
|
3969
|
+
payload = {}
|
|
3970
|
+
|
|
3971
|
+
response_text = fetch(self.web_page, url, payload)
|
|
3972
|
+
error_code = response_text.get('code')
|
|
3973
|
+
if str(error_code) != '0':
|
|
3974
|
+
raise send_exception(json.dumps(response_text, ensure_ascii=False))
|
|
3975
|
+
|
|
3976
|
+
hosting_list = response_text.get('info', [])
|
|
3977
|
+
log(f'获取到 {len(hosting_list)} 条托管规则')
|
|
3978
|
+
|
|
3979
|
+
write_dict_to_file_ex(cache_file, {self.store_username: hosting_list}, [self.store_username])
|
|
3980
|
+
|
|
3981
|
+
return hosting_list
|
|
3982
|
+
|
|
3983
|
+
def query_hosting_activity_goods(self, hosting_id, goods_states=None):
|
|
3984
|
+
"""
|
|
3985
|
+
查询托管活动参与的商品
|
|
3986
|
+
|
|
3987
|
+
Args:
|
|
3988
|
+
hosting_id: 托管规则ID
|
|
3989
|
+
goods_states: 商品状态列表,默认为[1](在售)
|
|
3990
|
+
|
|
3991
|
+
Returns:
|
|
3992
|
+
list: 参与托管活动的商品列表,每个元素包含:
|
|
3993
|
+
- goods_state: 商品状态
|
|
3994
|
+
- skc_info_list: SKC信息列表
|
|
3995
|
+
- skc_id: SKC ID
|
|
3996
|
+
- skc_name: SKC名称
|
|
3997
|
+
- goods_name: 商品名称
|
|
3998
|
+
- image_url: 图片URL
|
|
3999
|
+
- act_stock_num: 活动库存数量
|
|
4000
|
+
- act_sales_num: 活动销量
|
|
4001
|
+
- activity_info: 活动信息
|
|
4002
|
+
- sku_info_list: SKU信息列表
|
|
4003
|
+
"""
|
|
4004
|
+
if goods_states is None:
|
|
4005
|
+
goods_states = [1]
|
|
4006
|
+
|
|
4007
|
+
log(f'正在获取 {self.store_name} 托管活动商品列表 hosting_id={hosting_id}')
|
|
4008
|
+
|
|
4009
|
+
cache_file = f'{self.config.auto_dir}/shein/cache/hosting_activity_goods_{self.store_username}_{hosting_id}_{TimeUtils.today_date()}.json'
|
|
4010
|
+
goods_list = read_dict_from_file_ex(cache_file, self.store_username, 3600 * 8)
|
|
4011
|
+
if len(goods_list) > 0:
|
|
4012
|
+
log('返回缓存数据')
|
|
4013
|
+
return goods_list
|
|
4014
|
+
|
|
4015
|
+
page_num = 1
|
|
4016
|
+
page_size = 100
|
|
4017
|
+
|
|
4018
|
+
url = "https://sso.geiwohuo.com/mrs-api-prefix/promotion/hosting/query_hosting_activity_goods"
|
|
4019
|
+
payload = {
|
|
4020
|
+
"goods_states": goods_states,
|
|
4021
|
+
"hosting_id" : str(hosting_id),
|
|
4022
|
+
"page_num" : page_num,
|
|
4023
|
+
"page_size" : page_size
|
|
4024
|
+
}
|
|
4025
|
+
|
|
4026
|
+
response_text = fetch(self.web_page, url, payload)
|
|
4027
|
+
error_code = response_text.get('code')
|
|
4028
|
+
if str(error_code) != '0':
|
|
4029
|
+
raise send_exception(json.dumps(response_text, ensure_ascii=False))
|
|
4030
|
+
|
|
4031
|
+
goods_list = response_text.get('info', [])
|
|
4032
|
+
if not goods_list:
|
|
4033
|
+
log('未获取到商品数据')
|
|
4034
|
+
return []
|
|
4035
|
+
|
|
4036
|
+
# 获取第一页数据
|
|
4037
|
+
first_item = goods_list[0] if goods_list else {}
|
|
4038
|
+
skc_info_list = first_item.get('skc_info_list', {})
|
|
4039
|
+
all_data = skc_info_list.get('data', [])
|
|
4040
|
+
meta = skc_info_list.get('meta', {})
|
|
4041
|
+
total = meta.get('count', 0)
|
|
4042
|
+
|
|
4043
|
+
log(f'第1页获取到 {len(all_data)} 条商品,总数: {total}')
|
|
4044
|
+
|
|
4045
|
+
# 如果有多页,继续获取
|
|
4046
|
+
if total > page_size:
|
|
4047
|
+
totalPage = math.ceil(total / page_size)
|
|
4048
|
+
for page in range(2, totalPage + 1):
|
|
4049
|
+
log(f'获取托管活动商品列表 第{page}/{totalPage}页')
|
|
4050
|
+
payload['page_num'] = page
|
|
4051
|
+
response_text = fetch(self.web_page, url, payload)
|
|
4052
|
+
error_code = response_text.get('code')
|
|
4053
|
+
if str(error_code) != '0':
|
|
4054
|
+
log(f'获取第{page}页失败: {response_text}')
|
|
4055
|
+
continue
|
|
4056
|
+
|
|
4057
|
+
page_goods_list = response_text.get('info', [])
|
|
4058
|
+
if page_goods_list:
|
|
4059
|
+
page_data = page_goods_list[0].get('skc_info_list', {}).get('data', [])
|
|
4060
|
+
all_data.extend(page_data)
|
|
4061
|
+
log(f'第{page}页获取到 {len(page_data)} 条商品')
|
|
4062
|
+
|
|
4063
|
+
time.sleep(0.1)
|
|
4064
|
+
|
|
4065
|
+
log(f'总共获取到 {len(all_data)} 条商品')
|
|
4066
|
+
|
|
4067
|
+
# 保存缓存
|
|
4068
|
+
write_dict_to_file_ex(cache_file, {self.store_username: all_data}, [self.store_username])
|
|
4069
|
+
|
|
4070
|
+
return all_data
|
|
4071
|
+
|
|
4072
|
+
def get_skc_activity_price_info(self, skc, activity_id):
|
|
4073
|
+
"""
|
|
4074
|
+
根据SKC和活动ID获取供货价、活动价和活动库存
|
|
4075
|
+
|
|
4076
|
+
Args:
|
|
4077
|
+
skc: SKC名称
|
|
4078
|
+
activity_id: 活动ID(可以是字符串或整数)
|
|
4079
|
+
|
|
4080
|
+
Returns:
|
|
4081
|
+
dict: 包含以下键值的字典,如果未找到则返回None:
|
|
4082
|
+
- sku_price: SKU供货价(取第一个SKU的价格)
|
|
4083
|
+
- act_sku_price: SKU活动价(取第一个SKU的活动价)
|
|
4084
|
+
- act_stock_num: 活动库存数量
|
|
4085
|
+
- skc_name: SKC名称
|
|
4086
|
+
- goods_name: 商品名称
|
|
4087
|
+
- activity_id: 活动ID
|
|
4088
|
+
- currency: 币种
|
|
4089
|
+
- image_url: 商品图片
|
|
4090
|
+
"""
|
|
4091
|
+
log(f'获取SKC活动价格信息: skc={skc}, activity_id={activity_id}')
|
|
4092
|
+
|
|
4093
|
+
# 转换activity_id为整数进行比较
|
|
4094
|
+
try:
|
|
4095
|
+
target_activity_id = int(activity_id)
|
|
4096
|
+
except (ValueError, TypeError):
|
|
4097
|
+
log(f'无效的activity_id: {activity_id}')
|
|
4098
|
+
return None
|
|
4099
|
+
|
|
4100
|
+
# 缓存文件,使用skc和activity_id作为缓存key
|
|
4101
|
+
cache_file = f'{self.config.auto_dir}/shein/cache/skc_activity_price_{self.store_username}_{skc}_{activity_id}_{TimeUtils.today_date()}.json'
|
|
4102
|
+
cached_data = read_dict_from_file(cache_file, 3600 * 8)
|
|
4103
|
+
if cached_data:
|
|
4104
|
+
log('返回缓存的价格信息')
|
|
4105
|
+
return cached_data
|
|
4106
|
+
|
|
4107
|
+
# 获取所有托管规则
|
|
4108
|
+
hosting_list = self.query_hosting_info_list()
|
|
4109
|
+
|
|
4110
|
+
if not hosting_list:
|
|
4111
|
+
log('未找到任何托管规则')
|
|
4112
|
+
return None
|
|
4113
|
+
|
|
4114
|
+
# 遍历所有托管规则,查找匹配的SKC和活动
|
|
4115
|
+
for hosting in hosting_list:
|
|
4116
|
+
hosting_id = hosting.get('hosting_id')
|
|
4117
|
+
if not hosting_id:
|
|
4118
|
+
continue
|
|
4119
|
+
|
|
4120
|
+
log(f'查询托管规则: hosting_id={hosting_id}, hosting_name={hosting.get("hosting_name")}')
|
|
4121
|
+
|
|
4122
|
+
# 获取该托管规则下的商品
|
|
4123
|
+
goods_list = self.query_hosting_activity_goods(hosting_id)
|
|
4124
|
+
|
|
4125
|
+
# 在商品列表中查找匹配的SKC
|
|
4126
|
+
for goods_item in goods_list:
|
|
4127
|
+
skc_name = goods_item.get('skc_name', '')
|
|
4128
|
+
|
|
4129
|
+
# 匹配SKC名称
|
|
4130
|
+
if skc_name != skc:
|
|
4131
|
+
continue
|
|
4132
|
+
|
|
4133
|
+
# 检查活动信息
|
|
4134
|
+
activity_info = goods_item.get('activity_info', {})
|
|
4135
|
+
goods_activity_id = activity_info.get('activity_id')
|
|
4136
|
+
|
|
4137
|
+
# 匹配活动ID
|
|
4138
|
+
try:
|
|
4139
|
+
if int(goods_activity_id) != target_activity_id:
|
|
4140
|
+
continue
|
|
4141
|
+
except (ValueError, TypeError):
|
|
4142
|
+
continue
|
|
4143
|
+
|
|
4144
|
+
log(f'找到匹配的SKC: {skc_name}, activity_id={goods_activity_id}')
|
|
4145
|
+
|
|
4146
|
+
# 提取活动库存
|
|
4147
|
+
act_stock_num = goods_item.get('act_stock_num', 0)
|
|
4148
|
+
|
|
4149
|
+
# 获取第一个SKU的价格信息
|
|
4150
|
+
sku_info_list = goods_item.get('sku_info_list', [])
|
|
4151
|
+
if not sku_info_list:
|
|
4152
|
+
log(f'SKC {skc_name} 没有SKU信息')
|
|
4153
|
+
continue
|
|
4154
|
+
|
|
4155
|
+
first_sku = sku_info_list[0]
|
|
4156
|
+
sku_price = first_sku.get('sku_price', 0)
|
|
4157
|
+
act_sku_price = first_sku.get('act_sku_price', 0)
|
|
4158
|
+
currency = first_sku.get('currency', 'CNY')
|
|
4159
|
+
|
|
4160
|
+
# 构建返回结果
|
|
4161
|
+
result = {
|
|
4162
|
+
'skc_name' : skc_name,
|
|
4163
|
+
'goods_name' : goods_item.get('goods_name', ''),
|
|
4164
|
+
'image_url' : goods_item.get('image_url', ''),
|
|
4165
|
+
'activity_id' : goods_activity_id,
|
|
4166
|
+
'act_stock_num': act_stock_num,
|
|
4167
|
+
'sku_price' : sku_price,
|
|
4168
|
+
'act_sku_price': act_sku_price,
|
|
4169
|
+
'currency' : currency,
|
|
4170
|
+
'start_time' : activity_info.get('start_time', ''),
|
|
4171
|
+
'end_time' : activity_info.get('end_time', ''),
|
|
4172
|
+
'time_zone' : activity_info.get('time_zone', ''),
|
|
4173
|
+
}
|
|
4174
|
+
|
|
4175
|
+
log(f'SKC供货价: {sku_price} {currency}, 活动价: {act_sku_price} {currency}, 活动库存: {act_stock_num}')
|
|
4176
|
+
|
|
4177
|
+
# 保存缓存
|
|
4178
|
+
write_dict_to_file(cache_file, result)
|
|
4179
|
+
|
|
4180
|
+
return result
|
|
4181
|
+
|
|
4182
|
+
log(f'未找到匹配的SKC和活动: skc={skc}, activity_id={activity_id}')
|
|
4183
|
+
return None
|
|
@@ -11,7 +11,7 @@ qrpa/fun_web.py,sha256=9YuVy_wps9Ty_FBZ91W2R0iKgC2IViaJjHbyuUgngGs,11599
|
|
|
11
11
|
qrpa/fun_win.py,sha256=vMdVh00dsnVz8Wey4Bq7J3RPZAY8B_bI_IKphOX1cE8,7836
|
|
12
12
|
qrpa/shein_daily_report_model.py,sha256=O8s9qM45WZRoAgxUFRngvmBrc29v7Uf2ye7K8_bcSRg,12214
|
|
13
13
|
qrpa/shein_excel.py,sha256=-5fNetkVMixPQPw00K9F4OeJn8LSknaoyRXNqsQw1EA,158107
|
|
14
|
-
qrpa/shein_lib.py,sha256=
|
|
14
|
+
qrpa/shein_lib.py,sha256=GSHqiCoVgFs3Ri6HT-AxxcJuGTsZ2eRGnGbv2YsF4ho,190827
|
|
15
15
|
qrpa/shein_mysql.py,sha256=MxbiRSH0gaTtW4ET7lVWRNY4NLOrMLGXO_4STptE1pU,4562
|
|
16
16
|
qrpa/shein_sqlite.py,sha256=i4xwNf60eoG6wbWM1R2i5pDdVW1ZMy6uy9nB-c2WKzk,5554
|
|
17
17
|
qrpa/shein_ziniao.py,sha256=YN7g6m84-vyDyePssfR41lqwaROz-km0-rJ8qY-jhy0,21416
|
|
@@ -22,12 +22,12 @@ qrpa/time_utils.py,sha256=bOTSi_ewXPCxwgG_ndFGf8dl7S4fvSGT9sQ-90LESuo,31458
|
|
|
22
22
|
qrpa/time_utils_example.py,sha256=80zzunKw7F1S8MOwNFmmiCnI8MOYoh4PH-25UrEGuF0,7810
|
|
23
23
|
qrpa/wxwork.py,sha256=Vy8PGEtlTWt4-1laVhuqpJUGCFH2JymgbjvH00aaBog,10946
|
|
24
24
|
qrpa/mysql_module/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
-
qrpa/mysql_module/new_product_analysis_model.py,sha256=
|
|
25
|
+
qrpa/mysql_module/new_product_analysis_model.py,sha256=nLBxgzcBHofiORETEycWMUliG-9mEErGih9TmBClxkM,18615
|
|
26
26
|
qrpa/mysql_module/shein_ledger_model.py,sha256=KGKfGyzS00rbBZhiZhAzypwYPGs7OdfRLnH2ea36Vm8,18161
|
|
27
27
|
qrpa/mysql_module/shein_product_model.py,sha256=KiXMjPT93XkANCM53cCFaISja0sTmAWsionFrRy8DQ4,18773
|
|
28
28
|
qrpa/mysql_module/shein_return_order_model.py,sha256=8xvKhOzpcJS5FHfyA33UednaqRNCyXo3qeXBzwTXeN8,25993
|
|
29
29
|
qrpa/mysql_module/shein_store_model.py,sha256=tSXB7w8gmLXQfvuzk3te4OL1Tok-kEgGPYrCutDrzSw,20469
|
|
30
|
-
qrpa-1.1.
|
|
31
|
-
qrpa-1.1.
|
|
32
|
-
qrpa-1.1.
|
|
33
|
-
qrpa-1.1.
|
|
30
|
+
qrpa-1.1.36.dist-info/METADATA,sha256=Xk25QUVlFGW6ET2dpzJB8N9UiPu8BXMxAvZ7MH4kqjU,231
|
|
31
|
+
qrpa-1.1.36.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
32
|
+
qrpa-1.1.36.dist-info/top_level.txt,sha256=F6T5igi0fhXDucPPUbmmSC0qFCDEsH5eVijfVF48OFU,5
|
|
33
|
+
qrpa-1.1.36.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|