mns-common 1.5.1.4__py3-none-any.whl → 1.5.1.6__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 mns-common might be problematic. Click here for more details.

@@ -1,6 +1,5 @@
1
- import sys
2
1
  import os
3
- import time
2
+ import sys
4
3
 
5
4
  file_path = os.path.abspath(__file__)
6
5
  end = file_path.index('mns') + 16
@@ -12,7 +11,6 @@ import json
12
11
  import pandas as pd
13
12
  from concurrent.futures import ThreadPoolExecutor
14
13
  import datetime
15
- from loguru import logger
16
14
  import mns_common.utils.data_frame_util as data_frame_util
17
15
 
18
16
  mongodb_util = MongodbUtil('27017')
@@ -69,7 +67,7 @@ def get_stock_page_data(pn, proxies, page_size):
69
67
  global max_number
70
68
  max_number = int(data_text[begin_index_total + 8:end_index_total - 1])
71
69
  except Exception as e:
72
- logger.error(f"获取第{pn}页股票列表异常: {e}")
70
+ # logger.error(f"获取第{pn}页股票列表异常: {e}")
73
71
  return pd.DataFrame()
74
72
 
75
73
  begin_index = data_text.index('[')
@@ -79,9 +77,11 @@ def get_stock_page_data(pn, proxies, page_size):
79
77
  if data_json is None:
80
78
  return pd.DataFrame()
81
79
  else:
82
- return pd.DataFrame(data_json)
80
+ result_df = pd.DataFrame(data_json)
81
+ result_df['page_number'] = pn
82
+ return result_df
83
83
  except Exception as e:
84
- logger.error(f"获取第{pn}页股票列表异常: {e}")
84
+ # logger.error(f"获取第{pn}页股票列表异常: {e}")
85
85
  return pd.DataFrame()
86
86
 
87
87
 
@@ -290,16 +290,87 @@ def get_sum_north_south_net_buy_amt():
290
290
  return df
291
291
 
292
292
 
293
+ def get_real_time_quotes_ip_pool(proxies_pool, timeout_time, show_msg):
294
+ page_df = all_stock_ticker_data_ip_pools(proxies_pool, timeout_time, show_msg)
295
+ page_df = rename_real_time_quotes_df(page_df)
296
+ page_df.drop_duplicates('symbol', keep='last', inplace=True)
297
+ return page_df
298
+
299
+
300
+ def all_stock_ticker_data_ip_pools(proxies_pool, timeout_time: str, show_msg) -> pd.DataFrame:
301
+ """
302
+ 使用多线程获取所有股票数据,支持代理池,并避免超时死循环
303
+ :param proxies_pool: 代理池列表
304
+ :param timeout_time: 代理过期时间,格式为 "YYYY-MM-DD HH:MM:SS"
305
+ :return: 股票数据的 DataFrame
306
+ """
307
+ # 将timeout_time字符串转化为 datetime 对象
308
+ timeout_time = datetime.datetime.strptime(timeout_time, "%Y-%m-%d %H:%M:%S")
309
+
310
+ if datetime.datetime.now() > timeout_time:
311
+ logger.info("当前时间已超过: {},终止请求。", timeout_time)
312
+ return pd.DataFrame() # 返回空DataFrame,表示结束
313
+
314
+ per_page = PAGE_SIZE
315
+ total_pages = (max_number + per_page - 1) // per_page # 向上取整
316
+ results = []
317
+
318
+ def get_page_data_with_retries(pn, proxy_list):
319
+ """
320
+ 使用代理池并重试,直到获取成功或超过超时时间
321
+ """
322
+ proxy_index = 0
323
+ while True:
324
+ # 检查当前时间是否超过了超时时间
325
+ if datetime.datetime.now() > timeout_time:
326
+ logger.info("当前时间已超过: {},终止请求。", timeout_time)
327
+ return pd.DataFrame() # 返回空DataFrame,表示结束
328
+
329
+ proxy_ip = proxy_list[proxy_index]
330
+
331
+ proxies = {"https": proxy_ip,
332
+ "http": proxy_ip}
333
+
334
+ # 获取当前代理
335
+ result = get_stock_page_data(pn, proxies, PAGE_SIZE)
336
+ if not result.empty:
337
+ return result
338
+ else:
339
+ # 如果当前代理失败,切换到下一个代理
340
+ proxy_index = (proxy_index + 1) % len(proxy_list)
341
+ if show_msg:
342
+ logger.warning("页面 {} 获取失败,尝试使用代理 {} 重新获取.", pn, proxy_list[proxy_index])
343
+
344
+ # 创建线程池
345
+ with ThreadPoolExecutor(max_workers=10) as executor:
346
+ # 提交任务,获取每页数据
347
+ futures = [executor.submit(get_page_data_with_retries, pn, proxies_pool) for pn in range(1, total_pages + 1)]
348
+
349
+ # 收集结果
350
+ for future in futures:
351
+ result = future.result()
352
+ if result.empty:
353
+ break # 如果返回空的DataFrame(即超时),则退出循环
354
+ results.append(result)
355
+
356
+ # 合并所有页面的数据
357
+ if results:
358
+ return pd.concat(results, ignore_index=True)
359
+ else:
360
+ return pd.DataFrame()
361
+
362
+
363
+ # 示例调用
364
+ import mns_common.component.proxies.proxy_common_api as proxy_common_api
365
+ from loguru import logger
366
+
293
367
  # 示例调用
294
368
  if __name__ == "__main__":
369
+
295
370
  while True:
296
- ip_proxy_pool = mongodb_util.find_all_data('ip_proxy_pool')
297
- if data_frame_util.is_not_empty(ip_proxy_pool):
298
- proxy_ip = list(ip_proxy_pool['ip'])[0]
299
- proxy = {
300
- "https": proxy_ip}
301
- df = get_real_time_quotes_all_stocks(proxy)
302
- logger.info("涨停数据,{}", 1)
303
- else:
304
- time.sleep(1)
305
- logger.error("ip为空")
371
+ result = proxy_common_api.get_proxy_ip_pool(3, 50, 3)
372
+ ip_pool_list = result['ip_pool']
373
+ effect_time = result['effect_time']
374
+
375
+ test_df = get_real_time_quotes_ip_pool(ip_pool_list, effect_time, False)
376
+ logger.info(test_df)
@@ -57,9 +57,46 @@ def get_proxy_api(order_id, secret, unbind_time):
57
57
  return None
58
58
 
59
59
 
60
+ # 线程池
61
+ def get_proxy_pool_api(order_id, secret, unbind_time, ip_num):
62
+ num = str(ip_num)
63
+ pid = "-1"
64
+ cid = ""
65
+ noDuplicate = "1"
66
+ lineSeparator = "0"
67
+ singleIp = "0"
68
+ time_str = str(int(time.time())) # 时间戳
69
+
70
+ # 计算sign
71
+ txt = "orderId=" + order_id + "&" + "secret=" + secret + "&" + "time=" + time_str
72
+ sign = hashlib.md5(txt.encode()).hexdigest()
73
+ # 访问URL获取IP
74
+ url = (
75
+ "http://api.hailiangip.com:8422/api/getIp?type=1" + "&num=" + num + "&pid=" + pid
76
+ + "&unbindTime=" + unbind_time + "&cid=" + cid
77
+ + "&orderId=" + order_id + "&time=" + time_str + "&sign=" + sign + "&dataType=0"
78
+ + "&lineSeparator=" + lineSeparator + "&noDuplicate=" + noDuplicate + "&singleIp=" + singleIp)
79
+ my_response = requests.get(url).content
80
+ js_res = json.loads(my_response)
81
+ ip_pool_list = []
82
+ for dic in js_res["data"]:
83
+ try:
84
+ ip = dic["ip"]
85
+ port = dic["port"]
86
+ ip_port = ip + ":" + str(port)
87
+ ip_pool_list.append(ip_port)
88
+ except BaseException as e:
89
+ logger.error("获取ip地址异常:{}", e)
90
+ return None
91
+ return ip_pool_list
92
+
93
+
94
+
95
+
96
+
60
97
  if __name__ == '__main__':
61
- order_id = ''
62
- secret = ''
63
- unbind_time = str(60 * 10)
64
- ip = get_proxy_api(order_id, secret, unbind_time)
98
+ order_id_test = ''
99
+ secret_test = ''
100
+ unbind_time_test = str(60 * 10)
101
+ ip = get_proxy_api(order_id_test, secret_test, unbind_time_test)
65
102
  print(ip)
@@ -203,3 +203,8 @@ def symbol_add_prefix(symbol):
203
203
  return '0.' + symbol_simple
204
204
  else:
205
205
  return '0.' + symbol_simple
206
+
207
+
208
+ # 排除改变代码的北交所
209
+ def exclude_change_bjs_code(df):
210
+ return df[~df['symbol'].str.startswith(('8', '4'))]
@@ -12,7 +12,6 @@ import mns_common.utils.data_frame_util as data_frame_util
12
12
  from mns_common.db.MongodbUtil import MongodbUtil
13
13
  import mns_common.constant.db_name_constant as db_name_constant
14
14
  import datetime
15
- import requests
16
15
  import time
17
16
  from loguru import logger
18
17
  from functools import lru_cache
@@ -21,23 +20,25 @@ import threading
21
20
 
22
21
  mongodb_util = MongodbUtil('27017')
23
22
 
23
+ IP_POOL = 'ip_pool'
24
+ ONE_IP = 'one_ip'
25
+ query_one = {'ip_type': ONE_IP}
26
+ query_pool = {'ip_type': IP_POOL}
27
+
24
28
 
25
29
  def query_liu_guan_proxy_ip():
26
- ip_proxy_pool = mongodb_util.find_all_data(db_name_constant.IP_PROXY_POOL)
30
+ ip_proxy_pool = mongodb_util.find_one_query(db_name_constant.IP_PROXY_POOL, query_one)
27
31
  return ip_proxy_pool
28
32
 
29
33
 
30
34
  def remove_proxy_ip():
31
- mongodb_util.remove_data({}, db_name_constant.IP_PROXY_POOL)
35
+ mongodb_util.remove_data(query_one, db_name_constant.IP_PROXY_POOL)
32
36
 
33
37
 
34
38
  def check_valid(ip_proxy_pool):
35
39
  effect_time = list(ip_proxy_pool['effect_time'])[0]
36
-
37
40
  now_date = datetime.datetime.now()
38
-
39
41
  str_now_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
40
-
41
42
  if effect_time > str_now_date:
42
43
  return True
43
44
  else:
@@ -47,7 +48,7 @@ def check_valid(ip_proxy_pool):
47
48
 
48
49
  @lru_cache(maxsize=None)
49
50
  def get_account_cache():
50
- query = {"type": "liu_guan_proxy", }
51
+ query = {"type": "liu_guan_proxy"}
51
52
  return mongodb_util.find_query_data(db_name_constant.STOCK_ACCOUNT_INFO, query)
52
53
 
53
54
 
@@ -77,6 +78,7 @@ def generate_proxy_ip(minutes):
77
78
  ip = generate_proxy_ip_api(minutes)
78
79
  if check_proxy(ip):
79
80
  result_dict = {"_id": ip,
81
+ 'ip_type': ONE_IP,
80
82
  'effect_time': str_now_date,
81
83
  'ip': ip}
82
84
  result_df = pd.DataFrame(result_dict, index=[1])
@@ -113,6 +115,73 @@ def check_proxy(proxy_ip):
113
115
  return False
114
116
 
115
117
 
118
+ # 查询ip池子
119
+ def query_liu_guan_proxy_ip_pool():
120
+ ip_proxy_pool = mongodb_util.find_query_data(db_name_constant.IP_PROXY_POOL, query_pool)
121
+ return ip_proxy_pool
122
+
123
+
124
+ def remove_proxy_ip_pool():
125
+ mongodb_util.remove_data(query_pool, db_name_constant.IP_PROXY_POOL)
126
+
127
+
128
+ def generate_proxy_ip_pool_api(minutes, ip_num):
129
+ stock_account_info = get_account_cache()
130
+ order_id = list(stock_account_info['password'])[0]
131
+ secret = list(stock_account_info['account'])[0]
132
+ # 获取10分钟动态ip
133
+ ip_pool = liu_guan_proxy_api.get_proxy_pool_api(order_id, secret, str(60 * minutes), ip_num)
134
+ return ip_pool
135
+
136
+
137
+ def get_proxy_ip_pool(minutes, seconds, ip_num):
138
+ ip_proxy_pool = query_liu_guan_proxy_ip_pool()
139
+ if data_frame_util.is_empty(ip_proxy_pool):
140
+ return generate_proxy_ip_pool(minutes, seconds, ip_num)
141
+ else:
142
+ if check_valid(ip_proxy_pool):
143
+ ip_pool = list(ip_proxy_pool['ip_pool'])[0]
144
+ effect_time = list(ip_proxy_pool['effect_time'])[0]
145
+ result = {'ip_pool': ip_pool,
146
+ 'effect_time': effect_time}
147
+ return result
148
+ else:
149
+ # 已经失效 移除ip pool
150
+ remove_proxy_ip_pool()
151
+ # 重新生成
152
+ return generate_proxy_ip_pool(minutes, seconds, ip_num)
153
+
154
+
155
+ # seconds 有效秒数,minutes 需要减1
156
+ def generate_proxy_ip_pool(minutes, seconds, ip_num):
157
+ ip_proxy_pool = query_liu_guan_proxy_ip_pool()
158
+ if data_frame_util.is_not_empty(ip_proxy_pool):
159
+ ip_pool = list(ip_proxy_pool['ip_pool'])[0]
160
+ effect_time = list(ip_proxy_pool['effect_time'])[0]
161
+
162
+
163
+ else:
164
+ remove_proxy_ip_pool()
165
+ now_date = datetime.datetime.now()
166
+ # 加上分钟 少10秒
167
+ time_to_add = datetime.timedelta(minutes=minutes - 1, seconds=seconds)
168
+ new_date = now_date + time_to_add
169
+ effect_time = new_date.strftime('%Y-%m-%d %H:%M:%S')
170
+ ip_pool = generate_proxy_ip_pool_api(minutes, ip_num)
171
+ result_dict = {
172
+ "_id": [IP_POOL],
173
+ 'ip_type': [IP_POOL],
174
+ 'effect_time': [effect_time],
175
+ 'ip_pool': [ip_pool] # 每个字段都包装成列表
176
+ }
177
+ result_df = pd.DataFrame(result_dict)
178
+
179
+ mongodb_util.insert_mongo(result_df, db_name_constant.IP_PROXY_POOL)
180
+ result = {'ip_pool': ip_pool,
181
+ 'effect_time': effect_time}
182
+ return result
183
+
184
+
116
185
  def get_em_real_time_data(proxy_ip):
117
186
  proxies = {
118
187
  "http": proxy_ip,
@@ -153,4 +222,4 @@ def call_with_timeout(func, *args, timeout=2, **kwargs):
153
222
 
154
223
 
155
224
  if __name__ == "__main__":
156
- generate_proxy_ip(1)
225
+ get_proxy_ip_pool(1, 50, 2)
@@ -1,4 +1,4 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mns-common
3
- Version: 1.5.1.4
3
+ Version: 1.5.1.6
4
4
 
@@ -15,7 +15,7 @@ mns_common/api/em/gd/east_money_stock_gdfx_free_top_10_api.py,sha256=I2-JjFjTjvO
15
15
  mns_common/api/em/real_time/__init__.py,sha256=wEg73KlZo-dU0yKGwpA1C2y6LZm4IBb94tNda1tqLeg,163
16
16
  mns_common/api/em/real_time/east_money_debt_api.py,sha256=jMvMZtlrDfExl_4jZ1hepHX8rUoeVLoLSOIhRBjkUGk,14753
17
17
  mns_common/api/em/real_time/east_money_etf_api.py,sha256=tCyH4fNx-KfVRFuNGkgM8d_xkvR0oAfr8T3e7_XrjTM,14414
18
- mns_common/api/em/real_time/east_money_stock_a_api.py,sha256=6xYcNJyMhFFL2eNxQ9c0TbQ53wgumNovVHisXgQX7bs,12737
18
+ mns_common/api/em/real_time/east_money_stock_a_api.py,sha256=e_hPYJnNhjDOecTW5myorxEaDvuPku4pssuP9JIghG4,15621
19
19
  mns_common/api/em/real_time/east_money_stock_a_v2_api.py,sha256=mL4uuL6sVsC2Vnl09826AUnzxePGAUhlZ7I5BBFw8Ks,14530
20
20
  mns_common/api/em/real_time/east_money_stock_hk_api.py,sha256=KFIYUZ3N4ULrataeCIXwZPo775O7joKgMF466uwVDdY,15154
21
21
  mns_common/api/em/real_time/east_money_stock_us_api.py,sha256=RiTrdZDuDgTOtiMSD1Ba9aQAx4vghM66pEp_LicH3Ps,11632
@@ -43,7 +43,7 @@ mns_common/api/kpl/symbol/symbol_his_quotes_api.py,sha256=5F9L8V2UI_YUYe2dO6FbVK
43
43
  mns_common/api/msg/__init__.py,sha256=2U9DiKslxsWwLLEcZKjS8UiQPN1QgALvnK3HiJNIZE0,163
44
44
  mns_common/api/msg/push_msg_api.py,sha256=z8jDqFWygfxnCFFfQp4K-llgg27nRLv7Mx72lOddBH0,1390
45
45
  mns_common/api/proxies/__init__.py,sha256=wEg73KlZo-dU0yKGwpA1C2y6LZm4IBb94tNda1tqLeg,163
46
- mns_common/api/proxies/liu_guan_proxy_api.py,sha256=VASqcWnKyAEmF4UYNY39Jazh45qugVMYblRrdKfQFuE,1923
46
+ mns_common/api/proxies/liu_guan_proxy_api.py,sha256=CheM7j_028uofZBn4wN1bNkDuyK7pNg1PzAaSf8lYAc,3204
47
47
  mns_common/api/qmt/__init__.py,sha256=wEg73KlZo-dU0yKGwpA1C2y6LZm4IBb94tNda1tqLeg,163
48
48
  mns_common/api/qmt/qmt_minunte_tick_data.py,sha256=uwSw_AkA9RaD3pXPKzxqi4TKEkpglmFUwtYl9r5E6G8,3019
49
49
  mns_common/api/ths/__init__.py,sha256=2U9DiKslxsWwLLEcZKjS8UiQPN1QgALvnK3HiJNIZE0,163
@@ -74,7 +74,7 @@ mns_common/api/us/ths_us_company_info_api.py,sha256=qQjv4F-ovQ2uuu-FlBAnxjvVA7qj
74
74
  mns_common/api/xueqiu/__init__.py,sha256=wEg73KlZo-dU0yKGwpA1C2y6LZm4IBb94tNda1tqLeg,163
75
75
  mns_common/api/xueqiu/xue_qiu_k_line_api.py,sha256=yABuo5AsJRj6ElXkq8Xzwe-LIWzS0fo-g2fJtzLswoA,3535
76
76
  mns_common/component/__init__.py,sha256=2U9DiKslxsWwLLEcZKjS8UiQPN1QgALvnK3HiJNIZE0,163
77
- mns_common/component/common_service_fun_api.py,sha256=t-p0DWJXA870p-1v6416rlovXAF_OQsAMl_u909MwH0,7130
77
+ mns_common/component/common_service_fun_api.py,sha256=cVPG3dzn1XKvjmmeaWHRPbC_mzGoxeC2ffo45FBEIqY,7259
78
78
  mns_common/component/cache/__init__.py,sha256=2U9DiKslxsWwLLEcZKjS8UiQPN1QgALvnK3HiJNIZE0,163
79
79
  mns_common/component/cache/cache_service.py,sha256=QX7tjR1iGsoCyGt6O41w8aRbZ-3xXQ-53Ps3nmUzAGQ,809
80
80
  mns_common/component/classify/__init__.py,sha256=wEg73KlZo-dU0yKGwpA1C2y6LZm4IBb94tNda1tqLeg,163
@@ -116,7 +116,7 @@ mns_common/component/k_line/patterns/pattern_Enum.py,sha256=bl8cH1H3BWdj_deVO124
116
116
  mns_common/component/price/__init__.py,sha256=wEg73KlZo-dU0yKGwpA1C2y6LZm4IBb94tNda1tqLeg,163
117
117
  mns_common/component/price/trade_price_service_api.py,sha256=0loBjbOt__o-ngc2Q4n5lF8_0x2WINRpL-cH1341Uaw,4396
118
118
  mns_common/component/proxies/__init__.py,sha256=wEg73KlZo-dU0yKGwpA1C2y6LZm4IBb94tNda1tqLeg,163
119
- mns_common/component/proxies/proxy_common_api.py,sha256=N2VaiEQ15KycjSNmCHAguR1xiASZzJu1y24NhFCr7BA,4663
119
+ mns_common/component/proxies/proxy_common_api.py,sha256=GuMGK7kAOLqGv_NbRbdQlq_vhVjF3iT58pYkJoFOmCY,7302
120
120
  mns_common/component/qmt/__init__.py,sha256=wEg73KlZo-dU0yKGwpA1C2y6LZm4IBb94tNda1tqLeg,163
121
121
  mns_common/component/qmt/qmt_buy_service.py,sha256=tLTgrSxCcxuMhADRBBrW4ZWR_3MdbMZvvMdH5hbwyJU,7190
122
122
  mns_common/component/real_time/__init__.py,sha256=2U9DiKslxsWwLLEcZKjS8UiQPN1QgALvnK3HiJNIZE0,163
@@ -158,7 +158,7 @@ mns_common/utils/date_handle_util.py,sha256=XS-MyA8_7k35LOCFAYOHgVcVkMft_Kc4Wa9U
158
158
  mns_common/utils/db_util.py,sha256=hSmfNAN4vEeEaUva6_cicZEhb2jSnib-Gvk2reke1vc,2590
159
159
  mns_common/utils/file_util.py,sha256=egWu6PenGPRp_ixrNTHKarT4dAnOT6FETR82EHUZJnQ,1042
160
160
  mns_common/utils/ip_util.py,sha256=UTcYfz_uytB__6nlBf7T-izuI7hi4XdB6ET0sJgEel4,969
161
- mns_common-1.5.1.4.dist-info/METADATA,sha256=pkieOcVjsVxHdYsGMpfzfohYx-DmLR1Lj7lk-mvbxbo,61
162
- mns_common-1.5.1.4.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
163
- mns_common-1.5.1.4.dist-info/top_level.txt,sha256=ZC58kAR-8Hvc6U2xhYNBNLAh3mb6sZazbdj5nZpvEkQ,11
164
- mns_common-1.5.1.4.dist-info/RECORD,,
161
+ mns_common-1.5.1.6.dist-info/METADATA,sha256=PNkBebLDEDMZuxItxFxMN8Gg-Zsl0HEphR7KNuKLf1I,61
162
+ mns_common-1.5.1.6.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
163
+ mns_common-1.5.1.6.dist-info/top_level.txt,sha256=ZC58kAR-8Hvc6U2xhYNBNLAh3mb6sZazbdj5nZpvEkQ,11
164
+ mns_common-1.5.1.6.dist-info/RECORD,,