akshare 1.16.16__py3-none-any.whl → 1.16.18__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.
- akshare/__init__.py +13 -1
- akshare/stock/stock_board_concept_em.py +59 -9
- akshare/stock/stock_board_industry_em.py +109 -7
- akshare/stock_feature/stock_board_concept_ths.py +286 -0
- akshare/stock_feature/stock_board_industry_ths.py +2 -2
- akshare/stock_feature/stock_research_report_em.py +6 -1
- {akshare-1.16.16.dist-info → akshare-1.16.18.dist-info}/METADATA +1 -1
- {akshare-1.16.16.dist-info → akshare-1.16.18.dist-info}/RECORD +11 -10
- {akshare-1.16.16.dist-info → akshare-1.16.18.dist-info}/LICENSE +0 -0
- {akshare-1.16.16.dist-info → akshare-1.16.18.dist-info}/WHEEL +0 -0
- {akshare-1.16.16.dist-info → akshare-1.16.18.dist-info}/top_level.txt +0 -0
akshare/__init__.py
CHANGED
@@ -3025,9 +3025,11 @@ amac_manager_cancelled_info # 中国证券投资基金业协会-信息公示-诚
|
|
3025
3025
|
1.16.14 fix: fix stock_info_global_cls interface
|
3026
3026
|
1.16.15 fix: fix stock_board_concept_name_em interface
|
3027
3027
|
1.16.16 fix: fix stock_board_concept_spot_em interface
|
3028
|
+
1.16.17 fix: fix stock_research_report_em interface
|
3029
|
+
1.16.18 fix: fix stock_board_concept_spot_em interface
|
3028
3030
|
"""
|
3029
3031
|
|
3030
|
-
__version__ = "1.16.
|
3032
|
+
__version__ = "1.16.18"
|
3031
3033
|
__author__ = "AKFamily"
|
3032
3034
|
|
3033
3035
|
import sys
|
@@ -4276,6 +4278,16 @@ from akshare.stock_feature.stock_report_em import (
|
|
4276
4278
|
"""
|
4277
4279
|
from akshare.stock_feature.stock_yjbb_em import stock_yjbb_em
|
4278
4280
|
|
4281
|
+
"""
|
4282
|
+
同花顺-概念板块
|
4283
|
+
"""
|
4284
|
+
from akshare.stock_feature.stock_board_concept_ths import (
|
4285
|
+
stock_board_concept_info_ths,
|
4286
|
+
stock_board_concept_summary_ths,
|
4287
|
+
stock_board_concept_index_ths,
|
4288
|
+
stock_board_concept_name_ths,
|
4289
|
+
)
|
4290
|
+
|
4279
4291
|
"""
|
4280
4292
|
同花顺-行业板块
|
4281
4293
|
"""
|
@@ -1,11 +1,12 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding:utf-8 -*-
|
3
3
|
"""
|
4
|
-
Date: 2025/2/
|
4
|
+
Date: 2025/2/28 16:30
|
5
5
|
Desc: 东方财富-沪深板块-概念板块
|
6
6
|
https://quote.eastmoney.com/center/boardlist.html#concept_board
|
7
7
|
"""
|
8
8
|
|
9
|
+
import re
|
9
10
|
from functools import lru_cache
|
10
11
|
|
11
12
|
import pandas as pd
|
@@ -13,7 +14,7 @@ import requests
|
|
13
14
|
|
14
15
|
|
15
16
|
@lru_cache()
|
16
|
-
def
|
17
|
+
def __stock_board_concept_name_em() -> pd.DataFrame:
|
17
18
|
"""
|
18
19
|
东方财富网-行情中心-沪深京板块-概念板块-名称
|
19
20
|
https://quote.eastmoney.com/center/boardlist.html#concept_board
|
@@ -97,11 +98,11 @@ def stock_board_concept_name_em() -> pd.DataFrame:
|
|
97
98
|
return temp_df
|
98
99
|
|
99
100
|
|
100
|
-
def
|
101
|
+
def stock_board_concept_name_em() -> pd.DataFrame:
|
101
102
|
"""
|
102
|
-
|
103
|
+
东方财富网-行情中心-沪深京板块-概念板块-名称
|
103
104
|
https://quote.eastmoney.com/center/boardlist.html#concept_board
|
104
|
-
:return:
|
105
|
+
:return: 概念板块-名称
|
105
106
|
:rtype: pandas.DataFrame
|
106
107
|
"""
|
107
108
|
url = "https://79.push2.eastmoney.com/api/qt/clist/get"
|
@@ -181,6 +182,55 @@ def stock_board_concept_spot_em() -> pd.DataFrame:
|
|
181
182
|
return temp_df
|
182
183
|
|
183
184
|
|
185
|
+
def stock_board_concept_spot_em(symbol: str = "可燃冰") -> pd.DataFrame:
|
186
|
+
"""
|
187
|
+
东方财富网-行情中心-沪深京板块-概念板块-实时行情
|
188
|
+
https://quote.eastmoney.com/bk/90.BK0818.html
|
189
|
+
:return: 概念板块-实时行情
|
190
|
+
:rtype: pandas.DataFrame
|
191
|
+
"""
|
192
|
+
url = "https://91.push2.eastmoney.com/api/qt/stock/get"
|
193
|
+
field_map = {
|
194
|
+
"f43": "最新",
|
195
|
+
"f44": "最高",
|
196
|
+
"f45": "最低",
|
197
|
+
"f46": "开盘",
|
198
|
+
"f47": "成交量",
|
199
|
+
"f48": "成交额",
|
200
|
+
"f170": "涨跌幅",
|
201
|
+
"f171": "振幅",
|
202
|
+
"f168": "换手率",
|
203
|
+
"f169": "涨跌额",
|
204
|
+
}
|
205
|
+
|
206
|
+
if re.match(pattern=r"^BK\d+", string=symbol):
|
207
|
+
em_code = symbol
|
208
|
+
else:
|
209
|
+
industry_listing = __stock_board_concept_name_em()
|
210
|
+
em_code = industry_listing.query("板块名称 == @symbol")["板块代码"].values[0]
|
211
|
+
params = dict(
|
212
|
+
fields=",".join(field_map.keys()),
|
213
|
+
mpi="1000",
|
214
|
+
invt="2",
|
215
|
+
fltt="1",
|
216
|
+
secid=f"90.{em_code}",
|
217
|
+
ut="fa5fd1943c7b386f172d6893dbfba10b",
|
218
|
+
)
|
219
|
+
r = requests.get(url, params=params)
|
220
|
+
data_dict = r.json()
|
221
|
+
result = pd.DataFrame.from_dict(data_dict["data"], orient="index")
|
222
|
+
result.rename(field_map, inplace=True)
|
223
|
+
result.reset_index(inplace=True)
|
224
|
+
result.columns = ["item", "value"]
|
225
|
+
result["value"] = pd.to_numeric(result["value"], errors="coerce")
|
226
|
+
|
227
|
+
# 各项转换成正常单位. 除了成交量与成交额, 原始数据中已是正常单位(元)
|
228
|
+
result["value"] = result["value"] * 1e-2
|
229
|
+
result.iloc[4, 1] = result.iloc[4, 1] * 1e2
|
230
|
+
result.iloc[5, 1] = result.iloc[5, 1] * 1e2
|
231
|
+
return result
|
232
|
+
|
233
|
+
|
184
234
|
def stock_board_concept_hist_em(
|
185
235
|
symbol: str = "绿色电力",
|
186
236
|
period: str = "daily",
|
@@ -209,7 +259,7 @@ def stock_board_concept_hist_em(
|
|
209
259
|
"weekly": "102",
|
210
260
|
"monthly": "103",
|
211
261
|
}
|
212
|
-
stock_board_concept_em_map =
|
262
|
+
stock_board_concept_em_map = __stock_board_concept_name_em()
|
213
263
|
stock_board_code = stock_board_concept_em_map[
|
214
264
|
stock_board_concept_em_map["板块名称"] == symbol
|
215
265
|
]["板块代码"].values[0]
|
@@ -285,7 +335,7 @@ def stock_board_concept_hist_min_em(
|
|
285
335
|
:return: 分时历史行情
|
286
336
|
:rtype: pandas.DataFrame
|
287
337
|
"""
|
288
|
-
stock_board_concept_em_map =
|
338
|
+
stock_board_concept_em_map = __stock_board_concept_name_em()
|
289
339
|
stock_board_code = stock_board_concept_em_map[
|
290
340
|
stock_board_concept_em_map["板块名称"] == symbol
|
291
341
|
]["板块代码"].values[0]
|
@@ -391,7 +441,7 @@ def stock_board_concept_cons_em(symbol: str = "融资融券") -> pd.DataFrame:
|
|
391
441
|
:return: 板块成份
|
392
442
|
:rtype: pandas.DataFrame
|
393
443
|
"""
|
394
|
-
stock_board_concept_em_map =
|
444
|
+
stock_board_concept_em_map = __stock_board_concept_name_em()
|
395
445
|
stock_board_code = stock_board_concept_em_map[
|
396
446
|
stock_board_concept_em_map["板块名称"] == symbol
|
397
447
|
]["板块代码"].values[0]
|
@@ -490,7 +540,7 @@ if __name__ == "__main__":
|
|
490
540
|
stock_board_concept_em_df = stock_board_concept_name_em()
|
491
541
|
print(stock_board_concept_em_df)
|
492
542
|
|
493
|
-
stock_board_concept_spot_em_df = stock_board_concept_spot_em()
|
543
|
+
stock_board_concept_spot_em_df = stock_board_concept_spot_em(symbol="可燃冰")
|
494
544
|
print(stock_board_concept_spot_em_df)
|
495
545
|
|
496
546
|
stock_board_concept_hist_em_df = stock_board_concept_hist_em(
|
@@ -1,17 +1,120 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding:utf-8 -*-
|
3
3
|
"""
|
4
|
-
Date:
|
4
|
+
Date: 2025/2/28 16:30
|
5
5
|
Desc: 东方财富-沪深板块-行业板块
|
6
6
|
https://quote.eastmoney.com/center/boardlist.html#industry_board
|
7
7
|
"""
|
8
8
|
|
9
9
|
import re
|
10
|
+
from functools import lru_cache
|
10
11
|
|
11
12
|
import pandas as pd
|
12
13
|
import requests
|
13
14
|
|
14
15
|
|
16
|
+
@lru_cache()
|
17
|
+
def __stock_board_industry_name_em() -> pd.DataFrame:
|
18
|
+
"""
|
19
|
+
东方财富网-沪深板块-行业板块-名称
|
20
|
+
https://quote.eastmoney.com/center/boardlist.html#industry_board
|
21
|
+
:return: 行业板块-名称
|
22
|
+
:rtype: pandas.DataFrame
|
23
|
+
"""
|
24
|
+
url = "https://17.push2.eastmoney.com/api/qt/clist/get"
|
25
|
+
params = {
|
26
|
+
"pn": "1",
|
27
|
+
"pz": "50000",
|
28
|
+
"po": "1",
|
29
|
+
"np": "2",
|
30
|
+
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
31
|
+
"fltt": "2",
|
32
|
+
"invt": "2",
|
33
|
+
"fid": "f3",
|
34
|
+
"fs": "m:90 t:2 f:!50",
|
35
|
+
"fields": "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,"
|
36
|
+
"f23,f24,f25,f26,f22,f33,f11,f62,f128,f136,f115,f152,f124,f107,f104,f105,"
|
37
|
+
"f140,f141,f207,f208,f209,f222",
|
38
|
+
"_": "1626075887768",
|
39
|
+
}
|
40
|
+
r = requests.get(url, params=params)
|
41
|
+
data_json = r.json()
|
42
|
+
temp_df = pd.DataFrame(data_json["data"]["diff"]).T
|
43
|
+
temp_df.reset_index(inplace=True)
|
44
|
+
temp_df["index"] = temp_df.index + 1
|
45
|
+
temp_df.columns = [
|
46
|
+
"排名",
|
47
|
+
"-",
|
48
|
+
"最新价",
|
49
|
+
"涨跌幅",
|
50
|
+
"涨跌额",
|
51
|
+
"-",
|
52
|
+
"_",
|
53
|
+
"-",
|
54
|
+
"换手率",
|
55
|
+
"-",
|
56
|
+
"-",
|
57
|
+
"-",
|
58
|
+
"板块代码",
|
59
|
+
"-",
|
60
|
+
"板块名称",
|
61
|
+
"-",
|
62
|
+
"-",
|
63
|
+
"-",
|
64
|
+
"-",
|
65
|
+
"总市值",
|
66
|
+
"-",
|
67
|
+
"-",
|
68
|
+
"-",
|
69
|
+
"-",
|
70
|
+
"-",
|
71
|
+
"-",
|
72
|
+
"-",
|
73
|
+
"-",
|
74
|
+
"上涨家数",
|
75
|
+
"下跌家数",
|
76
|
+
"-",
|
77
|
+
"-",
|
78
|
+
"-",
|
79
|
+
"领涨股票",
|
80
|
+
"-",
|
81
|
+
"-",
|
82
|
+
"领涨股票-涨跌幅",
|
83
|
+
"-",
|
84
|
+
"-",
|
85
|
+
"-",
|
86
|
+
"-",
|
87
|
+
"-",
|
88
|
+
]
|
89
|
+
temp_df = temp_df[
|
90
|
+
[
|
91
|
+
"排名",
|
92
|
+
"板块名称",
|
93
|
+
"板块代码",
|
94
|
+
"最新价",
|
95
|
+
"涨跌额",
|
96
|
+
"涨跌幅",
|
97
|
+
"总市值",
|
98
|
+
"换手率",
|
99
|
+
"上涨家数",
|
100
|
+
"下跌家数",
|
101
|
+
"领涨股票",
|
102
|
+
"领涨股票-涨跌幅",
|
103
|
+
]
|
104
|
+
]
|
105
|
+
temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
|
106
|
+
temp_df["涨跌额"] = pd.to_numeric(temp_df["涨跌额"], errors="coerce")
|
107
|
+
temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce")
|
108
|
+
temp_df["总市值"] = pd.to_numeric(temp_df["总市值"], errors="coerce")
|
109
|
+
temp_df["换手率"] = pd.to_numeric(temp_df["换手率"], errors="coerce")
|
110
|
+
temp_df["上涨家数"] = pd.to_numeric(temp_df["上涨家数"], errors="coerce")
|
111
|
+
temp_df["下跌家数"] = pd.to_numeric(temp_df["下跌家数"], errors="coerce")
|
112
|
+
temp_df["领涨股票-涨跌幅"] = pd.to_numeric(
|
113
|
+
temp_df["领涨股票-涨跌幅"], errors="coerce"
|
114
|
+
)
|
115
|
+
return temp_df
|
116
|
+
|
117
|
+
|
15
118
|
def stock_board_industry_name_em() -> pd.DataFrame:
|
16
119
|
"""
|
17
120
|
东方财富网-沪深板块-行业板块-名称
|
@@ -139,9 +242,8 @@ def stock_board_industry_spot_em(symbol: str = "小金属") -> pd.DataFrame:
|
|
139
242
|
if re.match(pattern=r"^BK\d+", string=symbol):
|
140
243
|
em_code = symbol
|
141
244
|
else:
|
142
|
-
industry_listing =
|
245
|
+
industry_listing = __stock_board_industry_name_em()
|
143
246
|
em_code = industry_listing.query("板块名称 == @symbol")["板块代码"].values[0]
|
144
|
-
|
145
247
|
params = dict(
|
146
248
|
fields=",".join(field_map.keys()),
|
147
249
|
mpi="1000",
|
@@ -193,7 +295,7 @@ def stock_board_industry_hist_em(
|
|
193
295
|
"周k": "102",
|
194
296
|
"月k": "103",
|
195
297
|
}
|
196
|
-
stock_board_concept_em_map =
|
298
|
+
stock_board_concept_em_map = __stock_board_industry_name_em()
|
197
299
|
stock_board_code = stock_board_concept_em_map[
|
198
300
|
stock_board_concept_em_map["板块名称"] == symbol
|
199
301
|
]["板块代码"].values[0]
|
@@ -269,7 +371,7 @@ def stock_board_industry_hist_min_em(
|
|
269
371
|
:return: 分时历史行情
|
270
372
|
:rtype: pandas.DataFrame
|
271
373
|
"""
|
272
|
-
stock_board_concept_em_map =
|
374
|
+
stock_board_concept_em_map = __stock_board_industry_name_em()
|
273
375
|
stock_board_code = stock_board_concept_em_map[
|
274
376
|
stock_board_concept_em_map["板块名称"] == symbol
|
275
377
|
]["板块代码"].values[0]
|
@@ -378,11 +480,11 @@ def stock_board_industry_cons_em(symbol: str = "小金属") -> pd.DataFrame:
|
|
378
480
|
:return: 板块成份
|
379
481
|
:rtype: pandas.DataFrame
|
380
482
|
"""
|
381
|
-
stock_board_concept_em_map =
|
483
|
+
stock_board_concept_em_map = __stock_board_industry_name_em()
|
382
484
|
stock_board_code = stock_board_concept_em_map[
|
383
485
|
stock_board_concept_em_map["板块名称"] == symbol
|
384
486
|
]["板块代码"].values[0]
|
385
|
-
url = "
|
487
|
+
url = "https://29.push2.eastmoney.com/api/qt/clist/get"
|
386
488
|
params = {
|
387
489
|
"pn": "1",
|
388
490
|
"pz": "50000",
|
@@ -0,0 +1,286 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding:utf-8 -*-
|
3
|
+
"""
|
4
|
+
Date: 2025/2/28 13:20
|
5
|
+
Desc: 同花顺-板块-概念板块
|
6
|
+
https://q.10jqka.com.cn/thshy/
|
7
|
+
"""
|
8
|
+
|
9
|
+
from datetime import datetime
|
10
|
+
from functools import lru_cache
|
11
|
+
from io import StringIO
|
12
|
+
|
13
|
+
import pandas as pd
|
14
|
+
import requests
|
15
|
+
from bs4 import BeautifulSoup
|
16
|
+
import py_mini_racer
|
17
|
+
|
18
|
+
from akshare.datasets import get_ths_js
|
19
|
+
from akshare.utils import demjson
|
20
|
+
from akshare.utils.tqdm import get_tqdm
|
21
|
+
|
22
|
+
|
23
|
+
def _get_file_content_ths(file: str = "ths.js") -> str:
|
24
|
+
"""
|
25
|
+
获取 JS 文件的内容
|
26
|
+
:param file: JS 文件名
|
27
|
+
:type file: str
|
28
|
+
:return: 文件内容
|
29
|
+
:rtype: str
|
30
|
+
"""
|
31
|
+
setting_file_path = get_ths_js(file)
|
32
|
+
with open(setting_file_path, encoding="utf-8") as f:
|
33
|
+
file_data = f.read()
|
34
|
+
return file_data
|
35
|
+
|
36
|
+
|
37
|
+
@lru_cache()
|
38
|
+
def _get_stock_board_concept_name_ths() -> dict:
|
39
|
+
"""
|
40
|
+
获取同花顺概念板块代码和名称字典
|
41
|
+
:return: 获取同花顺概念板块代码和名称字典
|
42
|
+
:rtype: dict
|
43
|
+
"""
|
44
|
+
js_code = py_mini_racer.MiniRacer()
|
45
|
+
js_content = _get_file_content_ths("ths.js")
|
46
|
+
js_code.eval(js_content)
|
47
|
+
v_code = js_code.call("v")
|
48
|
+
headers = {
|
49
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
50
|
+
"Chrome/89.0.4389.90 Safari/537.36",
|
51
|
+
"Cookie": f"v={v_code}",
|
52
|
+
}
|
53
|
+
url = "https://q.10jqka.com.cn/gn/detail/code/307822/"
|
54
|
+
r = requests.get(url, headers=headers)
|
55
|
+
soup = BeautifulSoup(r.text, features="lxml")
|
56
|
+
code_list = [
|
57
|
+
item["href"].split("/")[-2]
|
58
|
+
for item in soup.find(name="div", attrs={"class": "cate_inner"}).find_all("a")
|
59
|
+
]
|
60
|
+
name_list = [
|
61
|
+
item.text
|
62
|
+
for item in soup.find(name="div", attrs={"class": "cate_inner"}).find_all("a")
|
63
|
+
]
|
64
|
+
name_code_map = dict(zip(name_list, code_list))
|
65
|
+
return name_code_map
|
66
|
+
|
67
|
+
|
68
|
+
def stock_board_concept_name_ths() -> pd.DataFrame:
|
69
|
+
"""
|
70
|
+
同花顺-板块-概念板块-概念
|
71
|
+
http://q.10jqka.com.cn/thshy/
|
72
|
+
:return: 所有概念板块的名称和链接
|
73
|
+
:rtype: pandas.DataFrame
|
74
|
+
"""
|
75
|
+
code_name_ths_map = _get_stock_board_concept_name_ths()
|
76
|
+
temp_df = pd.DataFrame.from_dict(code_name_ths_map, orient="index")
|
77
|
+
temp_df.reset_index(inplace=True)
|
78
|
+
temp_df.columns = ["name", "code"]
|
79
|
+
temp_df = temp_df[
|
80
|
+
[
|
81
|
+
"name",
|
82
|
+
"code",
|
83
|
+
]
|
84
|
+
]
|
85
|
+
return temp_df
|
86
|
+
|
87
|
+
|
88
|
+
def stock_board_concept_info_ths(symbol: str = "阿里巴巴概念") -> pd.DataFrame:
|
89
|
+
"""
|
90
|
+
同花顺-板块-概念板块-板块简介
|
91
|
+
http://q.10jqka.com.cn/gn/detail/code/301558/
|
92
|
+
:param symbol: 板块简介
|
93
|
+
:type symbol: str
|
94
|
+
:return: 板块简介
|
95
|
+
:rtype: pandas.DataFrame
|
96
|
+
"""
|
97
|
+
stock_board_ths_map_df = stock_board_concept_name_ths()
|
98
|
+
symbol_code = stock_board_ths_map_df[stock_board_ths_map_df["name"] == symbol][
|
99
|
+
"code"
|
100
|
+
].values[0]
|
101
|
+
url = f"http://q.10jqka.com.cn/gn/detail/code/{symbol_code}/"
|
102
|
+
headers = {
|
103
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
104
|
+
"Chrome/89.0.4389.90 Safari/537.36",
|
105
|
+
}
|
106
|
+
r = requests.get(url, headers=headers)
|
107
|
+
soup = BeautifulSoup(r.text, features="lxml")
|
108
|
+
name_list = [
|
109
|
+
item.text.strip()
|
110
|
+
for item in soup.find(name="div", attrs={"class": "board-infos"}).find_all("dt")
|
111
|
+
]
|
112
|
+
value_list = [
|
113
|
+
item.text.strip().replace("\n", "/")
|
114
|
+
for item in soup.find(name="div", attrs={"class": "board-infos"}).find_all("dd")
|
115
|
+
]
|
116
|
+
temp_df = pd.DataFrame([name_list, value_list]).T
|
117
|
+
temp_df.columns = ["项目", "值"]
|
118
|
+
return temp_df
|
119
|
+
|
120
|
+
|
121
|
+
def stock_board_concept_index_ths(
|
122
|
+
symbol: str = "阿里巴巴概念",
|
123
|
+
start_date: str = "20200101",
|
124
|
+
end_date: str = "20250228",
|
125
|
+
) -> pd.DataFrame:
|
126
|
+
"""
|
127
|
+
同花顺-板块-概念板块-指数数据
|
128
|
+
https://q.10jqka.com.cn/gn/detail/code/301558/
|
129
|
+
:param start_date: 开始时间
|
130
|
+
:type start_date: str
|
131
|
+
:param end_date: 结束时间
|
132
|
+
:type end_date: str
|
133
|
+
:param symbol: 指数数据
|
134
|
+
:type symbol: str
|
135
|
+
:return: 指数数据
|
136
|
+
:rtype: pandas.DataFrame
|
137
|
+
"""
|
138
|
+
js_code = py_mini_racer.MiniRacer()
|
139
|
+
js_content = _get_file_content_ths("ths.js")
|
140
|
+
js_code.eval(js_content)
|
141
|
+
v_code = js_code.call("v")
|
142
|
+
|
143
|
+
code_map = _get_stock_board_concept_name_ths()
|
144
|
+
symbol_code = code_map[symbol]
|
145
|
+
headers = {
|
146
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
147
|
+
"Chrome/89.0.4389.90 Safari/537.36",
|
148
|
+
}
|
149
|
+
url = f"https://q.10jqka.com.cn/gn/detail/code/{symbol_code}"
|
150
|
+
r = requests.get(url=url, headers=headers)
|
151
|
+
soup = BeautifulSoup(r.text, features="lxml")
|
152
|
+
inner_code = soup.find(name="input", attrs={"id": "clid"})["value"]
|
153
|
+
big_df = pd.DataFrame()
|
154
|
+
current_year = datetime.now().year
|
155
|
+
begin_year = int(start_date[:4])
|
156
|
+
tqdm = get_tqdm()
|
157
|
+
for year in tqdm(range(begin_year, current_year + 1), leave=False):
|
158
|
+
url = f"https://d.10jqka.com.cn/v4/line/bk_{inner_code}/01/{year}.js"
|
159
|
+
headers = {
|
160
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
161
|
+
"Chrome/89.0.4389.90 Safari/537.36",
|
162
|
+
"Referer": "http://q.10jqka.com.cn",
|
163
|
+
"Host": "d.10jqka.com.cn",
|
164
|
+
"Cookie": f"v={v_code}",
|
165
|
+
}
|
166
|
+
r = requests.get(url, headers=headers)
|
167
|
+
data_text = r.text
|
168
|
+
|
169
|
+
try:
|
170
|
+
demjson.decode(data_text[data_text.find("{") : -1])
|
171
|
+
except: # noqa: E722
|
172
|
+
continue
|
173
|
+
temp_df = demjson.decode(data_text[data_text.find("{") : -1])
|
174
|
+
temp_df = pd.DataFrame(temp_df["data"].split(";"))
|
175
|
+
temp_df = temp_df.iloc[:, 0].str.split(",", expand=True)
|
176
|
+
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
177
|
+
|
178
|
+
if len(big_df.columns) == 11:
|
179
|
+
big_df.columns = [
|
180
|
+
"日期",
|
181
|
+
"开盘价",
|
182
|
+
"最高价",
|
183
|
+
"最低价",
|
184
|
+
"收盘价",
|
185
|
+
"成交量",
|
186
|
+
"成交额",
|
187
|
+
"_",
|
188
|
+
"_",
|
189
|
+
"_",
|
190
|
+
"_",
|
191
|
+
]
|
192
|
+
else:
|
193
|
+
big_df.columns = [
|
194
|
+
"日期",
|
195
|
+
"开盘价",
|
196
|
+
"最高价",
|
197
|
+
"最低价",
|
198
|
+
"收盘价",
|
199
|
+
"成交量",
|
200
|
+
"成交额",
|
201
|
+
"_",
|
202
|
+
"_",
|
203
|
+
"_",
|
204
|
+
"_",
|
205
|
+
"_",
|
206
|
+
]
|
207
|
+
big_df = big_df[
|
208
|
+
[
|
209
|
+
"日期",
|
210
|
+
"开盘价",
|
211
|
+
"最高价",
|
212
|
+
"最低价",
|
213
|
+
"收盘价",
|
214
|
+
"成交量",
|
215
|
+
"成交额",
|
216
|
+
]
|
217
|
+
]
|
218
|
+
big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date
|
219
|
+
big_df.index = pd.to_datetime(big_df["日期"], errors="coerce")
|
220
|
+
big_df = big_df[start_date:end_date]
|
221
|
+
big_df.reset_index(drop=True, inplace=True)
|
222
|
+
big_df["开盘价"] = pd.to_numeric(big_df["开盘价"], errors="coerce")
|
223
|
+
big_df["最高价"] = pd.to_numeric(big_df["最高价"], errors="coerce")
|
224
|
+
big_df["最低价"] = pd.to_numeric(big_df["最低价"], errors="coerce")
|
225
|
+
big_df["收盘价"] = pd.to_numeric(big_df["收盘价"], errors="coerce")
|
226
|
+
big_df["成交量"] = pd.to_numeric(big_df["成交量"], errors="coerce")
|
227
|
+
big_df["成交额"] = pd.to_numeric(big_df["成交额"], errors="coerce")
|
228
|
+
return big_df
|
229
|
+
|
230
|
+
|
231
|
+
def stock_board_concept_summary_ths() -> pd.DataFrame:
|
232
|
+
"""
|
233
|
+
同花顺-数据中心-概念板块-概念时间表
|
234
|
+
https://q.10jqka.com.cn/gn/
|
235
|
+
:return: 概念时间表
|
236
|
+
:rtype: pandas.DataFrame
|
237
|
+
"""
|
238
|
+
js_code = py_mini_racer.MiniRacer()
|
239
|
+
js_content = _get_file_content_ths("ths.js")
|
240
|
+
js_code.eval(js_content)
|
241
|
+
v_code = js_code.call("v")
|
242
|
+
headers = {
|
243
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
244
|
+
"Chrome/89.0.4389.90 Safari/537.36",
|
245
|
+
"Cookie": f"v={v_code}",
|
246
|
+
}
|
247
|
+
url = "http://q.10jqka.com.cn/gn/index/field/addtime/order/desc/page/1/ajax/1/"
|
248
|
+
r = requests.get(url, headers=headers)
|
249
|
+
soup = BeautifulSoup(r.text, features="lxml")
|
250
|
+
page_num = soup.find(name="span", attrs={"class": "page_info"}).text.split("/")[1]
|
251
|
+
big_df = pd.DataFrame()
|
252
|
+
tqdm = get_tqdm()
|
253
|
+
for page in tqdm(range(1, int(page_num) + 1), leave=False):
|
254
|
+
url = f"http://q.10jqka.com.cn/gn/index/field/addtime/order/desc/page/{page}/ajax/1/"
|
255
|
+
r = requests.get(url, headers=headers)
|
256
|
+
try:
|
257
|
+
temp_df = pd.read_html(StringIO(r.text))[0]
|
258
|
+
big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
|
259
|
+
except ValueError:
|
260
|
+
break
|
261
|
+
big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date
|
262
|
+
big_df["成分股数量"] = pd.to_numeric(big_df["成分股数量"], errors="coerce")
|
263
|
+
return big_df
|
264
|
+
|
265
|
+
|
266
|
+
if __name__ == "__main__":
|
267
|
+
stock_board_concept_name_ths_df = stock_board_concept_name_ths()
|
268
|
+
print(stock_board_concept_name_ths_df)
|
269
|
+
|
270
|
+
stock_board_concept_info_ths_df = stock_board_concept_info_ths(
|
271
|
+
symbol="阿里巴巴概念"
|
272
|
+
)
|
273
|
+
print(stock_board_concept_info_ths_df)
|
274
|
+
|
275
|
+
stock_board_concept_index_ths_df = stock_board_concept_index_ths(
|
276
|
+
symbol="阿里巴巴概念", start_date="20200101", end_date="20250228"
|
277
|
+
)
|
278
|
+
print(stock_board_concept_index_ths_df)
|
279
|
+
|
280
|
+
stock_board_concept_summary_ths_df = stock_board_concept_summary_ths()
|
281
|
+
print(stock_board_concept_summary_ths_df)
|
282
|
+
|
283
|
+
for stock in stock_board_concept_name_ths_df["name"]:
|
284
|
+
print(stock)
|
285
|
+
stock_board_industry_index_ths_df = stock_board_concept_index_ths(symbol=stock)
|
286
|
+
print(stock_board_industry_index_ths_df)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding:utf-8 -*-
|
3
3
|
"""
|
4
|
-
Date:
|
4
|
+
Date: 2025/2/28 13:20
|
5
5
|
Desc: 同花顺-板块-同花顺行业
|
6
6
|
https://q.10jqka.com.cn/thshy/
|
7
7
|
"""
|
@@ -29,7 +29,7 @@ def _get_file_content_ths(file: str = "ths.js") -> str:
|
|
29
29
|
:rtype: str
|
30
30
|
"""
|
31
31
|
setting_file_path = get_ths_js(file)
|
32
|
-
with open(setting_file_path) as f:
|
32
|
+
with open(setting_file_path, encoding="utf-8") as f:
|
33
33
|
file_data = f.read()
|
34
34
|
return file_data
|
35
35
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env python
|
2
2
|
# -*- coding:utf-8 -*-
|
3
3
|
"""
|
4
|
-
Date: 2025/
|
4
|
+
Date: 2025/2/28 13:00
|
5
5
|
Desc: 东方财富网-数据中心-研究报告-个股研报
|
6
6
|
https://data.eastmoney.com/report/stock.jshtml
|
7
7
|
"""
|
@@ -67,6 +67,9 @@ def stock_research_report_em(symbol: str = "000001") -> pd.DataFrame:
|
|
67
67
|
predict_next_year_pe_title = f"{current_year + 1}-盈利预测-市盈率"
|
68
68
|
predict_next_two_year_eps_title = f"{current_year + 2}-盈利预测-收益"
|
69
69
|
predict_next_two_year_pe_title = f"{current_year + 2}-盈利预测-市盈率"
|
70
|
+
big_df["pdfUrl"] = big_df["infoCode"].apply(
|
71
|
+
lambda x: f"https://pdf.dfcfw.com/pdf/H3_{x}_1.pdf"
|
72
|
+
)
|
70
73
|
big_df.rename(
|
71
74
|
columns={
|
72
75
|
"index": "序号",
|
@@ -121,6 +124,7 @@ def stock_research_report_em(symbol: str = "000001") -> pd.DataFrame:
|
|
121
124
|
"authorID": "-",
|
122
125
|
"count": "近一月个股研报数",
|
123
126
|
"orgType": "-",
|
127
|
+
"pdfUrl": "报告PDF链接",
|
124
128
|
},
|
125
129
|
inplace=True,
|
126
130
|
)
|
@@ -141,6 +145,7 @@ def stock_research_report_em(symbol: str = "000001") -> pd.DataFrame:
|
|
141
145
|
predict_next_two_year_pe_title,
|
142
146
|
"行业",
|
143
147
|
"日期",
|
148
|
+
"报告PDF链接",
|
144
149
|
]
|
145
150
|
]
|
146
151
|
big_df["日期"] = pd.to_datetime(big_df["日期"], errors="coerce").dt.date
|
@@ -1,4 +1,4 @@
|
|
1
|
-
akshare/__init__.py,sha256=
|
1
|
+
akshare/__init__.py,sha256=7KwD4mtIrWqpTY0Pu66f4m5MfAQ4IU0eN5Ay4VGsx5A,188704
|
2
2
|
akshare/datasets.py,sha256=rKuRNZrqi6IMsZ9nyvO3Rx02js0tH3zMLjz8HQNAoPQ,963
|
3
3
|
akshare/exceptions.py,sha256=WEJjIhSmJ_xXNW6grwV4nufE_cfmmyuhmueVGiN1VAg,878
|
4
4
|
akshare/request.py,sha256=HtFFf9MhfEibR-ETWe-1Tts6ELU4VKSqA-ghaXjegQM,4252
|
@@ -231,8 +231,8 @@ akshare/stock/__init__.py,sha256=jSa9260d6aNZajaW68chI2mpPkDSXLOgi3eXrqo4MQ8,82
|
|
231
231
|
akshare/stock/cons.py,sha256=0oyUW5Pu-iQ3qgh-TFemM_O5f1fAwVe-PsI4Qa8EYpQ,42956
|
232
232
|
akshare/stock/stock_allotment_cninfo.py,sha256=OVjVdWp2XVRNbJvVgtgVVoBmPBJgBB4RyIIgA_9QHM8,6066
|
233
233
|
akshare/stock/stock_ask_bid_em.py,sha256=nXQhYIpU4k7GUc7nthWC29zVS9GhYb9ppQTLD0gycF4,3438
|
234
|
-
akshare/stock/stock_board_concept_em.py,sha256=
|
235
|
-
akshare/stock/stock_board_industry_em.py,sha256=
|
234
|
+
akshare/stock/stock_board_concept_em.py,sha256=JAyXNCuDf-IdkklRSz7D3rUwTwRM4aoLJgliQeivpSo,18431
|
235
|
+
akshare/stock/stock_board_industry_em.py,sha256=aaMU78BLVxSTQ4Z55212DsfQDBerKD2OX3as1J9-w1s,19041
|
236
236
|
akshare/stock/stock_cg_equity_mortgage.py,sha256=Pui5aWKKPwGuKjF_GNpejDzsMGNPrxiaJviLz3x2e9I,3426
|
237
237
|
akshare/stock/stock_cg_guarantee.py,sha256=ts7qcQhhyN1PHB7Q4XlMn38HhfVvubOvky9RZfmUP94,3844
|
238
238
|
akshare/stock/stock_cg_lawsuit.py,sha256=6Y92pPw0JgyrInteqHuU07G1jwmdX2wjaDtrJN8y6Hg,4129
|
@@ -291,7 +291,8 @@ akshare/stock_feature/stock_a_pe_and_pb.py,sha256=wf6AuJOCKwfYxskbrLjIjz21a1MzYv
|
|
291
291
|
akshare/stock_feature/stock_account_em.py,sha256=PA-531xnv5uerFrYGc40mk8q8O0DGciHC_XVlE9udis,3342
|
292
292
|
akshare/stock_feature/stock_all_pb.py,sha256=2yQLq03qXNbTB5AtJ-Q8uJldOluElH5zTjYneY3aaZ0,1194
|
293
293
|
akshare/stock_feature/stock_analyst_em.py,sha256=Md3_G-Px0O1lk4dx5dCEKl8Vjgwt79Sh-FSh_sW1Elo,9508
|
294
|
-
akshare/stock_feature/
|
294
|
+
akshare/stock_feature/stock_board_concept_ths.py,sha256=_FVWd6oxiSWB1X7TS5obHv9pObll3_rBXYwaAhNZ8KM,9689
|
295
|
+
akshare/stock_feature/stock_board_industry_ths.py,sha256=c22JP9MJGncLaqvBmkAxHUz3HKNMCKf58Rug9n2vlAU,15102
|
295
296
|
akshare/stock_feature/stock_buffett_index_lg.py,sha256=NpNccHmGjtqLz6aUladB6InPzO2pjoImbgCgmNEYUuM,2027
|
296
297
|
akshare/stock_feature/stock_classify_sina.py,sha256=Lg7ROG5W9HioFRplJI2rZ6tAAHM09N3g9qF6kReIQYI,3210
|
297
298
|
akshare/stock_feature/stock_comment_em.py,sha256=uSOS5YmyXB9jSDsZf1fNC0RPGTE6_4RzjwxaewhJQtc,13697
|
@@ -332,7 +333,7 @@ akshare/stock_feature/stock_market_legu.py,sha256=_LeyGUGyZFeD-1fnJPc4eIQkeoWAmo
|
|
332
333
|
akshare/stock_feature/stock_pankou_em.py,sha256=A3lu1hKddXwMFo9vKPLCQfL3Zh77xr2IbcAtKs8Lc9Y,5599
|
333
334
|
akshare/stock_feature/stock_qsjy_em.py,sha256=7EHroLZC3-X_3WNhb7GV9MPQHbxjtkfKI_YEbTvnSb0,3913
|
334
335
|
akshare/stock_feature/stock_report_em.py,sha256=jhePrTKGIYzdz8idiPoDs1vEajd73XRIFpZyWQggKa4,18075
|
335
|
-
akshare/stock_feature/stock_research_report_em.py,sha256=
|
336
|
+
akshare/stock_feature/stock_research_report_em.py,sha256=yc5aoFPlda_x3q_T_WD31PH5d2RymnMOFB1tITXhzog,6135
|
336
337
|
akshare/stock_feature/stock_sns_sseinfo.py,sha256=TGGLw5P77Hh-sSHgw_KKoK29d1m_V_2GDQXe9m_XFew,4556
|
337
338
|
akshare/stock_feature/stock_sy_em.py,sha256=GysP1WvPpqCLhbCRXH5sxwmXCPYvgtbJYQ_jltDqaA0,17721
|
338
339
|
akshare/stock_feature/stock_technology_ths.py,sha256=4u9z7H6MYEutOYAQvYfzgc_FxG6XlhkMLujSotAbraw,30827
|
@@ -380,8 +381,8 @@ akshare/utils/token_process.py,sha256=K4rGXjh_tgugbRcyOK2h2x0jP3PT65IIK7nxhUKhOe
|
|
380
381
|
akshare/utils/tqdm.py,sha256=MuPNwcswkOGjwWQOMWXi9ZvQ_RmW4obCWRj2i7HM7FE,847
|
381
382
|
tests/__init__.py,sha256=gNzhlO0UPjFq6Ieb38kaVIODXv4cTDByrdohAZnDYt4,82
|
382
383
|
tests/test_func.py,sha256=j1MGYbZI2if2j_LY1S4FLsf4qfq4NwVqD5wmRlv5Log,832
|
383
|
-
akshare-1.16.
|
384
|
-
akshare-1.16.
|
385
|
-
akshare-1.16.
|
386
|
-
akshare-1.16.
|
387
|
-
akshare-1.16.
|
384
|
+
akshare-1.16.18.dist-info/LICENSE,sha256=mmSZCPgfHiVw34LXuFArd-SUgQtBJ_QsIlh-kWlDHfs,1073
|
385
|
+
akshare-1.16.18.dist-info/METADATA,sha256=6vz1edzPefOIGHI7gk223yqPpj4-GHDm_LvIdCia_JE,13720
|
386
|
+
akshare-1.16.18.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
387
|
+
akshare-1.16.18.dist-info/top_level.txt,sha256=jsf9ZzZPmHaISTVumQPsAw7vv7Yv-PdEVW70SMEelQQ,14
|
388
|
+
akshare-1.16.18.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|