qrpa 1.0.22__py3-none-any.whl → 1.0.24__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/shein_lib.py CHANGED
@@ -22,6 +22,7 @@ class SheinLib:
22
22
  self.store_name = store_name
23
23
  self.web_page = web_page
24
24
  self.dt = None
25
+ self.DictQueryTime = {}
25
26
 
26
27
  self.deal_auth()
27
28
 
@@ -82,6 +83,160 @@ class SheinLib:
82
83
  # web_page.goto('https://sso.geiwohuo.com')
83
84
  log('鉴权处理结束')
84
85
 
86
+ def get_comment_list(self):
87
+ cache_file = f'{self.config.auto_dir}/shein/dict/comment_list_{TimeUtils.today_date()}.json'
88
+ comment_list = read_dict_from_file_ex(cache_file, self.store_username, 3600)
89
+ if len(comment_list) > 0:
90
+ return comment_list
91
+
92
+ page_num = 1
93
+ page_size = 50
94
+
95
+ yesterday = TimeUtils.get_yesterday()
96
+
97
+ url = f"https://sso.geiwohuo.com/gsp/goods/comment/list"
98
+ payload = {
99
+ "page" : page_num,
100
+ "perPage" : page_size,
101
+ "startCommentTime": f"{yesterday} 00:00:00",
102
+ "commentEndTime" : f"{yesterday} 23:59:59",
103
+ "commentStarList" : ["3", "2", "1"]
104
+ }
105
+ response_text = fetch(self.web_page, url, payload)
106
+ error_code = response_text.get('code')
107
+ if str(error_code) != '0':
108
+ raise send_exception(json.dumps(response_text, ensure_ascii=False))
109
+
110
+ comment_list = response_text['info']['data']
111
+ total = response_text['info']['meta']['count']
112
+ totalPage = math.ceil(total / page_size)
113
+
114
+ for page in range(2, totalPage + 1):
115
+ log(f'获取评价列表 第{page}/{totalPage}页')
116
+ page_num = page
117
+ payload['page'] = page_num
118
+ response_text = fetch(self.web_page, url, payload)
119
+ comment_list = response_text['info']['data']
120
+ time.sleep(0.1)
121
+
122
+ write_dict_to_file_ex(cache_file, {self.store_username: comment_list}, [self.store_username])
123
+ return comment_list
124
+
125
+ def get_last_month_outbound_amount(self):
126
+ url = "https://sso.geiwohuo.com/mils/report/month/list"
127
+ start, end = TimeUtils.get_current_year_range()
128
+ payload = {
129
+ "reportDateStart": start, "reportDateEnd": end, "pageNumber": 1, "pageSize": 50
130
+ }
131
+ response_text = fetch(self.web_page, url, payload)
132
+ error_code = response_text.get('code')
133
+ if str(error_code) != '0':
134
+ raise send_exception(json.dumps(response_text, ensure_ascii=False))
135
+ info = response_text.get('info')
136
+ lst = info.get('data', {}).get('list', [])
137
+ if not lst:
138
+ log(f'⚠️ {self.store_name} 最近一个月无出库记录,金额为0')
139
+ return 0
140
+
141
+ last_item = lst[-1]
142
+ log(f'正在获取 {self.store_name} 最近一个月出库金额: {last_item["totalCustomerAmount"]}')
143
+ return last_item['totalCustomerAmount']
144
+
145
+ def get_funds_data(self):
146
+ log(f'正在获取 {self.store_name} 财务数据')
147
+ url = "https://sso.geiwohuo.com/sso/homePage/dataOverview/v2/detail"
148
+ payload = {
149
+ "metaIndexIds": [
150
+ 298,
151
+ 67,
152
+ 70,
153
+ 72
154
+ ],
155
+ }
156
+ response_text = fetch(self.web_page, url, payload)
157
+ error_code = response_text.get('code')
158
+ if str(error_code) != '0':
159
+ raise send_exception(json.dumps(response_text, ensure_ascii=False))
160
+ info = response_text.get('info')
161
+ num298 = 0 # 在途商品金额
162
+ num67 = 0 # 在仓商品金额
163
+ num70 = 0 # 待结算金额
164
+ num72 = 0 # 可提现金额
165
+ for item in info['list']:
166
+ if item['metaIndexId'] == 298:
167
+ num298 = item['count']
168
+ if item['metaIndexId'] == 67:
169
+ num67 = item['count']
170
+ if item['metaIndexId'] == 70:
171
+ num70 = item['count']
172
+ if item['metaIndexId'] == 72:
173
+ num72 = item['count']
174
+
175
+ outAmount = self.get_last_month_outbound_amount()
176
+ dict_store = read_dict_from_file(self.config.shein_store_alias)
177
+ store_manager = dict_store.get(str(self.store_username).lower())
178
+ NotifyItem = [f'{self.store_name}', self.store_username, store_manager, num298, num67, num70, num72, outAmount, '',
179
+ TimeUtils.current_datetime()]
180
+
181
+ cache_file = f'{self.config.auto_dir}/shein/cache/stat_fund_{TimeUtils.today_date()}.json'
182
+ write_dict_to_file_ex(cache_file, {self.store_username: NotifyItem}, [self.store_username])
183
+ return NotifyItem
184
+
185
+ def getQueryDate(self):
186
+ query_time = self.DictQueryTime.get(self.store_username, None)
187
+ if query_time is not None:
188
+ log(f'从字典获取query_time: {query_time}')
189
+ return query_time
190
+ log('获取日期范围')
191
+ url = "https://sso.geiwohuo.com/mgs-api-prefix/estimate/queryDateRange"
192
+ payload = {}
193
+ response_text = fetch(self.web_page, url, payload)
194
+ error_code = response_text.get('code')
195
+ if str(error_code) != '0':
196
+ raise send_exception(json.dumps(response_text, ensure_ascii=False))
197
+ query_time = response_text.get('info').get('quality_goods_query_time')
198
+ self.DictQueryTime.update({self.store_username: query_time})
199
+ log(f'query_time: {query_time}')
200
+ return query_time
201
+
202
+ def get_goods_quality_estimate_list(self, query_date):
203
+ cache_file = f'{self.config.auto_dir}/shein/dict/googs_estimate_{query_date}.json'
204
+ estimate_list = read_dict_from_file_ex(cache_file, self.store_username, 3600 * 8)
205
+ if len(estimate_list) > 0:
206
+ return estimate_list
207
+
208
+ page_num = 1
209
+ page_size = 100
210
+
211
+ url = f"https://sso.geiwohuo.com/mgs-api-prefix/estimate/queryNewQualityGoodsList"
212
+ payload = {
213
+ "page_no" : page_num,
214
+ "page_size" : page_size,
215
+ "start_date": query_date,
216
+ "end_date" : query_date,
217
+ "order_col" : "skc_sale_cnt_14d",
218
+ "order_type": "desc"
219
+ }
220
+ response_text = fetch(self.web_page, url, payload, {'lan': 'CN'})
221
+ error_code = response_text.get('code')
222
+ if str(error_code) != '0':
223
+ raise send_exception(json.dumps(response_text, ensure_ascii=False))
224
+
225
+ estimate_list = response_text['info']['data']
226
+ total = response_text['info']['meta']['count']
227
+ totalPage = math.ceil(total / page_size)
228
+
229
+ for page in range(2, totalPage + 1):
230
+ log(f'获取质量评估列表 第{page}/{totalPage}页')
231
+ page_num = page
232
+ payload['page'] = page_num
233
+ response_text = fetch(self.web_page, url, payload)
234
+ estimate_list = response_text['info']['data']
235
+ time.sleep(0.1)
236
+
237
+ write_dict_to_file_ex(cache_file, {self.store_username: estimate_list}, [self.store_username])
238
+ return estimate_list
239
+
85
240
  # 已上架备货款A数量
86
241
  def get_product_bak_A_count(self):
87
242
  url = "https://sso.geiwohuo.com/idms/goods-skc/list"
qrpa/temu_chrome.py ADDED
@@ -0,0 +1,56 @@
1
+ from playwright.sync_api import sync_playwright, Page
2
+ from qrpa import get_progress_json_ex, done_progress_json_ex, send_exception
3
+ from qrpa import TemuLib, get_chrome_page_v3, log
4
+
5
+ from typing import Literal, Optional, Callable, List, Dict, Any
6
+
7
+ """不要test开头命名文件 否则会用pytest运行这个程序"""
8
+
9
+ def temu_chrome_excute(settings, run_prepare: Optional[Callable] = None, run: Optional[Callable] = None, run_summary: Optional[Callable] = None, run_notify: Optional[Callable] = None, key_id: Optional[str] = None, just_usernames: Optional[List] = None, just_mall_ids: Optional[List] = None):
10
+ run_prepare()
11
+ with sync_playwright() as p:
12
+ count = 0
13
+ while True:
14
+ try:
15
+ count += 1
16
+ with get_chrome_page_v3(p) as (browser, context, web_page):
17
+ web_page: Page # 显式注解
18
+
19
+ for account in settings.temu_account_list:
20
+ username = account[0]
21
+ password = account[1]
22
+
23
+ if just_usernames and username not in just_usernames:
24
+ continue
25
+
26
+ if get_progress_json_ex(settings, key_id, username):
27
+ continue
28
+
29
+ temu_client = TemuLib(settings, username, password, web_page)
30
+ shop_list = temu_client.get_shop_list()
31
+ # 增加每个店铺的处理进度
32
+ for shop in shop_list:
33
+ mall_id = shop[0]
34
+ mall_name = shop[1]
35
+ if just_mall_ids and mall_id not in just_mall_ids:
36
+ continue
37
+
38
+ store_name = f'{mall_id}_{mall_name}'
39
+ if not get_progress_json_ex(settings, key_id, store_name):
40
+ log(f"正在处理店铺: {mall_name},{mall_id},{username}")
41
+ run(temu_client, web_page, mall_id, mall_name)
42
+ done_progress_json_ex(settings, key_id, store_name)
43
+
44
+ done_progress_json_ex(settings, key_id, username)
45
+
46
+ if not get_progress_json_ex(settings, key_id, 'run_summary'):
47
+ run_summary()
48
+ done_progress_json_ex(settings, key_id, 'run_summary')
49
+ if not get_progress_json_ex(settings, key_id, 'run_notify'):
50
+ run_notify()
51
+ done_progress_json_ex(settings, key_id, 'run_notify')
52
+ break
53
+ except:
54
+ send_exception()
55
+ if count > 1:
56
+ break
qrpa/temu_excel.py ADDED
@@ -0,0 +1,109 @@
1
+ from .fun_excel import *
2
+ from .fun_base import log
3
+ from .fun_file import read_dict_from_file, read_dict_from_file_ex, write_dict_to_file, write_dict_to_file_ex, delete_file
4
+ from .time_utils import TimeUtils
5
+ from .wxwork import WxWorkBot
6
+
7
+ class TemuExcel:
8
+
9
+ def __init__(self, config, bridge):
10
+ self.config = config
11
+ self.bridge = bridge
12
+
13
+ def write_funds(self):
14
+ cache_file = f'{self.config.auto_dir}/temu/cache/funds_{TimeUtils.today_date()}.json'
15
+ dict = read_dict_from_file(cache_file)
16
+ data = []
17
+ for key, val in dict.items():
18
+ data.append(val)
19
+
20
+ excel_path = create_file_path(self.config.excel_temu_fund)
21
+ data.insert(0, ['汇总', '', '', '', ''])
22
+ data.insert(0, ['店铺名称', '总金额', '可用余额', '-', '导出时间'])
23
+ log(data)
24
+ # 删除第 4 列(索引为 3)
25
+ for row in data:
26
+ row.pop(3) # 删除每行中索引为 3 的元素
27
+
28
+ write_data(excel_path, 'Sheet1', data)
29
+
30
+ app, wb, sheet = open_excel(excel_path, 'Sheet1')
31
+ beautify_title(sheet)
32
+ format_to_money(sheet, ['金额', '余额'])
33
+ format_to_datetime(sheet, ['时间'])
34
+ add_sum_for_cell(sheet, ['总金额', '可用余额'])
35
+ add_borders(sheet)
36
+ close_excel(app, wb)
37
+
38
+ def format_purchase_advise_batch(self, sheet):
39
+ beautify_title(sheet)
40
+ format_to_datetime(sheet, ['时间'])
41
+ format_to_number(sheet, ['平均日销', '本地和采购可售天数', '建议采购'], 1)
42
+ add_borders(sheet)
43
+ add_formula_for_column(sheet, '平均日销', '=G2/7')
44
+ add_formula_for_column(sheet, '本地和采购可售天数', '=IF(H2>0,(E2+F2)/H2,0)')
45
+ add_formula_for_column(sheet, '建议采购', '=IF(J2>I2,H2*9,0)')
46
+ colorize_by_field(sheet, 'SKC')
47
+ autofit_column(sheet, ['店铺名称', '商品信息'])
48
+ column_to_left(sheet, ['商品信息'])
49
+ InsertImageV2(sheet, ['SKC图片', 'SKU图片'], 'temu', 120)
50
+
51
+ def write_purchase_advise(self, erp='mb'):
52
+ cache_file = f'{self.config.auto_dir}/temu/cache/warehouse_list_{TimeUtils.today_date()}.json'
53
+ dict = read_dict_from_file(cache_file)
54
+
55
+ store_info = read_dict_from_file(self.config.temu_store_info)
56
+
57
+ header = ['店铺名称', 'SKC图片', 'SKU图片', '商品信息', '现有库存数量', '已采购数量', '近7日销量', '平均日销', '本地和采购可售天数', '生产天数', '建议采购', '产品起定量', '备货周期(天)', 'SKC', '导出时间']
58
+ new_excel_path_list = []
59
+ for mall_id, subOrderList in dict.items():
60
+ excel_data = []
61
+ mall_name = store_info.get(mall_id)[1]
62
+ for product in subOrderList:
63
+ spu = str(product['productId']) # temu平台 spu_id
64
+ skc = str(product['productSkcId']) # temu平台 skc_id
65
+ skcExtCode = product['skcExtCode'] # 商家 SKC货号
66
+ category = product['category'] # 叶子类目
67
+ onSalesDurationOffline = product['onSalesDurationOffline'] # 加入站点时长
68
+ for sku in product['skuQuantityDetailList']:
69
+ priceReviewStatus = sku['priceReviewStatus']
70
+ if priceReviewStatus == 3: # 过滤 开款价格状态 已作废的 2是已生效
71
+ continue
72
+ mall_info = f'{mall_name}\n{mall_id}'
73
+ productSkcPicture = product['productSkcPicture'] # skc图片
74
+ skuExtCode = str(sku['skuExtCode']) # sku货号
75
+ sku_img = self.bridge.get_sku_img(skuExtCode, erp)
76
+ stock = self.bridge.get_sku_stock(skuExtCode, erp)
77
+
78
+ product_info = f"SPU: {spu}\nSKC: {skc}\nSKC货号: {skcExtCode}\nSKU货号: {skuExtCode}\n属性集: {sku['className']}\n类目: {category}\n加入站点时长: {onSalesDurationOffline}天\n"
79
+
80
+ row_item = []
81
+ row_item.append(mall_info)
82
+ row_item.append(productSkcPicture)
83
+ row_item.append(sku_img)
84
+ row_item.append(product_info)
85
+ row_item.append(stock)
86
+ row_item.append(0)
87
+ row_item.append(sku['lastSevenDaysSaleVolume'])
88
+ row_item.append(0)
89
+ row_item.append(0)
90
+ row_item.append(7)
91
+ row_item.append(0)
92
+ row_item.append(0)
93
+ row_item.append(0)
94
+ row_item.append(skc)
95
+ row_item.append(TimeUtils.current_datetime())
96
+ excel_data.append(row_item)
97
+
98
+ new_excel_path = str(self.config.excel_purcase_advice_temu).replace('#store_name#', mall_name).replace(' ', '_')
99
+ new_excel_path_list.append(new_excel_path)
100
+ sheet_name = 'Sheet1'
101
+ data = [header] + excel_data
102
+ close_excel_file(new_excel_path)
103
+ log(new_excel_path)
104
+ batch_excel_operations(new_excel_path, [
105
+ (sheet_name, 'write', sort_by_column(data, 6, 1), ['N']),
106
+ (sheet_name, 'format', self.format_purchase_advise_batch)
107
+ ])
108
+
109
+ return new_excel_path_list
qrpa/temu_lib.py ADDED
@@ -0,0 +1,154 @@
1
+ from .fun_file import read_dict_from_file, write_dict_to_file, read_dict_from_file_ex, write_dict_to_file_ex
2
+ from .fun_base import log, send_exception, md5_string, get_safe_value
3
+ from .time_utils import TimeUtils
4
+
5
+ import json, requests, time, math
6
+
7
+ class TemuLib:
8
+ def __init__(self, config, mobile, password, web_page):
9
+ self.config = config
10
+ self.web_page = web_page
11
+ self.mobile = mobile
12
+
13
+ self.dict_mall = {}
14
+ self.cookie = self.doLoginToTemu(mobile, password)
15
+
16
+ # 主账户登录 返回Cookie
17
+ def doLoginToTemu(self, username, password):
18
+ cache_cookie = f'{self.config.auto_dir}/temu/cookie/cookie_{username}.json'
19
+ dict_cookie = read_dict_from_file(cache_cookie, 1)
20
+ if len(dict_cookie) > 0:
21
+ self.cookie = dict_cookie.get('cookie')
22
+ return
23
+
24
+ log(f'登录Temu账号: {username}')
25
+
26
+ """使用 XPath 登录网站"""
27
+ # 导航到登录页面
28
+ self.web_page.goto("https://seller.kuajingmaihuo.com/login")
29
+ # 输入用户名
30
+ self.web_page.locator('//input[@id="usernameId"]').fill("")
31
+ self.web_page.locator('//input[@id="usernameId"]').fill(username)
32
+ # 输入密码
33
+ self.web_page.locator('//input[@id="passwordId"]').fill("")
34
+ self.web_page.locator('//input[@id="passwordId"]').fill(password)
35
+ # 勾选隐私政策(checkbox)
36
+ self.web_page.locator('//input[@type="checkbox"]/following-sibling::div').click() # 直接check不了 换成点击
37
+ # 点击登录按钮
38
+ self.web_page.locator('//button[span[text()="登录"]]').click()
39
+ # 等待登录完成(根据页面加载情况调整等待策略)
40
+ self.web_page.wait_for_load_state("load")
41
+
42
+ while True:
43
+ log('等待卖家中心出现')
44
+ try:
45
+ if self.web_page.locator('//div[text()="Temu商家中心"]').count() == 1:
46
+ log('卖家中心已出现')
47
+ break
48
+ if self.web_page.locator('//div[text()="Seller Central"]').count() == 1:
49
+ log('卖家中心已出现')
50
+ break
51
+ except Exception as e:
52
+ log(f"❌{e}")
53
+ time.sleep(1.5)
54
+
55
+ log("✅ 登录成功")
56
+
57
+ self.web_page.wait_for_load_state("load")
58
+ self.web_page.wait_for_timeout(3000)
59
+ cookies = self.web_page.context.cookies()
60
+ cookies_list = [cookie for cookie in cookies if '.kuajingmaihuo.com' in cookie['domain']]
61
+ self.cookie = '; '.join([f"{cookie['name']}={cookie['value']}" for cookie in cookies_list])
62
+ log(f'已获取self.cookie:', self.cookie)
63
+ write_dict_to_file(cache_cookie, {'cookie': self.cookie})
64
+ return self.cookie
65
+
66
+ def post_json(self, str_url, payload, mall_id=None):
67
+ global response
68
+ try:
69
+ headers = {
70
+ 'content-type': 'application/json',
71
+ 'priority' : 'u=1, i',
72
+ 'referer' : 'https://seller.kuajingmaihuo.com/settle/site-main',
73
+ 'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
74
+ 'Cookie' : self.cookie,
75
+ }
76
+ if mall_id:
77
+ headers.update({'mallid': f"{mall_id}"})
78
+ response = requests.post(str_url, headers=headers, data=json.dumps(payload))
79
+ response.raise_for_status() # 如果响应不正常,会抛出异常
80
+
81
+ response_text = response.json()
82
+ error_code = response_text.get('error_code') or response_text.get('errorCode')
83
+ if error_code != 1000000:
84
+ raise send_exception(response_text)
85
+ return response.json() # 直接返回 JSON 格式的数据
86
+ except:
87
+ raise send_exception()
88
+
89
+ def get_shop_list(self):
90
+ log(f'获取店铺列表')
91
+ global DictMall
92
+ url = "https://seller.kuajingmaihuo.com/bg/quiet/api/mms/userInfo"
93
+ response_text = self.post_json(url, {})
94
+
95
+ company_list = response_text['result']['companyList']
96
+ mall_list = []
97
+ for company in company_list:
98
+ mallList = company['malInfoList']
99
+ # shop_list = [['店铺ID', '店铺名称', '主账号', '店铺类型']]
100
+ for mall in mallList:
101
+ mall_id = str(mall['mallId'])
102
+ mall_name = str(mall['mallName'])
103
+ shop_info = [mall_id, mall_name, self.mobile, '半托管' if mall['isSemiManagedMall'] else '全托管']
104
+ write_dict_to_file_ex(self.config.temu_store_info, {mall_id: shop_info}, [mall_id])
105
+
106
+ self.dict_mall[str(mall['mallId'])] = mall['mallName']
107
+
108
+ if not mall['isSemiManagedMall']:
109
+ mall_list.append([str(mall['mallId']), mall['mallName'], '', self.mobile])
110
+
111
+ return mall_list
112
+
113
+ def get_funds_info(self, mall_id):
114
+ log(f'获取 {self.dict_mall[mall_id]} 资金信息')
115
+ url = "https://seller.kuajingmaihuo.com/api/merchant/payment/account/amount/info"
116
+ response_text = self.post_json(url, {}, mall_id)
117
+ total_amount = response_text.get('result').get('totalAmount')
118
+ available_amount = response_text.get('result').get('availableBalance')
119
+
120
+ NotifyItem = [self.dict_mall[mall_id], total_amount, available_amount, '', TimeUtils.current_datetime()]
121
+
122
+ cache_file = f'{self.config.auto_dir}/temu/cache/funds_{TimeUtils.today_date()}.json'
123
+ write_dict_to_file_ex(cache_file, {mall_id: NotifyItem}, [mall_id])
124
+
125
+ return NotifyItem
126
+
127
+ def list_warehouse(self, mall_id, mall_name):
128
+ log(f'获取店铺 {mall_name} 销售商品列表 第1页')
129
+ url = "https://seller.kuajingmaihuo.com/marvel-mms/cn/api/kiana/venom/sales/management/listWarehouse"
130
+ payload = {
131
+ "pageNo" : 1,
132
+ "pageSize" : 40,
133
+ "isLack" : 0,
134
+ "selectStatusList" : [12], # 12 是已加入站点
135
+ "priceAdjustRecentDays": 30 # 近30日价格调整
136
+ }
137
+ response_text = self.post_json(url, payload, mall_id)
138
+
139
+ total = response_text['result']['total']
140
+ subOrderListCount = len(response_text['result']['subOrderList'])
141
+ totalPage = math.ceil(total / subOrderListCount) if subOrderListCount else 0
142
+ subOrderList = response_text['result']['subOrderList']
143
+
144
+ for page in range(2, totalPage + 1):
145
+ log(f'获取店铺{mall_name}销售商品列表 第{page}/{totalPage}页')
146
+ payload['pageNo'] = page
147
+ response_text = self.post_json(url, payload, mall_id)
148
+ subOrderList += response_text['result']['subOrderList']
149
+ time.sleep(0.3)
150
+
151
+ cache_file = f'{self.config.auto_dir}/temu/cache/warehouse_list_{TimeUtils.today_date()}.json'
152
+ write_dict_to_file_ex(cache_file, {mall_id: subOrderList}, [mall_id])
153
+
154
+ return subOrderList
qrpa/wxwork.py CHANGED
@@ -41,6 +41,9 @@ class WxWorkBot:
41
41
  response = requests.post(
42
42
  f'https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={self.key}&type=file',
43
43
  headers=headers, files=files)
44
+ response_text = json.loads(response.text)
45
+ if str(response_text.get('errcode')) != '0':
46
+ raise Exception(response_text)
44
47
  if response.status_code == 200:
45
48
  result = json.loads(response.text)
46
49
  return result['media_id']
@@ -190,6 +193,9 @@ class WxWorkBot:
190
193
  "Content-Type": "application/json"
191
194
  }
192
195
  response = requests.post(f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={self.key}", headers=header, data=json.dumps(data))
196
+ response_text = json.loads(response.text)
197
+ if str(response_text.get('errcode')) != '0':
198
+ raise Exception(response_text)
193
199
  if response.status_code == 200:
194
200
  result = json.loads(response.text)
195
201
  return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qrpa
3
- Version: 1.0.22
3
+ Version: 1.0.24
4
4
  Summary: qsir's rpa library
5
5
  Author: QSir
6
6
  Author-email: QSir <1171725650@qq.com>
@@ -0,0 +1,23 @@
1
+ qrpa/RateLimitedSender.py,sha256=hqvb1qspDFaW4RsLuVufylOrefkMgixANKeBaGEqYb4,1421
2
+ qrpa/__init__.py,sha256=-7KlqEQj8qwtMs6xAHh3JB2B-5xDBz273BeZiBQ5Fe4,953
3
+ qrpa/db_migrator.py,sha256=2VmhzcMsU0MKpl-mNCwKyV8tLTqyEysSpP27-S_rQZ8,21862
4
+ qrpa/fun_base.py,sha256=j3sbYInaltsRItUEqt1dhqsijdjvkePV4X4aN34madg,4410
5
+ qrpa/fun_excel.py,sha256=o6Tb_lp3uFc0MpS6NG6N6CTrgUwRABTTHyVY2eMTYDA,105676
6
+ qrpa/fun_file.py,sha256=yzjDV16WL5vRys7J4uQcNzIFkX4D5MAlSCwxcD-mwQo,11966
7
+ qrpa/fun_web.py,sha256=5QLQorAhRzMOGMRh4eCJ2UH8ZhVHvxkHwobWhmgU5qM,6286
8
+ qrpa/fun_win.py,sha256=-LnTeocdTt72NVH6VgLdpAT9_C5oV9okeudXG6CftMA,8034
9
+ qrpa/shein_daily_report_model.py,sha256=H8oZmIN5Pyqe306W1_xuz87lOqLQ_LI5RjXbaxDkIzE,12589
10
+ qrpa/shein_excel.py,sha256=7gFAh7etQB9ChoXZkqPD3fEQA0Y3sm_Ja6UtD_DkfSo,38472
11
+ qrpa/shein_lib.py,sha256=ub0jv9P4Nt8S_DQ77uIQBCULGDWYrkzjwsmPhlUkKq8,85266
12
+ qrpa/shein_sqlite.py,sha256=ZQwD0Gz81q9WY7tY2HMEYvSF9r3N_G_Aur3bYfST9WY,5707
13
+ qrpa/shein_ziniao.py,sha256=nSqqcEPh4nVQtUxUnIRzeZfTLyXywGPjPZn5pP-w57U,18309
14
+ qrpa/temu_chrome.py,sha256=CbtFy1QPan9xJdJcNZj-EsVGhUvv3ZTEPVDEA4-im40,2803
15
+ qrpa/temu_excel.py,sha256=pmXKuCZ1H6A-F7dj0Kg5JjENYPEJO2dr572Q-GkepuI,5447
16
+ qrpa/temu_lib.py,sha256=hYB59zsLS3m3NTic_duTwPMOTSxlHyQVa8OhHnHm-1g,7199
17
+ qrpa/time_utils.py,sha256=ef0hhbN_6b-gcnz5ETIVOoxemIMvcxGVGGIRnHnGaBo,29564
18
+ qrpa/time_utils_example.py,sha256=shHOXKKF3QSzb0SHsNc34M61wEkkLuM30U9X1THKNS8,8053
19
+ qrpa/wxwork.py,sha256=Vy8PGEtlTWt4-1laVhuqpJUGCFH2JymgbjvH00aaBog,10946
20
+ qrpa-1.0.24.dist-info/METADATA,sha256=IUf28BbfVg7_crICn1PvAHv6u_xeOQljmoDtKk_sccg,231
21
+ qrpa-1.0.24.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
+ qrpa-1.0.24.dist-info/top_level.txt,sha256=F6T5igi0fhXDucPPUbmmSC0qFCDEsH5eVijfVF48OFU,5
23
+ qrpa-1.0.24.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- qrpa/RateLimitedSender.py,sha256=hqvb1qspDFaW4RsLuVufylOrefkMgixANKeBaGEqYb4,1421
2
- qrpa/__init__.py,sha256=EysO3QHdHWPWuVmtbekAZBSKSlCIAHnLzg2O6e26nNs,801
3
- qrpa/db_migrator.py,sha256=2VmhzcMsU0MKpl-mNCwKyV8tLTqyEysSpP27-S_rQZ8,21862
4
- qrpa/fun_base.py,sha256=W_owEa8-yuGG18n9kX3remm9YTzym69ztQjtYCNMTw4,3308
5
- qrpa/fun_excel.py,sha256=uaSNvJGA0vopBn0N__tVYpdeX4WlliOAQWP4sHanFUw,104030
6
- qrpa/fun_file.py,sha256=yzjDV16WL5vRys7J4uQcNzIFkX4D5MAlSCwxcD-mwQo,11966
7
- qrpa/fun_web.py,sha256=5QLQorAhRzMOGMRh4eCJ2UH8ZhVHvxkHwobWhmgU5qM,6286
8
- qrpa/fun_win.py,sha256=-LnTeocdTt72NVH6VgLdpAT9_C5oV9okeudXG6CftMA,8034
9
- qrpa/shein_daily_report_model.py,sha256=C2ZE3XhLEZdV4Imdz7gE6756apSWyVku-hVKy4BOAwg,12588
10
- qrpa/shein_excel.py,sha256=BLCpnxi_M26R2hdlECmTrWd3GVCvwKm6cgqnLD5Ilbc,29191
11
- qrpa/shein_lib.py,sha256=IurTKa-K5Ay6DCOSv-cxiz1N6uvFKrxpxvREkua78FE,78696
12
- qrpa/shein_sqlite.py,sha256=ZQwD0Gz81q9WY7tY2HMEYvSF9r3N_G_Aur3bYfST9WY,5707
13
- qrpa/shein_ziniao.py,sha256=nSqqcEPh4nVQtUxUnIRzeZfTLyXywGPjPZn5pP-w57U,18309
14
- qrpa/time_utils.py,sha256=ef0hhbN_6b-gcnz5ETIVOoxemIMvcxGVGGIRnHnGaBo,29564
15
- qrpa/time_utils_example.py,sha256=shHOXKKF3QSzb0SHsNc34M61wEkkLuM30U9X1THKNS8,8053
16
- qrpa/wxwork.py,sha256=zu6eQZHJEpwe4Q6vvwmBJaU31qm0bixII_XC9uJIrJc,10618
17
- qrpa-1.0.22.dist-info/METADATA,sha256=ugQ2bx-icC0GEM1Uq2MDmZaws0rTyltOTrcM5ZvRf5o,231
18
- qrpa-1.0.22.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
- qrpa-1.0.22.dist-info/top_level.txt,sha256=F6T5igi0fhXDucPPUbmmSC0qFCDEsH5eVijfVF48OFU,5
20
- qrpa-1.0.22.dist-info/RECORD,,
File without changes