akshare 1.12.99__py3-none-any.whl → 1.15.72__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 akshare might be problematic. Click here for more details.

Files changed (236) hide show
  1. akshare/__init__.py +441 -138
  2. akshare/air/air_hebei.py +79 -53
  3. akshare/air/air_zhenqi.py +29 -43
  4. akshare/air/sunrise_tad.py +32 -17
  5. akshare/bank/bank_cbirc_2020.py +12 -9
  6. akshare/bond/bond_cb_ths.py +17 -9
  7. akshare/bond/bond_china.py +38 -39
  8. akshare/bond/bond_china_money.py +75 -48
  9. akshare/bond/bond_info_cm.py +28 -8
  10. akshare/bond/bond_issue_cninfo.py +73 -30
  11. akshare/bond/bond_zh_cov.py +1 -1
  12. akshare/bond/bond_zh_sina.py +57 -51
  13. akshare/cal/__init__.py +0 -0
  14. akshare/cal/rv.py +170 -0
  15. akshare/cost/cost_living.py +7 -5
  16. akshare/currency/currency_safe.py +7 -6
  17. akshare/data/cninfo.js +15 -0
  18. akshare/datasets.py +10 -21
  19. akshare/economic/macro_bank.py +95 -653
  20. akshare/economic/macro_china.py +772 -1024
  21. akshare/economic/macro_china_hk.py +65 -243
  22. akshare/economic/macro_china_nbs.py +24 -7
  23. akshare/economic/macro_constitute.py +17 -12
  24. akshare/economic/macro_euro.py +13 -6
  25. akshare/economic/macro_finance_ths.py +133 -0
  26. akshare/economic/macro_info_ws.py +100 -0
  27. akshare/economic/macro_japan.py +5 -4
  28. akshare/economic/macro_other.py +12 -9
  29. akshare/economic/macro_usa.py +376 -1940
  30. akshare/economic/marco_cnbs.py +11 -6
  31. akshare/energy/energy_carbon.py +94 -125
  32. akshare/event/migration.py +3 -2
  33. akshare/exceptions.py +43 -0
  34. akshare/file_fold/calendar.json +245 -2
  35. akshare/fortune/fortune_500.py +15 -48
  36. akshare/fund/fund_amac.py +157 -75
  37. akshare/fund/fund_em.py +191 -184
  38. akshare/fund/fund_etf_em.py +16 -15
  39. akshare/fund/fund_etf_sina.py +71 -23
  40. akshare/fund/fund_etf_ths.py +93 -0
  41. akshare/fund/fund_fee_em.py +98 -0
  42. akshare/fund/fund_portfolio_em.py +60 -50
  43. akshare/fund/fund_rank_em.py +91 -82
  44. akshare/fund/fund_report_cninfo.py +63 -48
  45. akshare/fund/fund_scale_sina.py +20 -10
  46. akshare/fund/fund_xq.py +139 -109
  47. akshare/futures/cons.py +8 -31
  48. akshare/futures/cot.py +185 -137
  49. akshare/futures/futures_basis.py +97 -32
  50. akshare/futures/futures_comm_ctp.py +37 -0
  51. akshare/futures/futures_comm_qihuo.py +74 -45
  52. akshare/futures/futures_daily_bar.py +121 -184
  53. akshare/futures/futures_hf_em.py +66 -61
  54. akshare/futures/futures_hq_sina.py +79 -61
  55. akshare/futures/futures_index_ccidx.py +6 -3
  56. akshare/futures/futures_inventory_99.py +61 -272
  57. akshare/futures/futures_news_shmet.py +4 -2
  58. akshare/futures/futures_roll_yield.py +12 -25
  59. akshare/futures/futures_spot_stock_em.py +19 -13
  60. akshare/futures/futures_stock_js.py +14 -12
  61. akshare/futures/futures_to_spot.py +38 -33
  62. akshare/futures/futures_warehouse_receipt.py +75 -71
  63. akshare/futures/futures_zh_sina.py +5 -5
  64. akshare/futures/symbol_var.py +18 -13
  65. akshare/futures_derivative/futures_contract_info_czce.py +60 -52
  66. akshare/futures_derivative/futures_contract_info_ine.py +43 -34
  67. akshare/futures_derivative/futures_contract_info_shfe.py +46 -35
  68. akshare/futures_derivative/futures_cot_sina.py +26 -19
  69. akshare/futures_derivative/futures_spot_sys.py +21 -8
  70. akshare/fx/currency_investing.py +19 -285
  71. akshare/index/index_cflp.py +29 -26
  72. akshare/index/index_cni.py +86 -88
  73. akshare/index/index_cons.py +26 -10
  74. akshare/index/index_cx.py +248 -47
  75. akshare/index/index_drewry.py +17 -16
  76. akshare/index/index_option_qvix.py +329 -0
  77. akshare/index/index_research_fund_sw.py +134 -0
  78. akshare/index/{index_sw_research.py → index_research_sw.py} +122 -58
  79. akshare/index/index_spot.py +9 -5
  80. akshare/index/index_stock_hk.py +35 -16
  81. akshare/index/index_stock_us_sina.py +1 -1
  82. akshare/index/index_stock_zh.py +180 -89
  83. akshare/index/index_stock_zh_csindex.py +15 -369
  84. akshare/index/index_sw.py +62 -34
  85. akshare/index/index_yw.py +46 -23
  86. akshare/index/index_zh_a_scope.py +48 -0
  87. akshare/index/index_zh_em.py +6 -4
  88. akshare/interest_rate/interbank_rate_em.py +14 -9
  89. akshare/movie/artist_yien.py +32 -5
  90. akshare/movie/movie_yien.py +92 -18
  91. akshare/movie/video_yien.py +28 -5
  92. akshare/news/news_baidu.py +78 -44
  93. akshare/news/news_cctv.py +38 -38
  94. akshare/news/news_stock.py +6 -3
  95. akshare/nlp/nlp_interface.py +7 -8
  96. akshare/option/cons.py +11 -11
  97. akshare/option/option_comm_qihuo.py +86 -0
  98. akshare/option/option_commodity.py +178 -51
  99. akshare/option/option_daily_stats_sse_szse.py +146 -0
  100. akshare/option/option_em.py +147 -138
  101. akshare/option/option_finance_sina.py +160 -137
  102. akshare/option/option_lhb_em.py +62 -56
  103. akshare/option/option_risk_indicator_sse.py +17 -14
  104. akshare/other/other_car_cpca.py +934 -0
  105. akshare/other/{other_car.py → other_car_gasgoo.py} +15 -54
  106. akshare/qdii/__init__.py +0 -0
  107. akshare/qdii/qdii_jsl.py +233 -0
  108. akshare/request.py +117 -0
  109. akshare/spot/spot_hog_soozhu.py +232 -0
  110. akshare/spot/spot_price_qh.py +121 -0
  111. akshare/spot/spot_sge.py +63 -10
  112. akshare/stock/stock_allotment_cninfo.py +10 -9
  113. akshare/stock/stock_board_concept_em.py +23 -14
  114. akshare/stock/stock_board_industry_em.py +40 -34
  115. akshare/stock/stock_cg_equity_mortgage.py +15 -11
  116. akshare/stock/stock_cg_guarantee.py +41 -51
  117. akshare/stock/stock_cg_lawsuit.py +36 -35
  118. akshare/stock/stock_dividend_cninfo.py +12 -6
  119. akshare/stock/stock_dzjy_em.py +347 -260
  120. akshare/stock/stock_fund_em.py +332 -84
  121. akshare/stock/stock_hk_famous.py +108 -0
  122. akshare/stock/stock_hk_sina.py +8 -7
  123. akshare/stock/stock_hold_control_cninfo.py +100 -15
  124. akshare/stock/stock_hold_control_em.py +4 -3
  125. akshare/stock/stock_hold_num_cninfo.py +18 -12
  126. akshare/stock/stock_hot_rank_em.py +2 -1
  127. akshare/stock/stock_hot_search_baidu.py +5 -2
  128. akshare/stock/stock_industry_cninfo.py +24 -18
  129. akshare/stock/stock_industry_pe_cninfo.py +45 -31
  130. akshare/stock/stock_industry_sw.py +9 -10
  131. akshare/stock/stock_info.py +25 -15
  132. akshare/stock/stock_info_em.py +5 -2
  133. akshare/stock/stock_intraday_em.py +5 -2
  134. akshare/stock/stock_intraday_sina.py +22 -18
  135. akshare/stock/stock_ipo_summary_cninfo.py +25 -10
  136. akshare/stock/stock_new_cninfo.py +32 -19
  137. akshare/stock/stock_news_cx.py +39 -0
  138. akshare/stock/stock_profile_cninfo.py +9 -8
  139. akshare/stock/stock_rank_forecast.py +8 -6
  140. akshare/stock/stock_share_changes_cninfo.py +18 -14
  141. akshare/stock/stock_share_hold.py +24 -19
  142. akshare/stock/stock_summary.py +54 -26
  143. akshare/stock/stock_us_famous.py +15 -6
  144. akshare/stock/stock_us_pink.py +7 -5
  145. akshare/stock/stock_us_sina.py +15 -12
  146. akshare/stock/stock_xq.py +38 -12
  147. akshare/stock/stock_zh_a_sina.py +53 -78
  148. akshare/stock/stock_zh_b_sina.py +32 -55
  149. akshare/stock/stock_zh_kcb_report.py +11 -9
  150. akshare/stock/stock_zh_kcb_sina.py +67 -64
  151. akshare/stock_feature/stock_a_below_net_asset_statistics.py +5 -2
  152. akshare/stock_feature/stock_a_high_low.py +5 -2
  153. akshare/stock_feature/stock_a_indicator.py +12 -9
  154. akshare/stock_feature/stock_a_pe_and_pb.py +27 -6
  155. akshare/stock_feature/stock_account_em.py +58 -40
  156. akshare/stock_feature/stock_analyst_em.py +36 -27
  157. akshare/stock_feature/stock_board_industry_ths.py +136 -400
  158. akshare/stock_feature/stock_comment_em.py +118 -85
  159. akshare/stock_feature/stock_concept_futu.py +183 -0
  160. akshare/stock_feature/stock_cyq_em.py +58 -54
  161. akshare/stock_feature/stock_disclosure_cninfo.py +147 -102
  162. akshare/stock_feature/stock_esg_sina.py +216 -11
  163. akshare/stock_feature/stock_fhps_em.py +60 -25
  164. akshare/stock_feature/stock_fhps_ths.py +25 -6
  165. akshare/stock_feature/stock_fund_flow.py +38 -25
  166. akshare/stock_feature/stock_gdfx_em.py +180 -95
  167. akshare/stock_feature/stock_gdhs.py +73 -49
  168. akshare/stock_feature/stock_gpzy_em.py +78 -46
  169. akshare/stock_feature/stock_hist_em.py +55 -23
  170. akshare/stock_feature/stock_hk_valuation_baidu.py +20 -8
  171. akshare/stock_feature/stock_hsgt_em.py +184 -452
  172. akshare/stock_feature/stock_info.py +52 -29
  173. akshare/stock_feature/stock_inner_trade_xq.py +39 -31
  174. akshare/stock_feature/stock_irm_cninfo.py +32 -9
  175. akshare/stock_feature/stock_jgdy_em.py +41 -38
  176. akshare/stock_feature/stock_lh_yybpm.py +36 -37
  177. akshare/stock_feature/stock_lhb_em.py +135 -71
  178. akshare/stock_feature/stock_lhb_sina.py +93 -46
  179. akshare/stock_feature/stock_margin_em.py +102 -0
  180. akshare/stock_feature/{stock_sse_margin.py → stock_margin_sse.py} +21 -15
  181. akshare/stock_feature/{stock_szse_margin.py → stock_margin_szse.py} +23 -19
  182. akshare/stock_feature/stock_market_legu.py +13 -8
  183. akshare/stock_feature/stock_pankou_em.py +72 -34
  184. akshare/stock_feature/stock_report_em.py +244 -54
  185. akshare/stock_feature/stock_research_report_em.py +48 -19
  186. akshare/stock_feature/stock_sns_sseinfo.py +15 -12
  187. akshare/stock_feature/stock_sy_em.py +86 -33
  188. akshare/stock_feature/stock_technology_ths.py +152 -120
  189. akshare/stock_feature/stock_tfp_em.py +35 -13
  190. akshare/stock_feature/stock_three_report_em.py +119 -77
  191. akshare/stock_feature/stock_ttm_lyr.py +4 -7
  192. akshare/stock_feature/stock_value_em.py +83 -0
  193. akshare/stock_feature/stock_wencai.py +21 -9
  194. akshare/stock_feature/stock_yjyg_em.py +63 -28
  195. akshare/stock_feature/stock_zf_pg.py +61 -38
  196. akshare/stock_feature/stock_zh_valuation_baidu.py +3 -2
  197. akshare/stock_feature/stock_ztb_em.py +62 -40
  198. akshare/stock_fundamental/stock_finance.py +150 -58
  199. akshare/stock_fundamental/stock_finance_ths.py +116 -31
  200. akshare/stock_fundamental/stock_mda_ym.py +5 -3
  201. akshare/stock_fundamental/stock_notice.py +29 -15
  202. akshare/stock_fundamental/stock_profit_forecast_em.py +31 -13
  203. akshare/stock_fundamental/stock_profit_forecast_ths.py +19 -10
  204. akshare/stock_fundamental/stock_register_em.py +448 -0
  205. akshare/stock_fundamental/stock_restricted_em.py +79 -32
  206. akshare/stock_fundamental/stock_zygc.py +10 -8
  207. akshare/stock_fundamental/stock_zyjs_ths.py +5 -3
  208. akshare/tool/trade_date_hist.py +4 -3
  209. akshare/utils/cons.py +10 -0
  210. akshare/utils/context.py +43 -0
  211. akshare/utils/demjson.py +2 -2
  212. akshare/utils/func.py +26 -0
  213. akshare/utils/tqdm.py +13 -3
  214. {akshare-1.12.99.dist-info → akshare-1.15.72.dist-info}/METADATA +52 -69
  215. akshare-1.15.72.dist-info/RECORD +385 -0
  216. {akshare-1.12.99.dist-info → akshare-1.15.72.dist-info}/WHEEL +1 -1
  217. tests/test_func.py +3 -5
  218. akshare/bond/bond_futures.py +0 -50
  219. akshare/bond/bond_investing.py +0 -139
  220. akshare/crypto/crypto_hist_investing.py +0 -249
  221. akshare/fortune/fortune_it_juzi.py +0 -123
  222. akshare/futures/futures_international.py +0 -170
  223. akshare/futures/futures_news_baidu.py +0 -54
  224. akshare/futures/inventory_data.py +0 -100
  225. akshare/futures_derivative/futures_index_price_nh.py +0 -61
  226. akshare/futures_derivative/futures_index_return_nh.py +0 -47
  227. akshare/futures_derivative/futures_index_volatility_nh.py +0 -51
  228. akshare/futures_derivative/futures_other_index_nh.py +0 -145
  229. akshare/index/index_fear_greed_funddb.py +0 -71
  230. akshare/index/index_investing.py +0 -232
  231. akshare/sport/sport_olympic_winter.py +0 -39
  232. akshare/stock_feature/stock_board_concept_ths.py +0 -422
  233. akshare/stock_fundamental/stock_register.py +0 -292
  234. akshare-1.12.99.dist-info/RECORD +0 -374
  235. {akshare-1.12.99.dist-info → akshare-1.15.72.dist-info}/LICENSE +0 -0
  236. {akshare-1.12.99.dist-info → akshare-1.15.72.dist-info}/top_level.txt +0 -0
akshare/air/air_hebei.py CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding:utf-8 -*-
3
3
  """
4
- Date: 2022/3/5 12:33
4
+ Date: 2024/4/25 17:20
5
5
  Desc: 河北省空气质量预报信息发布系统
6
- http://110.249.223.67/publish/
6
+ https://110.249.223.67/publish
7
7
  每日 17 时发布
8
8
  等级划分
9
9
  1. 空气污染指数为0-50,空气质量级别为一级,空气质量状况属于优。此时,空气质量令人满意,基本无空气污染,各类人群可正常活动。
@@ -14,68 +14,94 @@ http://110.249.223.67/publish/
14
14
  6. 空气污染指数大于300,空气质量级别为六级,空气质量状况属于严重污染。此时,健康人群运动耐受力降低,有明显强烈症状,提前出现某些疾病,建议儿童、老年人和病人应当留在室内,避免体力消耗,一般人群应避免户外活动。
15
15
  发布单位:河北省环境应急与重污染天气预警中心 技术支持:中国科学院大气物理研究所 中科三清科技有限公司
16
16
  """
17
- from datetime import datetime
18
17
 
19
18
  import pandas as pd
20
19
  import requests
21
- from tqdm import tqdm
20
+ from bs4 import BeautifulSoup
22
21
 
23
22
 
24
- def air_quality_hebei(symbol: str = "唐山市") -> pd.DataFrame:
23
+ def air_quality_hebei() -> pd.DataFrame:
25
24
  """
26
25
  河北省空气质量预报信息发布系统-空气质量预报, 未来 6 天
27
- http://110.249.223.67/publish/
28
- :param symbol: choice of {'石家庄市', '唐山市', '秦皇岛市', '邯郸市', '邢台市', '保定市', '张家口市', '承德市', '沧州市', '廊坊市', '衡水市', '辛集市', '定州市'}
29
- :type symbol: str
26
+ http://218.11.10.130:8080/#/application/home
30
27
  :return: city = "", 返回所有地区的数据; city="唐山市", 返回唐山市的数据
31
28
  :rtype: pandas.DataFrame
32
29
  """
33
- url = "http://110.249.223.67/server/api/CityPublishInfo/GetProvinceAndCityPublishData"
34
- params = {"publishDate": f"{datetime.today().strftime('%Y-%m-%d')} 16:00:00"}
35
- r = requests.get(url, params=params)
36
- json_data = r.json()
37
- city_list = pd.DataFrame.from_dict(json_data["cityPublishDatas"], orient="columns")[
38
- "CityName"
39
- ].tolist()
40
- outer_df = pd.DataFrame()
41
- for i in tqdm(range(1, 7), leave=False):
42
- inner_df = pd.DataFrame(
43
- [item[f"Date{i}"] for item in json_data["cityPublishDatas"]],
44
- index=city_list,
45
- )
46
- outer_df = pd.concat([outer_df, inner_df])
47
- if symbol == "":
48
- temp_df = outer_df.reset_index()
49
- temp_df.columns = [
50
- 'city',
51
- 'date',
52
- 'pollutant',
53
- 'minAQI',
54
- 'maxAQI',
55
- 'level',
56
- ]
57
- temp_df['date'] = pd.to_datetime(temp_df['date']).dt.date
58
- temp_df['minaqi'] = pd.to_numeric(temp_df['minaqi'])
59
- temp_df['maxaqi'] = pd.to_numeric(temp_df['maxaqi'])
60
- return temp_df
61
- else:
62
- temp_df = outer_df.reset_index()
63
- temp_df.columns = [
64
- 'city',
65
- 'date',
66
- 'pollutant',
67
- 'minaqi',
68
- 'maxaqi',
69
- 'level',
70
- ]
71
- temp_df['date'] = pd.to_datetime(temp_df['date']).dt.date
72
- temp_df['minaqi'] = pd.to_numeric(temp_df['minaqi'])
73
- temp_df['maxaqi'] = pd.to_numeric(temp_df['maxaqi'])
74
- temp_df = temp_df[temp_df['city'] == symbol]
75
- temp_df.reset_index(inplace=True, drop=True)
76
- return temp_df
30
+ url = "http://218.11.10.130:8080/api/hour/130000.xml"
31
+ r = requests.get(url)
32
+ soup = BeautifulSoup(r.content, features="xml")
33
+ data = []
34
+ cities = soup.find_all("City")
35
+ for city in cities:
36
+ pointers = city.find_all("Pointer")
37
+ for pointer in pointers:
38
+ row = {
39
+ "City": city.Name.text if city.Name else None,
40
+ "Region": pointer.Region.text if pointer.Region else None,
41
+ "Station": pointer.Name.text if pointer.Name else None,
42
+ "DateTime": pointer.DataTime.text if pointer.DataTime else None,
43
+ "AQI": pointer.AQI.text if pointer.AQI else None,
44
+ "Level": pointer.Level.text if pointer.Level else None,
45
+ "MaxPoll": pointer.MaxPoll.text if pointer.MaxPoll else None,
46
+ "Longitude": pointer.CLng.text if pointer.CLng else None,
47
+ "Latitude": pointer.CLat.text if pointer.CLat else None,
48
+ }
49
+ polls = pointer.find_all("Poll")
50
+ for poll in polls:
51
+ poll_name = poll.Name.text if poll.Name else None
52
+ poll_value = poll.Value.text if poll.Value else None
53
+ row[f"{poll_name}_Value"] = poll_value
54
+ row[f"{poll_name}_IAQI"] = poll.IAQI.text if poll.IAQI else None
55
+ data.append(row)
56
+
57
+ df = pd.DataFrame(data)
58
+ numeric_columns = ["AQI", "Longitude", "Latitude"] + [
59
+ col for col in df.columns if col.endswith("_Value") or col.endswith("_IAQI")
60
+ ]
61
+ for col in numeric_columns:
62
+ df[col] = pd.to_numeric(df[col], errors="coerce")
63
+
64
+ column_names = {
65
+ "City": "城市",
66
+ "Region": "区域",
67
+ "Station": "监测点",
68
+ "DateTime": "时间",
69
+ "Level": "空气质量等级",
70
+ "MaxPoll": "首要污染物",
71
+ "Longitude": "经度",
72
+ "Latitude": "纬度",
73
+ "SO2_Value": "二氧化硫_浓度",
74
+ "SO2_IAQI": "二氧化硫_IAQI",
75
+ "CO_Value": "一氧化碳_浓度",
76
+ "CO_IAQI": "一氧化碳_IAQI",
77
+ "NO2_Value": "二氧化氮_浓度",
78
+ "NO2_IAQI": "二氧化氮_IAQI",
79
+ "O3-1H_Value": "臭氧1小时_浓度",
80
+ "O3-1H_IAQI": "臭氧1小时_IAQI",
81
+ "O3-8H_Value": "臭氧8小时_浓度",
82
+ "O3-8H_IAQI": "臭氧8小时_IAQI",
83
+ "PM2.5_Value": "PM2.5_浓度",
84
+ "PM2.5_IAQI": "PM2.5_IAQI",
85
+ "PM10_Value": "PM10_浓度",
86
+ "PM10_IAQI": "PM10_IAQI",
87
+ }
88
+ df = df.rename(columns=column_names)
89
+ basic_columns = [
90
+ "城市",
91
+ "区域",
92
+ "监测点",
93
+ "时间",
94
+ "AQI",
95
+ "空气质量等级",
96
+ "首要污染物",
97
+ "经度",
98
+ "纬度",
99
+ ]
100
+ pollutant_columns = [col for col in df.columns if col not in basic_columns]
101
+ df = df[basic_columns + sorted(pollutant_columns)]
102
+ return df
77
103
 
78
104
 
79
105
  if __name__ == "__main__":
80
- air_quality_hebei_df = air_quality_hebei(symbol="定州市")
106
+ air_quality_hebei_df = air_quality_hebei()
81
107
  print(air_quality_hebei_df)
akshare/air/air_zhenqi.py CHANGED
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding:utf-8 -*-
3
3
  """
4
- Date: 2022/2/24 14:50
4
+ Date: 2024/4/2 22:40
5
5
  Desc: 真气网-空气质量
6
6
  https://www.zq12369.com/environment.php
7
7
  空气质量在线监测分析平台的空气质量数据
8
8
  https://www.aqistudy.cn/
9
9
  """
10
+
10
11
  import json
11
12
  import os
12
13
  import re
@@ -14,7 +15,7 @@ from io import StringIO
14
15
 
15
16
  import pandas as pd
16
17
  import requests
17
- from py_mini_racer import py_mini_racer
18
+ from py_mini_racer import MiniRacer
18
19
 
19
20
  from akshare.utils import demjson
20
21
 
@@ -29,9 +30,7 @@ def _get_js_path(name: str = None, module_file: str = None) -> str:
29
30
  :return: 路径
30
31
  :rtype: str
31
32
  """
32
- module_folder = os.path.abspath(
33
- os.path.dirname(os.path.dirname(module_file))
34
- )
33
+ module_folder = os.path.abspath(os.path.dirname(os.path.dirname(module_file)))
35
34
  module_json_path = os.path.join(module_folder, "air", name)
36
35
  return module_json_path
37
36
 
@@ -71,6 +70,7 @@ def air_city_table() -> pd.DataFrame:
71
70
  """
72
71
  url = "https://www.zq12369.com/environment.php"
73
72
  date = "2020-05-01"
73
+ temp_df = None
74
74
  if len(date.split("-")) == 3:
75
75
  params = {
76
76
  "date": date,
@@ -83,13 +83,21 @@ def air_city_table() -> pd.DataFrame:
83
83
  del temp_df["降序"]
84
84
  temp_df.reset_index(inplace=True)
85
85
  temp_df["index"] = temp_df.index + 1
86
- temp_df.columns = ["序号", "省份", "城市", "AQI", "空气质量", "PM2.5浓度", "首要污染物"]
86
+ temp_df.columns = [
87
+ "序号",
88
+ "省份",
89
+ "城市",
90
+ "AQI",
91
+ "空气质量",
92
+ "PM2.5浓度",
93
+ "首要污染物",
94
+ ]
87
95
  temp_df["AQI"] = pd.to_numeric(temp_df["AQI"])
88
96
  return temp_df
89
97
 
90
98
 
91
99
  def air_quality_watch_point(
92
- city: str = "杭州", start_date: str = "20220408", end_date: str = "20220409"
100
+ city: str = "杭州", start_date: str = "20220408", end_date: str = "20220409"
93
101
  ) -> pd.DataFrame:
94
102
  """
95
103
  真气网-监测点空气质量-细化到具体城市的每个监测点
@@ -108,7 +116,7 @@ def air_quality_watch_point(
108
116
  end_date = "-".join([end_date[:4], end_date[4:6], end_date[6:]])
109
117
  url = "https://www.zq12369.com/api/zhenqiapi.php"
110
118
  file_data = _get_file_content(file_name="crypto.js")
111
- ctx = py_mini_racer.MiniRacer()
119
+ ctx = MiniRacer()
112
120
  ctx.eval(file_data)
113
121
  method = "GETCITYPOINTAVG"
114
122
  ctx.call("encode_param", method)
@@ -122,12 +130,11 @@ def air_quality_watch_point(
122
130
  "city": city_param,
123
131
  "startTime": ctx.call("encode_param", start_date),
124
132
  "endTime": ctx.call("encode_param", end_date),
125
- "secret": ctx.call(
126
- "encode_secret", method, city_param, start_date, end_date
127
- ),
133
+ "secret": ctx.call("encode_secret", method, city_param, start_date, end_date),
128
134
  }
129
135
  headers = {
130
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36"
136
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
137
+ "Chrome/81.0.4044.122 Safari/537.36"
131
138
  }
132
139
  r = requests.post(url, data=payload, headers=headers)
133
140
  data_text = r.text
@@ -137,10 +144,10 @@ def air_quality_watch_point(
137
144
 
138
145
 
139
146
  def air_quality_hist(
140
- city: str = "杭州",
141
- period: str = "day",
142
- start_date: str = "20190327",
143
- end_date: str = "20200427",
147
+ city: str = "杭州",
148
+ period: str = "day",
149
+ start_date: str = "20190327",
150
+ end_date: str = "20200427",
144
151
  ) -> pd.DataFrame:
145
152
  """
146
153
  真气网-空气历史数据
@@ -160,9 +167,9 @@ def air_quality_hist(
160
167
  end_date = "-".join([end_date[:4], end_date[4:6], end_date[6:]])
161
168
  url = "https://www.zq12369.com/api/newzhenqiapi.php"
162
169
  file_data = _get_file_content(file_name="outcrypto.js")
163
- ctx = py_mini_racer.MiniRacer()
170
+ ctx = MiniRacer()
164
171
  ctx.eval(file_data)
165
- appId = "4f0e3a273d547ce6b7147bfa7ceb4b6e"
172
+ app_id = "4f0e3a273d547ce6b7147bfa7ceb4b6e"
166
173
  method = "CETCITYPERIOD"
167
174
  timestamp = ctx.eval("timestamp = new Date().getTime()")
168
175
  p_text = json.dumps(
@@ -175,9 +182,7 @@ def air_quality_hist(
175
182
  ensure_ascii=False,
176
183
  indent=None,
177
184
  ).replace(' "', '"')
178
- secret = ctx.call(
179
- "hex_md5", appId + method + str(timestamp) + "WEB" + p_text
180
- )
185
+ secret = ctx.call("hex_md5", app_id + method + str(timestamp) + "WEB" + p_text)
181
186
  payload = {
182
187
  "appId": "4f0e3a273d547ce6b7147bfa7ceb4b6e",
183
188
  "method": "CETCITYPERIOD",
@@ -200,30 +205,11 @@ def air_quality_hist(
200
205
  )
201
206
 
202
207
  headers = {
203
- # 'Accept': '*/*',
204
- # 'Accept-Encoding': 'gzip, deflate, br',
205
- # 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
206
- # 'Cache-Control': 'no-cache',
207
- # 'Connection': 'keep-alive',
208
- # 'Content-Length': '1174',
209
- # 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
210
- # 'Cookie': 'UM_distinctid=1800e5142c5b85-04b8f11aa852f3-1a343370-1fa400-1800e5142c6b7e; CNZZDATA1254317176=1502593570-1649496979-%7C1649507817; city=%E6%9D%AD%E5%B7%9E; SECKEY_ABVK=eSrbUhd28Mjo7jf8Rfh+uY5E9C+tAhQ8mOfYJHSjSfY%3D; BMAP_SECKEY=N5fGcwdWpeJW46eZRpR9GW3qdVnODGQwGm6JE0ELECQHJOTFc9MCuNdyf8OWUspFI6Xq4MMPxgVVr5I13odFOW6AQMgSPOtEvVHciC2NsQwb1pnmFtEaqyKHOUeavelt0ejBy6ETRD_4FXAhZb9FSbVIMPew7qwFX_kdPDxVJH-vHfCVhRx9XDZgb41B_T4D',
211
- # 'Host': 'www.zq12369.com',
212
- # 'Origin': 'https://www.zq12369.com',
213
- # 'Pragma': 'no-cache',
214
- # 'Referer': 'https://www.zq12369.com/environment.php?catid=4',
215
- # 'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"',
216
- # 'sec-ch-ua-mobile': '?0',
217
- # 'sec-ch-ua-platform': '"Windows"',
218
- # 'Sec-Fetch-Dest': 'empty',
219
- # 'Sec-Fetch-Mode': 'cors',
220
- # 'Sec-Fetch-Site': 'same-origin',
221
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36",
208
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
209
+ "Chrome/100.0.4896.75 Safari/537.36",
222
210
  "X-Requested-With": "XMLHttpRequest",
223
211
  }
224
- params = {"param": ctx.call("AES.encrypt", need)}
225
212
  params = {"param": ctx.call("encode_param", need)}
226
-
227
213
  r = requests.post(url, data=params, headers=headers)
228
214
  temp_text = ctx.call("decryptData", r.text)
229
215
  data_json = demjson.decode(ctx.call("b.decode", temp_text))
@@ -304,7 +290,7 @@ if __name__ == "__main__":
304
290
  city="北京",
305
291
  period="day",
306
292
  start_date="20220801",
307
- end_date="20220816",
293
+ end_date="20240402",
308
294
  )
309
295
  print(air_quality_hist_df)
310
296
 
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding:utf-8 -*-
3
3
  """
4
- Date: 2024/1/24 15:00
4
+ Date: 2024/4/29 16:00
5
5
  Desc: 日出和日落数据
6
6
  https://www.timeanddate.com
7
7
  """
8
+
8
9
  from io import StringIO
9
10
 
10
11
  import pandas as pd
11
- import pypinyin
12
12
  import requests
13
13
 
14
14
 
@@ -31,11 +31,13 @@ def sunrise_city_list() -> list:
31
31
  city_list.extend([item.lower() for item in china_city_two_df.iloc[:, 1].tolist()])
32
32
  city_list.extend([item.lower() for item in china_city_two_df.iloc[:, 2].tolist()])
33
33
  city_list.extend([item.lower() for item in china_city_two_df.iloc[:, 3].tolist()])
34
- city_list.extend([item.lower() for item in china_city_two_df.iloc[:, 4].dropna().tolist()])
34
+ city_list.extend(
35
+ [item.lower() for item in china_city_two_df.iloc[:, 4].dropna().tolist()]
36
+ )
35
37
  return city_list
36
38
 
37
39
 
38
- def sunrise_daily(date: str = "20200428", city: str = "北京") -> pd.DataFrame:
40
+ def sunrise_daily(date: str = "20240428", city: str = "beijing") -> pd.DataFrame:
39
41
  """
40
42
  每日日出日落数据
41
43
  https://www.timeanddate.com/astronomy/china/shaoxing
@@ -46,24 +48,29 @@ def sunrise_daily(date: str = "20200428", city: str = "北京") -> pd.DataFrame:
46
48
  :return: 返回指定日期指定地区的日出日落数据
47
49
  :rtype: pandas.DataFrame
48
50
  """
49
- if pypinyin.slug(city, separator='') in sunrise_city_list():
51
+ import urllib3
52
+
53
+ urllib3.disable_warnings()
54
+ if city in sunrise_city_list():
50
55
  year = date[:4]
51
56
  month = date[4:6]
52
- url = f"https://www.timeanddate.com/sun/china/{pypinyin.slug(city, separator='')}?month={month}&year={year}"
53
- r = requests.get(url)
57
+ url = f"https://www.timeanddate.com/sun/china/{city}?month={month}&year={year}"
58
+ r = requests.get(url, verify=False)
54
59
  table = pd.read_html(StringIO(r.text), header=2)[1]
55
- month_df = table.iloc[:-1, ]
56
- day_df = month_df[month_df.iloc[:, 0].astype(str).str.zfill(2) == date[6:]].copy()
60
+ month_df = table.iloc[:-1,]
61
+ day_df = month_df[
62
+ month_df.iloc[:, 0].astype(str).str.zfill(2) == date[6:]
63
+ ].copy()
57
64
  day_df.index = pd.to_datetime([date] * len(day_df), format="%Y%m%d")
58
65
  day_df.reset_index(inplace=True)
59
66
  day_df.rename(columns={"index": "date"}, inplace=True)
60
- day_df['date'] = pd.to_datetime(day_df['date']).dt.date
67
+ day_df["date"] = pd.to_datetime(day_df["date"]).dt.date
61
68
  return day_df
62
69
  else:
63
70
  raise "请输入正确的城市名称"
64
71
 
65
72
 
66
- def sunrise_monthly(date: str = "20190801", city: str = "北京") -> pd.DataFrame:
73
+ def sunrise_monthly(date: str = "20240428", city: str = "beijing") -> pd.DataFrame:
67
74
  """
68
75
  每个指定 date 所在月份的每日日出日落数据, 如果当前月份未到月底, 则以预测值填充
69
76
  https://www.timeanddate.com/astronomy/china/shaoxing
@@ -74,24 +81,32 @@ def sunrise_monthly(date: str = "20190801", city: str = "北京") -> pd.DataFram
74
81
  :return: 指定 date 所在月份的每日日出日落数据
75
82
  :rtype: pandas.DataFrame
76
83
  """
77
- if pypinyin.slug(city, separator='') in sunrise_city_list():
84
+ import urllib3
85
+
86
+ urllib3.disable_warnings()
87
+ if city in sunrise_city_list():
78
88
  year = date[:4]
79
89
  month = date[4:6]
80
- url = f"https://www.timeanddate.com/sun/china/{pypinyin.slug(city, separator='')}?month={month}&year={year}"
90
+ url = f"https://www.timeanddate.com/sun/china/{city}?month={month}&year={year}"
81
91
  r = requests.get(url)
82
92
  table = pd.read_html(StringIO(r.text), header=2)[1]
83
- month_df = table.iloc[:-1, ].copy()
93
+ month_df = table.iloc[:-1,].copy()
84
94
  month_df.index = [date[:-2]] * len(month_df)
85
95
  month_df.reset_index(inplace=True)
86
- month_df.rename(columns={"index": "date", }, inplace=True)
96
+ month_df.rename(
97
+ columns={
98
+ "index": "date",
99
+ },
100
+ inplace=True,
101
+ )
87
102
  return month_df
88
103
  else:
89
104
  raise "请输入正确的城市名称"
90
105
 
91
106
 
92
107
  if __name__ == "__main__":
93
- sunrise_daily_df = sunrise_daily(date="20230220", city="北京")
108
+ sunrise_daily_df = sunrise_daily(date="20240428", city="beijing")
94
109
  print(sunrise_daily_df)
95
110
 
96
- sunrise_monthly_df = sunrise_monthly(date="20230220", city="北京")
111
+ sunrise_monthly_df = sunrise_monthly(date="20240428", city="beijing")
97
112
  print(sunrise_monthly_df)
@@ -8,6 +8,7 @@ https://www.cbirc.gov.cn/cn/view/pages/ItemList.html?itemPId=923&itemId=4115&ite
8
8
  https://www.cbirc.gov.cn/cn/static/data/DocInfo/SelectByDocId/data_docId=881446.json
9
9
  2020 新接口
10
10
  """
11
+
11
12
  import warnings
12
13
  from io import StringIO
13
14
 
@@ -33,7 +34,7 @@ def bank_fjcf_total_num(item: str = "分局本级") -> int:
33
34
  "分局本级": "4115",
34
35
  }
35
36
  cbirc_headers = cbirc_headers_without_cookie_2020.copy()
36
- main_url = "http://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
37
+ main_url = "https://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
37
38
  params = {
38
39
  "itemId": item_id_list[item],
39
40
  "pageSize": "18",
@@ -60,7 +61,7 @@ def bank_fjcf_total_page(item: str = "分局本级", begin: int = 1) -> int:
60
61
  "分局本级": "4115",
61
62
  }
62
63
  cbirc_headers = cbirc_headers_without_cookie_2020.copy()
63
- main_url = "http://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
64
+ main_url = "https://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
64
65
  params = {
65
66
  "itemId": item_id_list[item],
66
67
  "pageSize": "18",
@@ -73,7 +74,7 @@ def bank_fjcf_total_page(item: str = "分局本级", begin: int = 1) -> int:
73
74
 
74
75
 
75
76
  def bank_fjcf_page_url(
76
- page: int = 5, item: str = "分局本级", begin: int = 1
77
+ page: int = 5, item: str = "分局本级", begin: int = 1
77
78
  ) -> pd.DataFrame:
78
79
  """
79
80
  获取 首页-政务信息-行政处罚-银保监分局本级-每一页的 json 数据
@@ -92,7 +93,7 @@ def bank_fjcf_page_url(
92
93
  "分局本级": "4115",
93
94
  }
94
95
  cbirc_headers = cbirc_headers_without_cookie_2020.copy()
95
- main_url = "http://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
96
+ main_url = "https://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
96
97
  temp_df = pd.DataFrame()
97
98
  for i_page in tqdm(range(begin, page + begin), leave=False):
98
99
  params = {
@@ -108,7 +109,7 @@ def bank_fjcf_page_url(
108
109
 
109
110
 
110
111
  def bank_fjcf_table_detail(
111
- page: int = 5, item: str = "分局本级", begin: int = 1
112
+ page: int = 5, item: str = "分局本级", begin: int = 1
112
113
  ) -> pd.DataFrame:
113
114
  """
114
115
  获取 首页-政务信息-行政处罚-银保监分局本级-XXXX行政处罚信息公开表 数据
@@ -124,7 +125,7 @@ def bank_fjcf_table_detail(
124
125
  id_list = bank_fjcf_page_url(page=page, item=item, begin=begin)["docId"]
125
126
  big_df = pd.DataFrame()
126
127
  for item in id_list:
127
- url = f"http://www.cbirc.gov.cn/cn/static/data/DocInfo/SelectByDocId/data_docId={item}.json"
128
+ url = f"https://www.cbirc.gov.cn/cn/static/data/DocInfo/SelectByDocId/data_docId={item}.json"
128
129
  res = requests.get(url)
129
130
  try:
130
131
  table_list = pd.read_html(StringIO(res.json()["data"]["docClob"]))[0]
@@ -146,7 +147,9 @@ def bank_fjcf_table_detail(
146
147
  table_list = table_list[2:]
147
148
  table_list.insert(2, pd.NA)
148
149
  else:
149
- print(f"{item} 异常,请通过 https://www.cbirc.gov.cn/cn/view/pages/ItemDetail.html?docId={item} 查看")
150
+ print(
151
+ f"{item} 异常,请通过 https://www.cbirc.gov.cn/cn/view/pages/ItemDetail.html?docId={item} 查看"
152
+ )
150
153
  continue
151
154
 
152
155
  # 部分会变成嵌套列表, 这里还原
@@ -159,7 +162,7 @@ def bank_fjcf_table_detail(
159
162
  table_df.columns = ["内容"]
160
163
  big_df = pd.concat(objs=[big_df, table_df.T], ignore_index=True)
161
164
  # 解决有些页面缺少字段的问题, 都放到 try 里面
162
- except:
165
+ except: # noqa: E722
163
166
  warnings.warn(f"{item} 不是表格型数据,将跳过采集")
164
167
  continue
165
168
  if big_df.empty:
@@ -182,5 +185,5 @@ def bank_fjcf_table_detail(
182
185
 
183
186
 
184
187
  if __name__ == "__main__":
185
- bank_fjcf_table_detail_df = bank_fjcf_table_detail(page=1, item="机关", begin=11)
188
+ bank_fjcf_table_detail_df = bank_fjcf_table_detail(page=1, item="机关", begin=1)
186
189
  print(bank_fjcf_table_detail_df)
@@ -1,24 +1,26 @@
1
1
  # -*- coding:utf-8 -*-
2
2
  # !/usr/bin/env python
3
3
  """
4
- Date: 2023/5/4 22:46
4
+ Date: 2024/8/14 11:30
5
5
  Desc: 同花顺-数据中心-可转债
6
- http://data.10jqka.com.cn/ipo/bond/
6
+ https://data.10jqka.com.cn/ipo/bond/
7
7
  """
8
- import requests
8
+
9
9
  import pandas as pd
10
+ import requests
10
11
 
11
12
 
12
13
  def bond_zh_cov_info_ths() -> pd.DataFrame:
13
14
  """
14
15
  同花顺-数据中心-可转债
15
- http://data.10jqka.com.cn/ipo/bond/
16
+ https://data.10jqka.com.cn/ipo/bond/
16
17
  :return: 可转债行情
17
18
  :rtype: pandas.DataFrame
18
19
  """
19
- url = "http://data.10jqka.com.cn/ipo/kzz/"
20
+ url = "https://data.10jqka.com.cn/ipo/kzz/"
20
21
  headers = {
21
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",
22
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
23
+ "Chrome/89.0.4389.90 Safari/537.36",
22
24
  }
23
25
  r = requests.get(url, headers=headers)
24
26
  data_json = r.json()
@@ -67,12 +69,18 @@ def bond_zh_cov_info_ths() -> pd.DataFrame:
67
69
  "中签率",
68
70
  ]
69
71
  ]
70
- temp_df["申购日期"] = pd.to_datetime(temp_df["申购日期"], format="%Y-%m-%d").dt.date
71
- temp_df["中签公布日"] = pd.to_datetime(temp_df["中签公布日"], format="%Y-%m-%d").dt.date
72
+ temp_df["申购日期"] = pd.to_datetime(
73
+ temp_df["申购日期"], format="%Y-%m-%d", errors="coerce"
74
+ ).dt.date
75
+ temp_df["中签公布日"] = pd.to_datetime(
76
+ temp_df["中签公布日"], format="%Y-%m-%d", errors="coerce"
77
+ ).dt.date
72
78
  temp_df["上市日期"] = pd.to_datetime(
73
79
  temp_df["上市日期"], format="%Y-%m-%d", errors="coerce"
74
80
  ).dt.date
75
- temp_df["到期时间"] = pd.to_datetime(temp_df["到期时间"], format="%Y-%m-%d").dt.date
81
+ temp_df["到期时间"] = pd.to_datetime(
82
+ temp_df["到期时间"], format="%Y-%m-%d", errors="coerce"
83
+ ).dt.date
76
84
  temp_df["每股获配额"] = pd.to_numeric(temp_df["每股获配额"], errors="coerce")
77
85
  temp_df["计划发行量"] = pd.to_numeric(temp_df["计划发行量"], errors="coerce")
78
86
  temp_df["实际发行量"] = pd.to_numeric(temp_df["实际发行量"], errors="coerce")