mns-scheduler 1.0.5.5__tar.gz → 1.0.5.6__tar.gz

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-scheduler might be problematic. Click here for more details.

Files changed (98) hide show
  1. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/PKG-INFO +1 -1
  2. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/company_info/company_info_sync_api.py +24 -2
  3. mns-scheduler-1.0.5.6/mns_scheduler/irm/api/sh_stock_sns_sse_info_api.py +152 -0
  4. mns-scheduler-1.0.5.6/mns_scheduler/irm/api/sz_stock_sns_sse_info_api.py +200 -0
  5. mns-scheduler-1.0.5.6/mns_scheduler/irm/stock_irm_cninfo_service.py +143 -0
  6. mns-scheduler-1.0.5.6/mns_scheduler/risk/__init__.py +7 -0
  7. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zz_task/data_sync_task.py +10 -0
  8. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler.egg-info/PKG-INFO +1 -1
  9. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler.egg-info/SOURCES.txt +3 -0
  10. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/setup.py +1 -1
  11. mns-scheduler-1.0.5.5/mns_scheduler/irm/stock_irm_cninfo_service.py +0 -42
  12. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/README.md +0 -0
  13. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/__init__.py +0 -0
  14. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/backup/__init__.py +0 -0
  15. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/backup/app/__init__.py +0 -0
  16. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/backup/app/ths_new_concept_sync_app.py +0 -0
  17. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/backup/em/__init__.py +0 -0
  18. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/backup/em/em_new_concept_his_sync.py +0 -0
  19. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/backup/em/em_new_concept_sync_common_api.py +0 -0
  20. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/backup/em/em_new_concept_sync_web.py +0 -0
  21. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/backup/wen_cai/__init__.py +0 -0
  22. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/backup/wen_cai/wen_cai_concept_sync.py +0 -0
  23. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/big_deal/__init__.py +0 -0
  24. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/big_deal/ths_big_deal_sync.py +0 -0
  25. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/company_info/__init__.py +0 -0
  26. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/company_info/company_constant_data.py +0 -0
  27. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/company_info/de_list_stock_service.py +0 -0
  28. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/__init__.py +0 -0
  29. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/clean/__init__.py +0 -0
  30. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/clean/kpl_concept_clean_api.py +0 -0
  31. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/clean/ths_concept_clean_api.py +0 -0
  32. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/ths/__init__.py +0 -0
  33. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/ths/common/__init__.py +0 -0
  34. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/ths/common/ths_concept_sync_common_api.py +0 -0
  35. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/ths/common/ths_concept_update_common_api.py +0 -0
  36. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/ths/sync_new_index/__init__.py +0 -0
  37. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/ths/sync_new_index/sync_ths_concept_by_ak_api.py +0 -0
  38. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/ths/sync_new_index/sync_ths_new_concept_by_web_api.py +0 -0
  39. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/ths/update_concept_info/__init__.py +0 -0
  40. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/ths/update_concept_info/sync_one_concept_all_symbols_api.py +0 -0
  41. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/concept/ths/update_concept_info/sync_one_symbol_all_concepts_api.py +0 -0
  42. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/db/__init__.py +0 -0
  43. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/db/col_move_service.py +0 -0
  44. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/db/db_status.py +0 -0
  45. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/dt/__init__.py +0 -0
  46. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/dt/stock_dt_pool_sync.py +0 -0
  47. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/finance/__init__.py +0 -0
  48. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/finance/em_financial_asset_liability_sync_service_api.py +0 -0
  49. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/finance/em_financial_profit_sync_service_api.py +0 -0
  50. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/finance/finance_common_api.py +0 -0
  51. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/finance/financial_high_risk_stock_clean_service_api.py +0 -0
  52. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/finance/sync_financial_report_service_api.py +0 -0
  53. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/finance/test/__init__.py +0 -0
  54. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/finance/test/fix_blask_list.py +0 -0
  55. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/hk/__init__.py +0 -0
  56. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/hk/hk_company_info_sync_service_api.py +0 -0
  57. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/irm/__init__.py +0 -0
  58. {mns-scheduler-1.0.5.5/mns_scheduler/lhb → mns-scheduler-1.0.5.6/mns_scheduler/irm/api}/__init__.py +0 -0
  59. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/k_line/__init__.py +0 -0
  60. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/k_line/clean/__init__.py +0 -0
  61. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/k_line/clean/k_line_info_clean_impl.py +0 -0
  62. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/k_line/clean/k_line_info_clean_service.py +0 -0
  63. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/k_line/clean/recent_hot_stocks_clean_service.py +0 -0
  64. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/k_line/sync/__init__.py +0 -0
  65. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/k_line/sync/daily_week_month_line_sync.py +0 -0
  66. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/kpl/__init__.py +0 -0
  67. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/kpl/selection/__init__.py +0 -0
  68. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/kpl/selection/index/__init__.py +0 -0
  69. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/kpl/selection/index/sync_best_choose_his_index.py +0 -0
  70. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/kpl/selection/index/sync_best_choose_index.py +0 -0
  71. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/kpl/selection/symbol/__init__.py +0 -0
  72. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/kpl/selection/symbol/sync_best_choose_symbol.py +0 -0
  73. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/kpl/selection/total/__init__.py +0 -0
  74. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/kpl/selection/total/sync_kpl_best_total_sync_api.py +0 -0
  75. {mns-scheduler-1.0.5.5/mns_scheduler/risk → mns-scheduler-1.0.5.6/mns_scheduler/lhb}/__init__.py +0 -0
  76. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/lhb/stock_lhb_sync_service.py +0 -0
  77. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/real_time/__init__.py +0 -0
  78. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/real_time/realtime_quotes_now_create_db_index.py +0 -0
  79. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/real_time/realtime_quotes_now_sync.py +0 -0
  80. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/risk/register_and_investigate_stock_sync_api.py +0 -0
  81. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/risk/stock_equity_mortgage_sync_api.py +0 -0
  82. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/trade/__init__.py +0 -0
  83. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/trade/auto_ipo_buy_api.py +0 -0
  84. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/trade/auto_sell_service_api.py +0 -0
  85. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/trade/sync_position_api.py +0 -0
  86. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zb/__init__.py +0 -0
  87. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zb/stock_zb_pool_sync.py +0 -0
  88. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zt/__init__.py +0 -0
  89. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zt/export_open_data_to_excel.py +0 -0
  90. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zt/realtime_quotes_now_zt_kc_sync.py +0 -0
  91. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zt/today_high_chg_pool_sync_api.py +0 -0
  92. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zt/zt_five_boards_sync_api.py +0 -0
  93. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zt/zt_pool_sync_api.py +0 -0
  94. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zz_task/__init__.py +0 -0
  95. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler/zz_task/sync_realtime_quotes_task.py +0 -0
  96. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler.egg-info/dependency_links.txt +0 -0
  97. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/mns_scheduler.egg-info/top_level.txt +0 -0
  98. {mns-scheduler-1.0.5.5 → mns-scheduler-1.0.5.6}/setup.cfg +0 -0
@@ -1,3 +1,3 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mns-scheduler
3
- Version: 1.0.5.5
3
+ Version: 1.0.5.6
@@ -19,8 +19,8 @@ import mns_common.api.kpl.symbol.kpl_real_time_quotes_api as kpl_real_time_quote
19
19
  import mns_common.utils.data_frame_util as data_frame_util
20
20
  import mns_common.api.kpl.constant.kpl_constant as kpl_constant
21
21
  import mns_common.component.company.company_common_service_api as company_common_service_api
22
- import mns_common.constant.db_name_constant as db_name_constant
23
22
  import mns_common.component.k_line.common.k_line_common_service_api as k_line_common_service_api
23
+ import mns_common.constant.db_name_constant as db_name_constant
24
24
 
25
25
  mongodb_util = MongodbUtil('27017')
26
26
  # 分页大小
@@ -105,7 +105,9 @@ def filed_sort(company_info):
105
105
  "ths_concept_list_info",
106
106
  "kpl_plate_name",
107
107
  "kpl_most_relative_name",
108
- "kpl_plate_list_info"
108
+ "kpl_plate_list_info",
109
+ 'operate_profit',
110
+ 'total_operate_income'
109
111
  ]]
110
112
 
111
113
 
@@ -332,6 +334,9 @@ def single_thread_sync_company_info(east_money_stock_info,
332
334
  str_day = now_date.strftime('%Y-%m-%d')
333
335
  deal_days = k_line_common_service_api.get_deal_days(str_day, company_one.symbol)
334
336
  company_info_type['deal_days'] = deal_days
337
+ # 设置年报信息
338
+ company_info_type = get_recent_year_income(company_one.symbol, company_info_type)
339
+
335
340
  try:
336
341
  if data_frame_util.is_not_empty(kpl_real_time_quotes):
337
342
  kpl_real_time_quotes_one = kpl_real_time_quotes.loc[
@@ -480,6 +485,23 @@ def save_sw_data(company_info_type):
480
485
  mongodb_util.save_mongo(third_sw_info, 'sw_industry')
481
486
 
482
487
 
488
+ # 获取最近年报收入
489
+ def get_recent_year_income(symbol, company_info_type):
490
+ query = {'symbol': symbol, "REPORT_TYPE": "年报"}
491
+ em_stock_profit = mongodb_util.descend_query(query, db_name_constant.EM_STOCK_PROFIT, 'REPORT_DATE', 1)
492
+ if data_frame_util.is_not_empty(em_stock_profit):
493
+ company_info_type['operate_profit'] = list(em_stock_profit['OPERATE_PROFIT'])[0]
494
+ company_info_type['total_operate_income'] = list(em_stock_profit['TOTAL_OPERATE_INCOME'])[0]
495
+ else:
496
+ company_info_type['operate_profit'] = 0
497
+ company_info_type['total_operate_income'] = 0
498
+ company_info_type['operate_profit'] = round(
499
+ company_info_type['operate_profit'] / common_service_fun_api.HUNDRED_MILLION, 2)
500
+ company_info_type['total_operate_income'] = round(
501
+ company_info_type['total_operate_income'] / common_service_fun_api.HUNDRED_MILLION, 2)
502
+ return company_info_type
503
+
504
+
483
505
  if __name__ == '__main__':
484
506
  # while True:
485
507
  # df = ths_stock_api.get_company_info_detail('000001')
@@ -0,0 +1,152 @@
1
+ import sys
2
+ import os
3
+
4
+ file_path = os.path.abspath(__file__)
5
+ end = file_path.index('mns') + 16
6
+ project_path = file_path[0:end]
7
+ sys.path.append(project_path)
8
+ # !/usr/bin/env python
9
+ # -*- coding:utf-8 -*-
10
+ """
11
+ Date: 2023/8/4 19:20
12
+ Desc: 上证e互动-提问与回答
13
+ https://sns.sseinfo.com/
14
+ """
15
+ import warnings
16
+ from functools import lru_cache
17
+
18
+ import pandas as pd
19
+ import requests
20
+ from bs4 import BeautifulSoup
21
+ from tqdm import tqdm
22
+
23
+
24
+ @lru_cache()
25
+ def _fetch_stock_uid() -> dict:
26
+ """
27
+ 上证e互动-代码ID映射
28
+ https://sns.sseinfo.com/list/company.do
29
+ :return: 代码ID映射
30
+ :rtype: str
31
+ """
32
+ url = "https://sns.sseinfo.com/allcompany.do"
33
+ data = {
34
+ "code": "0",
35
+ "order": "2",
36
+ "areaId": "0",
37
+ "page": "1",
38
+ }
39
+ uid_list = list()
40
+ code_list = list()
41
+ for page in tqdm(range(1, 73), leave=False):
42
+ data.update({"page": page})
43
+ r = requests.post(url, data=data)
44
+ data_json = r.json()
45
+ soup = BeautifulSoup(data_json["content"], "lxml")
46
+ soup.find_all("a", attrs={"rel": "tag"})
47
+ uid_list.extend(
48
+ [item["uid"] for item in soup.find_all("a", attrs={"rel": "tag"})]
49
+ )
50
+ code_list.extend(
51
+ [
52
+ item.find("img")["src"].split("?")[0].split("/")[-1].split(".")[0]
53
+ for item in soup.find_all("a", attrs={"rel": "tag"})
54
+ ]
55
+ )
56
+ code_uid_map = dict(zip(code_list, uid_list))
57
+ return code_uid_map
58
+
59
+
60
+ def stock_sns_sse_info(symbol: str = "603119") -> pd.DataFrame:
61
+ """
62
+ 上证e互动-提问与回答
63
+ https://sns.sseinfo.com/company.do?uid=65
64
+ :param symbol: 股票代码
65
+ :type symbol: str
66
+ :return: 提问与回答
67
+ :rtype: str
68
+ """
69
+ code_uid_map = _fetch_stock_uid()
70
+ url = "https://sns.sseinfo.com/ajax/userfeeds.do"
71
+ params = {
72
+ "typeCode": "company",
73
+ "type": "11",
74
+ "pageSize": "100",
75
+ "uid": code_uid_map[symbol],
76
+ "page": "1",
77
+ }
78
+ big_df = pd.DataFrame()
79
+ page = 1
80
+ warnings.warn("正在下载中")
81
+ params.update({"page": page})
82
+ r = requests.post(url, params=params)
83
+ if len(r.text) < 300:
84
+ return None
85
+ r = requests.post(url, params=params)
86
+ soup = BeautifulSoup(r.text, "lxml")
87
+ content_list = [
88
+ item.get_text().strip()
89
+ for item in soup.find_all("div", attrs={"class": "m_feed_txt"})
90
+ ]
91
+ date_list = [
92
+ item.get_text().strip().split("\n")[0]
93
+ for item in soup.find_all("div", attrs={"class": "m_feed_from"})
94
+ ]
95
+ source_list = [
96
+ item.get_text().strip().split("\n")[2]
97
+ for item in soup.find_all("div", attrs={"class": "m_feed_from"})
98
+ ]
99
+ q_list = [
100
+ item.split(")")[1]
101
+ for index, item in enumerate(content_list)
102
+ if index % 2 == 0
103
+ ]
104
+ stock_name = [
105
+ item.split("(")[0].strip(":")
106
+ for index, item in enumerate(content_list)
107
+ if index % 2 == 0
108
+ ]
109
+ stock_code = [
110
+ item.split("(")[1].split(")")[0]
111
+ for index, item in enumerate(content_list)
112
+ if index % 2 == 0
113
+ ]
114
+ a_list = [item for index, item in enumerate(content_list) if index % 2 != 0]
115
+ d_q_list = [item for index, item in enumerate(date_list) if index % 2 == 0]
116
+ d_a_list = [item for index, item in enumerate(date_list) if index % 2 != 0]
117
+ s_q_list = [item for index, item in enumerate(source_list) if index % 2 == 0]
118
+ s_a_list = [item for index, item in enumerate(source_list) if index % 2 != 0]
119
+ author_name = [
120
+ item["title"] for item in soup.find_all("a", attrs={"rel": "face"})
121
+ ]
122
+ temp_df = pd.DataFrame(
123
+ [
124
+ stock_code,
125
+ stock_name,
126
+ q_list,
127
+ a_list,
128
+ d_q_list,
129
+ d_a_list,
130
+ s_q_list,
131
+ s_a_list,
132
+ author_name,
133
+ ]
134
+ ).T
135
+ temp_df.columns = [
136
+ "股票代码",
137
+ "公司简称",
138
+ "问题",
139
+ "回答",
140
+ "问题时间",
141
+ "回答时间",
142
+ "问题来源",
143
+ "回答来源",
144
+ "用户名",
145
+ ]
146
+ big_df = pd.concat([big_df, temp_df], ignore_index=True)
147
+ return big_df
148
+
149
+
150
+ if __name__ == "__main__":
151
+ stock_sns_sse_info_df = stock_sns_sse_info(symbol="603119")
152
+ print(stock_sns_sse_info_df)
@@ -0,0 +1,200 @@
1
+ import sys
2
+ import os
3
+
4
+ file_path = os.path.abspath(__file__)
5
+ end = file_path.index('mns') + 16
6
+ project_path = file_path[0:end]
7
+ sys.path.append(project_path)
8
+ # !/usr/bin/env python
9
+ # -*- coding:utf-8 -*-
10
+ """
11
+ Date: 2024/5/12 22:20
12
+ Desc: 互动易-提问与回答
13
+ https://irm.cninfo.com.cn/
14
+ """
15
+
16
+ import pandas as pd
17
+ import requests
18
+
19
+
20
+ def _fetch_org_id(symbol: str = "000001") -> str:
21
+ """
22
+ 股票-互动易-组织代码
23
+ https://irm.cninfo.com.cn/
24
+ :return: 组织代码
25
+ :rtype: str
26
+ """
27
+ url = "https://irm.cninfo.com.cn/newircs/index/queryKeyboardInfo"
28
+ params = {"_t": "1691144074"}
29
+ data = {"keyWord": symbol}
30
+ r = requests.post(url, params=params, data=data)
31
+ data_json = r.json()
32
+ org_id = data_json["data"][0]["secid"]
33
+ return org_id
34
+
35
+
36
+ def stock_irm_cninfo(symbol: str = "002594") -> pd.DataFrame:
37
+ """
38
+ 互动易-提问
39
+ https://irm.cninfo.com.cn/ircs/question/questionDetail?questionId=1515236357817618432
40
+ :param symbol: 股票代码
41
+ :type symbol: str
42
+ :return: 提问
43
+ :rtype: str
44
+ """
45
+ url = "https://irm.cninfo.com.cn/newircs/company/question"
46
+ params = {
47
+ "_t": "1691142650",
48
+ "stockcode": symbol,
49
+ "orgId": _fetch_org_id(symbol),
50
+ "pageSize": "100",
51
+ "pageNum": "1",
52
+ "keyWord": "",
53
+ "startDay": "",
54
+ "endDay": "",
55
+ }
56
+
57
+ big_df = pd.DataFrame()
58
+ page = 1
59
+ params.update({"pageNum": page})
60
+ r = requests.post(url, params=params)
61
+ data_json = r.json()
62
+ temp_df = pd.DataFrame(data_json["rows"])
63
+ big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
64
+ big_df.rename(
65
+ columns={
66
+ "indexId": "问题编号",
67
+ "contentType": "-",
68
+ "trade": "行业",
69
+ "mainContent": "问题",
70
+ "attachmentUrl": "-",
71
+ "boardType": "行业代码",
72
+ "filetype": "-",
73
+ "pubDate": "提问时间",
74
+ "stockCode": "股票代码",
75
+ "companyShortName": "公司简称",
76
+ "author": "提问者编号",
77
+ "authorName": "提问者",
78
+ "authorLogo": "-",
79
+ "pubClient": "来源",
80
+ "attachedId": "回答ID",
81
+ "attachedContent": "回答内容",
82
+ "attachedAuthor": "回答者",
83
+ "attachedPubDate": "-",
84
+ "updateDate": "更新时间",
85
+ "isPraise": "-",
86
+ "isFavorite": "-",
87
+ "isForward": "-",
88
+ "praiseCount": "-",
89
+ "qaStatus": "-",
90
+ "rights": "-",
91
+ "topStatus": "-",
92
+ "companyLogo": "-",
93
+ "favoriteCount": "-",
94
+ "forwardCount": "-",
95
+ },
96
+ inplace=True,
97
+ )
98
+ big_df = big_df[
99
+ [
100
+ "股票代码",
101
+ "公司简称",
102
+ "行业",
103
+ "行业代码",
104
+ "问题",
105
+ "提问者",
106
+ "来源",
107
+ "提问时间",
108
+ "更新时间",
109
+ "提问者编号",
110
+ "问题编号",
111
+ "回答ID",
112
+ "回答内容",
113
+ "回答者",
114
+ ]
115
+ ]
116
+ big_df["行业"] = [item[0] for item in big_df["行业"]]
117
+ big_df["行业代码"] = [item[0] for item in big_df["行业代码"]]
118
+ big_df["提问时间"] = (
119
+ pd.to_datetime(big_df["提问时间"], unit="ms", errors="coerce")
120
+ .dt.tz_localize("UTC")
121
+ .dt.tz_convert("Asia/Shanghai")
122
+ .dt.strftime("%Y-%m-%d %H:%M:%S")
123
+ )
124
+ big_df["更新时间"] = (
125
+ pd.to_datetime(big_df["更新时间"], unit="ms", errors="coerce")
126
+ .dt.tz_localize("UTC")
127
+ .dt.tz_convert("Asia/Shanghai")
128
+ .dt.strftime("%Y-%m-%d %H:%M:%S")
129
+ )
130
+ big_df["来源"] = big_df["来源"].map(
131
+ {
132
+ "2": "APP",
133
+ "5": "公众号",
134
+ "4": "网站",
135
+ }
136
+ )
137
+ big_df["来源"] = big_df["来源"].fillna("网站")
138
+ return big_df
139
+
140
+
141
+ def stock_irm_ans_cninfo(symbol: str = "1513586704097333248") -> pd.DataFrame:
142
+ """
143
+ 互动易-回答
144
+ https://irm.cninfo.com.cn/ircs/question/questionDetail?questionId=1515236357817618432
145
+ :param symbol: 提问者编号; 通过 ak.stock_irm_cninfo 来获取具体的提问者编号
146
+ :type symbol: str
147
+ :return: 回答
148
+ :rtype: str
149
+ """
150
+ url = "https://irm.cninfo.com.cn/newircs/question/getQuestionDetail"
151
+ params = {"questionId": symbol, "_t": "1691146921"}
152
+ r = requests.get(url, params=params)
153
+ data_json = r.json()
154
+ temp_df = pd.DataFrame.from_dict(data_json["data"], orient="index").T
155
+ if "replyDate" not in temp_df.columns:
156
+ return pd.DataFrame()
157
+ temp_df.rename(
158
+ columns={
159
+ "questionContent": "问题",
160
+ "questioner": "提问者",
161
+ "questionDate": "提问时间",
162
+ "replyDate": "回答时间",
163
+ "replyContent": "回答内容",
164
+ "stockCode": "股票代码",
165
+ "shortName": "公司简称",
166
+ },
167
+ inplace=True,
168
+ )
169
+ temp_df = temp_df[
170
+ [
171
+ "股票代码",
172
+ "公司简称",
173
+ "问题",
174
+ "回答内容",
175
+ "提问者",
176
+ "提问时间",
177
+ "回答时间",
178
+ ]
179
+ ]
180
+ temp_df["提问时间"] = (
181
+ pd.to_datetime(temp_df["提问时间"], unit="ms", errors="coerce")
182
+ .dt.tz_localize("UTC")
183
+ .dt.tz_convert("Asia/Shanghai")
184
+ .dt.strftime("%Y-%m-%d %H:%M:%S")
185
+ )
186
+ temp_df["回答时间"] = (
187
+ pd.to_datetime(temp_df["回答时间"], unit="ms", errors="coerce")
188
+ .dt.tz_localize("UTC")
189
+ .dt.tz_convert("Asia/Shanghai")
190
+ .dt.strftime("%Y-%m-%d %H:%M:%S")
191
+ )
192
+ return temp_df
193
+
194
+
195
+ if __name__ == "__main__":
196
+ stock_irm_cninfo_df = stock_irm_cninfo(symbol="002594")
197
+ print(stock_irm_cninfo_df)
198
+
199
+ stock_irm_ans_cninfo_df = stock_irm_ans_cninfo(symbol="1495108801386602496")
200
+ print(stock_irm_ans_cninfo_df)
@@ -0,0 +1,143 @@
1
+ import sys
2
+ import os
3
+
4
+ file_path = os.path.abspath(__file__)
5
+ end = file_path.index('mns') + 16
6
+ project_path = file_path[0:end]
7
+ sys.path.append(project_path)
8
+ import akshare as ak
9
+ import mns_common.utils.data_frame_util as data_frame_util
10
+ import pandas as pd
11
+ import mns_common.api.em.east_money_stock_api as east_money_stock_api
12
+ import mns_common.component.company.company_common_service_api as company_common_service_api
13
+ from loguru import logger
14
+ from datetime import datetime
15
+ from mns_common.db.MongodbUtil import MongodbUtil
16
+ import mns_common.utils.date_handle_util as date_handle_util
17
+
18
+ mongodb_util = MongodbUtil('27017')
19
+ import mns_common.constant.db_name_constant as db_name_constant
20
+ import mns_common.component.common_service_fun_api as common_service_fun_api
21
+ import mns_scheduler.irm.api.sh_stock_sns_sse_info_api as sh_stock_sns_sse_info_api
22
+ import mns_scheduler.irm.api.sz_stock_sns_sse_info_api as sz_stock_sns_sse_info_api
23
+
24
+
25
+ # 获取股票提问 互动易-提问 深交所
26
+ def get_stock_irm_cninfo_sz_api(symbol):
27
+ try:
28
+ # 获取一页
29
+ stock_irm_cninfo_df = sh_stock_sns_sse_info_api.stock_sns_sse_info(symbol)
30
+ # 获取全页
31
+ # stock_irm_cninfo_df = ak.stock_irm_cninfo(symbol)
32
+ except Exception as e:
33
+ logger.error("获取提问者异常:{},{}", symbol, e)
34
+ return pd.DataFrame()
35
+ if data_frame_util.is_empty(stock_irm_cninfo_df):
36
+ return pd.DataFrame()
37
+ stock_irm_cninfo_df = stock_irm_cninfo_df.rename(columns={"股票代码": "symbol",
38
+ "公司简称": "name",
39
+ "行业": "industry",
40
+ "行业代码": "industry_code",
41
+ "问题": "question",
42
+ '提问者': "questioner",
43
+ '来源': "source",
44
+ '提问时间': "question_time",
45
+ '更新时间': "answer_time",
46
+ "提问者编号": "questioner_no",
47
+ "问题编号": "question_no",
48
+ "回答ID": "answer_id",
49
+ "回答内容": "answer_content",
50
+ "回答者": "answer"
51
+ })
52
+ stock_irm_cninfo_df['_id'] = stock_irm_cninfo_df['symbol'] + '_' + stock_irm_cninfo_df['question_no']
53
+ stock_irm_cninfo_df = stock_irm_cninfo_df[[
54
+ '_id',
55
+ "symbol",
56
+ "name",
57
+ "question",
58
+ "answer_content",
59
+ "question_time",
60
+ "answer_time",
61
+ "questioner",
62
+ "source"]]
63
+ return stock_irm_cninfo_df
64
+
65
+
66
+ # 获取股票提问 互动易-提问 上交所
67
+ def get_stock_irm_cninfo_sh_api(symbol):
68
+ try:
69
+ # 获取一页
70
+ stock_sns_sse_info_df = sz_stock_sns_sse_info_api.stock_irm_cninfo(symbol)
71
+ # 获取全页
72
+ # stock_sns_sse_info_df = ak.stock_sns_sseinfo(symbol)
73
+ except Exception as e:
74
+ logger.error("获取提问者异常:{},{}", symbol, e)
75
+ return pd.DataFrame()
76
+ if data_frame_util.is_empty(stock_sns_sse_info_df):
77
+ return pd.DataFrame()
78
+
79
+ stock_sns_sse_info_df = stock_sns_sse_info_df.rename(columns={"股票代码": "symbol",
80
+ "公司简称": "name",
81
+ "问题": "question",
82
+ "回答": "answer_content",
83
+ '问题时间': "question_time",
84
+ '回答时间': "answer_time",
85
+ '用户名': "questioner",
86
+ '问题来源': "source"
87
+ })
88
+ stock_sns_sse_info_df['question_time'] = stock_sns_sse_info_df['question_time'].apply(replace_date_format)
89
+ stock_sns_sse_info_df['answer_time'] = stock_sns_sse_info_df['answer_time'].apply(replace_date_format)
90
+ stock_sns_sse_info_df['_id'] = stock_sns_sse_info_df['symbol'] + '_' + stock_sns_sse_info_df['question_time']
91
+ stock_sns_sse_info_df = stock_sns_sse_info_df[[
92
+ "_id",
93
+ "symbol",
94
+ "name",
95
+ "question",
96
+ "answer_content",
97
+ "question_time",
98
+ "answer_time",
99
+ "questioner",
100
+ "source"]]
101
+
102
+ return stock_sns_sse_info_df
103
+
104
+
105
+ def replace_date_format(date_str):
106
+ now_date = datetime.now()
107
+ str_day = now_date.strftime('%Y-%m-%d')
108
+ last_day = date_handle_util.add_date(str_day, -1)
109
+
110
+ return date_str.replace('年', '-').replace('月', '-').replace('日', '').replace('昨天', last_day)
111
+
112
+
113
+ # 同步所有互动问题
114
+ def sync_all_interactive_questions():
115
+ real_time_quotes_all_stocks = east_money_stock_api.get_real_time_quotes_all_stocks()
116
+ de_list_company_symbols = company_common_service_api.get_de_list_company()
117
+ real_time_quotes_all_stocks = real_time_quotes_all_stocks.loc[
118
+ ~(real_time_quotes_all_stocks['symbol'].isin(de_list_company_symbols))]
119
+ real_time_quotes_all_stocks = common_service_fun_api.classify_symbol(real_time_quotes_all_stocks)
120
+ for stock_one in real_time_quotes_all_stocks.itertuples():
121
+ try:
122
+ now_date = datetime.now()
123
+ str_day = now_date.strftime('%Y-%m-%d')
124
+ str_now_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
125
+ classification = stock_one.classification
126
+ if classification in ['S', 'C']:
127
+ stock_irm_cninfo_df = get_stock_irm_cninfo_sz_api(stock_one.symbol)
128
+ elif classification in ['K', 'H']:
129
+ stock_irm_cninfo_df = get_stock_irm_cninfo_sh_api(stock_one.symbol)
130
+ else:
131
+ continue
132
+ stock_irm_cninfo_df['sync_time'] = str_now_date
133
+ stock_irm_cninfo_df['str_day'] = str_day
134
+ stock_irm_cninfo_df.drop_duplicates('_id', keep='last', inplace=True)
135
+ mongodb_util.save_mongo(stock_irm_cninfo_df, db_name_constant.STOCK_INTERACTIVE_QUESTION)
136
+ logger.info("完成同步到:{}", stock_one.symbol)
137
+ except Exception as e:
138
+ logger.error("同步互动问题出现异常:{},{}", stock_one.symbol, e)
139
+
140
+
141
+ if __name__ == '__main__':
142
+ # get_stock_irm_cninfo_sh_api('603633')
143
+ sync_all_interactive_questions()
@@ -0,0 +1,7 @@
1
+ import sys
2
+ import os
3
+
4
+ file_path = os.path.abspath(__file__)
5
+ end = file_path.index('mns') + 16
6
+ project_path = file_path[0:end]
7
+ sys.path.append(project_path)
@@ -41,6 +41,7 @@ import mns_scheduler.concept.ths.common.ths_concept_update_common_api as ths_con
41
41
  import mns_scheduler.trade.sync_position_api as sync_position_api
42
42
  import mns_scheduler.concept.clean.kpl_concept_clean_api as kpl_concept_clean_api
43
43
  import mns_scheduler.company_info.de_list_stock_service as de_list_stock_service
44
+ import mns_scheduler.irm.stock_irm_cninfo_service as stock_irm_cninfo_service
44
45
 
45
46
 
46
47
  # 同步交易日期任务完成
@@ -322,6 +323,12 @@ def sync_new_high_risk_stocks():
322
323
  register_and_investigate_stock_sync_api.sync_new_high_risk_stocks()
323
324
 
324
325
 
326
+ # 同步互动回答
327
+ def sync_all_interactive_questions():
328
+ logger.info('同步互动回答')
329
+ stock_irm_cninfo_service.sync_all_interactive_questions()
330
+
331
+
325
332
  # # 定义BlockingScheduler
326
333
  blockingScheduler = BlockingScheduler()
327
334
  # sync_trade_date 同步交易日期
@@ -397,6 +404,9 @@ blockingScheduler.add_job(sync_position, 'cron', hour='0,08', minute='10')
397
404
  # 同步被立案调查的股票
398
405
  blockingScheduler.add_job(sync_new_high_risk_stocks, 'cron', hour='0,09,12,16', minute='20')
399
406
 
407
+ # 同步互动回答
408
+ blockingScheduler.add_job(sync_all_interactive_questions, 'cron', hour='08,12,17', minute='05')
409
+
400
410
  print('定时任务启动成功')
401
411
  blockingScheduler.start()
402
412
  #
@@ -1,3 +1,3 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mns-scheduler
3
- Version: 1.0.5.5
3
+ Version: 1.0.5.6
@@ -51,6 +51,9 @@ mns_scheduler/hk/__init__.py
51
51
  mns_scheduler/hk/hk_company_info_sync_service_api.py
52
52
  mns_scheduler/irm/__init__.py
53
53
  mns_scheduler/irm/stock_irm_cninfo_service.py
54
+ mns_scheduler/irm/api/__init__.py
55
+ mns_scheduler/irm/api/sh_stock_sns_sse_info_api.py
56
+ mns_scheduler/irm/api/sz_stock_sns_sse_info_api.py
54
57
  mns_scheduler/k_line/__init__.py
55
58
  mns_scheduler/k_line/clean/__init__.py
56
59
  mns_scheduler/k_line/clean/k_line_info_clean_impl.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='mns-scheduler',
5
- version='1.0.5.5',
5
+ version='1.0.5.6',
6
6
  packages=find_packages(),
7
7
  install_requires=[], # 如果有依赖项,可以在这里列出
8
8
  )
@@ -1,42 +0,0 @@
1
- import sys
2
- import os
3
-
4
- file_path = os.path.abspath(__file__)
5
- end = file_path.index('mns') + 16
6
- project_path = file_path[0:end]
7
- sys.path.append(project_path)
8
- import akshare as ak
9
- import mns_common.utils.data_frame_util as data_frame_util
10
- import pandas as pd
11
- from loguru import logger
12
-
13
-
14
- # 获取股票提问 互动易-提问
15
- def get_stock_irm_cninfo(symbol):
16
- try:
17
- stock_irm_cninfo_df = ak.stock_irm_cninfo(symbol)
18
- except Exception as e:
19
- logger.error("获取提问者异常:{},{}", symbol, e)
20
- return pd.DataFrame()
21
- if data_frame_util.is_empty(stock_irm_cninfo_df):
22
- return pd.DataFrame()
23
- stock_irm_cninfo_df = stock_irm_cninfo_df.rename(columns={"股票代码": "symbol",
24
- "公司简称": "name",
25
- "行业": "industry",
26
- "行业代码": "industry_code",
27
- "问题": "question",
28
- '提问者': "questioner",
29
- '来源': "source",
30
- '提问时间': "question_time",
31
- '更新时间': "update_time",
32
- "提问者编号": "questioner_no",
33
- "问题编号": "question_no",
34
- "回答ID": "answer_id",
35
- "回答内容": "answer_content",
36
- "回答者": "answer"
37
- })
38
- return stock_irm_cninfo_df
39
-
40
-
41
- if __name__ == '__main__':
42
- get_stock_irm_cninfo('301191')