akshare 1.14.49__py3-none-any.whl → 1.17.99__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.
Files changed (343) hide show
  1. akshare/__init__.py +595 -129
  2. akshare/air/air_hebei.py +77 -54
  3. akshare/air/air_zhenqi.py +0 -4
  4. akshare/air/cons.py +1 -0
  5. akshare/air/crypto.js +1 -1
  6. akshare/air/outcrypto.js +1 -1
  7. akshare/article/cons.py +1 -0
  8. akshare/article/epu_index.py +4 -3
  9. akshare/article/ff_factor.py +19 -8
  10. akshare/article/fred_md.py +4 -1
  11. akshare/article/risk_rv.py +3 -8
  12. akshare/bank/bank_cbirc_2020.py +11 -11
  13. akshare/bank/cons.py +7 -6
  14. akshare/bond/bond_buy_back_em.py +228 -0
  15. akshare/bond/bond_cb_sina.py +1 -0
  16. akshare/bond/bond_cb_ths.py +17 -9
  17. akshare/bond/bond_cbond.py +19 -14
  18. akshare/bond/bond_china.py +38 -39
  19. akshare/bond/bond_china_money.py +1 -1
  20. akshare/bond/bond_convert.py +10 -9
  21. akshare/bond/bond_em.py +37 -17
  22. akshare/bond/bond_summary.py +38 -37
  23. akshare/bond/bond_zh_cov.py +31 -40
  24. akshare/bond/bond_zh_sina.py +4 -0
  25. akshare/bond/cons.py +14 -11
  26. akshare/cal/__init__.py +0 -0
  27. akshare/cal/rv.py +170 -0
  28. akshare/cost/cost_living.py +7 -5
  29. akshare/crypto/__init__.py +1 -1
  30. akshare/crypto/crypto_bitcoin_cme.py +9 -7
  31. akshare/crypto/crypto_hold.py +4 -2
  32. akshare/currency/currency.py +1 -0
  33. akshare/currency/currency_china_bank_sina.py +11 -6
  34. akshare/data/__init__.py +1 -1
  35. akshare/data/cninfo.js +1 -1
  36. akshare/datasets.py +10 -21
  37. akshare/economic/cons.py +10 -3
  38. akshare/economic/macro_australia.py +74 -69
  39. akshare/economic/macro_bank.py +95 -653
  40. akshare/economic/macro_canada.py +92 -81
  41. akshare/economic/macro_china.py +97 -105
  42. akshare/economic/macro_china_hk.py +0 -1
  43. akshare/economic/macro_euro.py +103 -56
  44. akshare/economic/macro_finance_ths.py +7 -5
  45. akshare/economic/macro_germany.py +1 -1
  46. akshare/economic/macro_japan.py +0 -1
  47. akshare/economic/macro_other.py +1 -6
  48. akshare/economic/macro_swiss.py +2 -3
  49. akshare/economic/macro_uk.py +1 -1
  50. akshare/economic/macro_usa.py +7 -9
  51. akshare/economic/marco_cnbs.py +11 -6
  52. akshare/energy/energy_carbon.py +0 -1
  53. akshare/energy/energy_oil_em.py +1 -2
  54. akshare/event/cons.py +1 -0
  55. akshare/exceptions.py +43 -0
  56. akshare/file_fold/calendar.json +245 -2
  57. akshare/forex/__init__.py +0 -0
  58. akshare/forex/cons.py +192 -0
  59. akshare/forex/forex_em.py +149 -0
  60. akshare/fortune/fortune_500.py +1 -37
  61. akshare/fortune/fortune_bloomberg.py +6 -3
  62. akshare/fortune/fortune_forbes_500.py +3 -6
  63. akshare/fortune/fortune_hurun.py +2 -1
  64. akshare/fortune/fortune_xincaifu_500.py +17 -14
  65. akshare/fund/fund_announcement_em.py +145 -0
  66. akshare/fund/fund_aum_em.py +49 -35
  67. akshare/fund/fund_em.py +251 -220
  68. akshare/fund/fund_etf_em.py +44 -35
  69. akshare/fund/fund_etf_sina.py +75 -27
  70. akshare/fund/fund_etf_ths.py +2 -0
  71. akshare/fund/fund_fee_em.py +172 -0
  72. akshare/fund/fund_fhsp_em.py +42 -32
  73. akshare/fund/fund_init_em.py +8 -5
  74. akshare/fund/fund_lof_em.py +12 -19
  75. akshare/fund/fund_manager.py +25 -11
  76. akshare/fund/fund_overview_em.py +42 -0
  77. akshare/fund/fund_portfolio_em.py +23 -21
  78. akshare/fund/fund_position_lg.py +19 -8
  79. akshare/fund/fund_rank_em.py +2 -5
  80. akshare/fund/fund_rating.py +33 -12
  81. akshare/fund/fund_scale_em.py +24 -13
  82. akshare/fund/fund_scale_sina.py +20 -10
  83. akshare/fund/fund_xq.py +3 -2
  84. akshare/futures/cons.py +135 -39
  85. akshare/futures/cot.py +55 -56
  86. akshare/futures/futures_basis.py +49 -11
  87. akshare/futures/futures_comex_em.py +1 -0
  88. akshare/futures/futures_comm_ctp.py +1 -1
  89. akshare/futures/futures_contract_detail.py +59 -9
  90. akshare/futures/futures_daily_bar.py +66 -59
  91. akshare/futures/futures_foreign.py +14 -8
  92. akshare/futures/futures_hf_em.py +215 -61
  93. akshare/futures/futures_hist_em.py +191 -0
  94. akshare/futures/futures_hq_sina.py +5 -3
  95. akshare/futures/futures_index_ccidx.py +24 -82
  96. akshare/futures/futures_inventory_99.py +70 -272
  97. akshare/futures/futures_inventory_em.py +14 -11
  98. akshare/futures/futures_news_shmet.py +2 -2
  99. akshare/futures/futures_roll_yield.py +11 -24
  100. akshare/futures/futures_rule.py +7 -3
  101. akshare/futures/futures_rule_em.py +38 -0
  102. akshare/futures/futures_settlement_price_sgx.py +21 -6
  103. akshare/futures/futures_stock_js.py +0 -1
  104. akshare/futures/futures_to_spot.py +5 -6
  105. akshare/futures/futures_warehouse_receipt.py +48 -47
  106. akshare/futures/futures_zh_sina.py +3 -3
  107. akshare/futures/receipt.py +298 -165
  108. akshare/futures/requests_fun.py +16 -3
  109. akshare/futures/symbol_var.py +32 -13
  110. akshare/futures_derivative/cons.py +100 -103
  111. akshare/futures_derivative/futures_contract_info_cffex.py +55 -39
  112. akshare/futures_derivative/futures_contract_info_czce.py +2 -0
  113. akshare/futures_derivative/futures_contract_info_dce.py +43 -17
  114. akshare/futures_derivative/futures_contract_info_gfex.py +43 -31
  115. akshare/futures_derivative/futures_contract_info_ine.py +43 -34
  116. akshare/futures_derivative/futures_contract_info_shfe.py +3 -4
  117. akshare/futures_derivative/futures_cot_sina.py +8 -6
  118. akshare/futures_derivative/futures_index_sina.py +25 -13
  119. akshare/fx/cons.py +12 -7
  120. akshare/fx/fx_c_swap_cm.py +62 -0
  121. akshare/fx/fx_quote.py +3 -2
  122. akshare/fx/fx_quote_baidu.py +2 -1
  123. akshare/hf/__init__.py +1 -1
  124. akshare/hf/hf_sp500.py +8 -7
  125. akshare/index/cons.py +132 -28
  126. akshare/index/index_cni.py +7 -7
  127. akshare/index/index_cons.py +2 -2
  128. akshare/index/index_csindex.py +68 -0
  129. akshare/index/index_cx.py +20 -20
  130. akshare/index/index_drewry.py +17 -16
  131. akshare/index/index_eri.py +1 -0
  132. akshare/index/index_global_em.py +167 -0
  133. akshare/index/index_global_sina.py +82 -0
  134. akshare/index/index_kq_fz.py +17 -14
  135. akshare/index/index_kq_ss.py +1 -0
  136. akshare/index/index_option_qvix.py +351 -16
  137. akshare/index/index_research_sw.py +21 -21
  138. akshare/index/index_spot.py +9 -5
  139. akshare/index/index_stock_hk.py +5 -9
  140. akshare/index/index_stock_zh.py +111 -24
  141. akshare/index/index_stock_zh_csindex.py +3 -367
  142. akshare/index/index_sugar.py +18 -4
  143. akshare/index/index_sw.py +10 -2
  144. akshare/index/index_yw.py +53 -75
  145. akshare/index/index_zh_em.py +15 -82
  146. akshare/interest_rate/interbank_rate_em.py +0 -1
  147. akshare/movie/jm.js +0 -1
  148. akshare/news/__init__.py +1 -1
  149. akshare/news/news_baidu.py +395 -222
  150. akshare/news/news_stock.py +49 -16
  151. akshare/option/cons.py +2 -2
  152. akshare/option/option_commodity.py +341 -220
  153. akshare/option/option_commodity_sina.py +22 -26
  154. akshare/option/option_contract_info_ctp.py +63 -0
  155. akshare/option/option_current_sse.py +61 -0
  156. akshare/option/option_current_szse.py +84 -0
  157. akshare/option/option_czce.py +37 -9
  158. akshare/option/option_daily_stats_sse_szse.py +0 -1
  159. akshare/option/option_em.py +4 -8
  160. akshare/option/option_finance.py +60 -12
  161. akshare/option/option_finance_sina.py +7 -7
  162. akshare/option/option_lhb_em.py +0 -1
  163. akshare/option/option_margin.py +62 -0
  164. akshare/option/option_premium_analysis_em.py +58 -53
  165. akshare/option/option_risk_analysis_em.py +11 -8
  166. akshare/option/option_risk_indicator_sse.py +3 -4
  167. akshare/option/option_value_analysis_em.py +62 -55
  168. akshare/other/__init__.py +1 -1
  169. akshare/pro/__init__.py +0 -1
  170. akshare/pro/client.py +6 -4
  171. akshare/pro/cons.py +3 -2
  172. akshare/pro/data_pro.py +6 -5
  173. akshare/qdii/__init__.py +0 -0
  174. akshare/qdii/qdii_jsl.py +233 -0
  175. akshare/qhkc/__init__.py +1 -6
  176. akshare/qhkc/qhkc_api.py +64 -22
  177. akshare/qhkc_web/__init__.py +1 -6
  178. akshare/qhkc_web/qhkc_fund.py +10 -6
  179. akshare/qhkc_web/qhkc_index.py +28 -14
  180. akshare/qhkc_web/qhkc_tool.py +62 -59
  181. akshare/rate/__init__.py +1 -1
  182. akshare/rate/repo_rate.py +36 -32
  183. akshare/reits/__init__.py +1 -1
  184. akshare/reits/reits_basic.py +149 -13
  185. akshare/request.py +117 -0
  186. akshare/spot/__init__.py +1 -1
  187. akshare/spot/spot_hog_soozhu.py +165 -3
  188. akshare/spot/spot_sge.py +70 -9
  189. akshare/stock/cons.py +60 -23
  190. akshare/stock/stock_allotment_cninfo.py +8 -8
  191. akshare/stock/stock_ask_bid_em.py +3 -78
  192. akshare/stock/stock_board_concept_em.py +160 -35
  193. akshare/stock/stock_board_industry_em.py +163 -70
  194. akshare/stock/stock_dividend_cninfo.py +31 -17
  195. akshare/stock/stock_dzjy_em.py +347 -260
  196. akshare/stock/stock_fund_em.py +72 -64
  197. akshare/stock/stock_fund_hold.py +1 -2
  198. akshare/stock/stock_gsrl_em.py +1 -0
  199. akshare/stock/stock_hk_comparison_em.py +175 -0
  200. akshare/stock/stock_hk_famous.py +4 -5
  201. akshare/stock/stock_hk_fhpx_ths.py +2 -1
  202. akshare/stock/stock_hk_hot_rank_em.py +1 -0
  203. akshare/stock/stock_hk_sina.py +84 -36
  204. akshare/stock/stock_hold_control_cninfo.py +82 -0
  205. akshare/stock/stock_hold_control_em.py +0 -2
  206. akshare/stock/stock_hot_rank_em.py +4 -1
  207. akshare/stock/stock_hot_search_baidu.py +32 -19
  208. akshare/stock/stock_hot_up_em.py +4 -1
  209. akshare/stock/stock_hsgt_em.py +155 -0
  210. akshare/stock/stock_industry.py +1 -0
  211. akshare/stock/stock_industry_cninfo.py +1 -2
  212. akshare/stock/stock_info.py +6 -4
  213. akshare/stock/stock_info_em.py +17 -11
  214. akshare/stock/stock_intraday_em.py +4 -78
  215. akshare/stock/stock_intraday_sina.py +2 -2
  216. akshare/stock/stock_news_cx.py +39 -0
  217. akshare/stock/stock_profile_cninfo.py +7 -7
  218. akshare/stock/stock_profile_em.py +302 -0
  219. akshare/stock/stock_rank_forecast.py +6 -5
  220. akshare/stock/stock_repurchase_em.py +7 -2
  221. akshare/stock/stock_share_changes_cninfo.py +7 -5
  222. akshare/stock/stock_share_hold.py +24 -20
  223. akshare/stock/stock_stop.py +6 -6
  224. akshare/stock/stock_summary.py +153 -417
  225. akshare/stock/stock_us_famous.py +5 -6
  226. akshare/stock/stock_us_js.py +3 -2
  227. akshare/stock/stock_us_pink.py +38 -27
  228. akshare/stock/stock_us_sina.py +7 -3
  229. akshare/stock/stock_weibo_nlp.py +18 -20
  230. akshare/stock/stock_xq.py +24 -22
  231. akshare/stock/stock_zh_a_sina.py +8 -5
  232. akshare/stock/stock_zh_a_special.py +240 -243
  233. akshare/stock/stock_zh_a_tick_tx.py +11 -3
  234. akshare/stock/stock_zh_ah_tx.py +23 -26
  235. akshare/stock/stock_zh_b_sina.py +2 -2
  236. akshare/stock/stock_zh_comparison_em.py +250 -0
  237. akshare/stock/stock_zh_kcb_sina.py +67 -64
  238. akshare/stock_a/__init__.py +0 -0
  239. akshare/stock_a/stock_board_concept_name_em.py +170 -0
  240. akshare/stock_a/stock_individual_fund_flow_rank.py +258 -0
  241. akshare/stock_a/stock_zh_a_spot.py +212 -0
  242. akshare/stock_feature/cons.py +1 -0
  243. akshare/stock_feature/stock_a_indicator.py +9 -54
  244. akshare/stock_feature/stock_a_pe_and_pb.py +23 -5
  245. akshare/stock_feature/stock_account_em.py +0 -1
  246. akshare/stock_feature/stock_all_pb.py +2 -1
  247. akshare/stock_feature/stock_analyst_em.py +36 -30
  248. akshare/stock_feature/stock_board_concept_ths.py +328 -0
  249. akshare/stock_feature/stock_board_industry_ths.py +57 -2
  250. akshare/stock_feature/stock_buffett_index_lg.py +10 -8
  251. akshare/stock_feature/stock_classify_sina.py +3 -6
  252. akshare/stock_feature/stock_comment_em.py +81 -144
  253. akshare/stock_feature/stock_congestion_lg.py +2 -1
  254. akshare/stock_feature/stock_cyq_em.py +5 -11
  255. akshare/stock_feature/stock_disclosure_cninfo.py +6 -6
  256. akshare/stock_feature/stock_dxsyl_em.py +121 -74
  257. akshare/stock_feature/stock_ebs_lg.py +5 -4
  258. akshare/stock_feature/stock_esg_sina.py +29 -7
  259. akshare/stock_feature/stock_fhps_em.py +2 -1
  260. akshare/stock_feature/stock_fhps_ths.py +15 -7
  261. akshare/stock_feature/stock_fund_flow.py +30 -22
  262. akshare/stock_feature/stock_gddh_em.py +19 -11
  263. akshare/stock_feature/stock_gdfx_em.py +226 -113
  264. akshare/stock_feature/stock_gdhs.py +75 -50
  265. akshare/stock_feature/stock_gdzjc_em.py +21 -10
  266. akshare/stock_feature/stock_gpzy_em.py +78 -46
  267. akshare/stock_feature/stock_gxl_lg.py +3 -2
  268. akshare/stock_feature/stock_hist_em.py +137 -234
  269. akshare/stock_feature/stock_hist_tx.py +13 -10
  270. akshare/stock_feature/stock_hk_valuation_baidu.py +20 -8
  271. akshare/stock_feature/stock_hot_xq.py +4 -6
  272. akshare/stock_feature/stock_hsgt_em.py +269 -97
  273. akshare/stock_feature/stock_hsgt_exchange_rate.py +115 -87
  274. akshare/stock_feature/stock_hsgt_min_em.py +13 -16
  275. akshare/stock_feature/stock_info.py +7 -80
  276. akshare/stock_feature/stock_inner_trade_xq.py +38 -31
  277. akshare/stock_feature/stock_jgdy_em.py +43 -40
  278. akshare/stock_feature/stock_lhb_em.py +119 -3
  279. akshare/stock_feature/stock_margin_em.py +0 -1
  280. akshare/stock_feature/stock_margin_sse.py +0 -2
  281. akshare/stock_feature/stock_pankou_em.py +71 -35
  282. akshare/stock_feature/stock_qsjy_em.py +13 -4
  283. akshare/stock_feature/stock_report_em.py +151 -7
  284. akshare/stock_feature/stock_research_report_em.py +55 -20
  285. akshare/stock_feature/stock_sy_em.py +20 -15
  286. akshare/stock_feature/stock_technology_ths.py +122 -77
  287. akshare/stock_feature/stock_tfp_em.py +2 -1
  288. akshare/stock_feature/stock_three_report_em.py +21 -5
  289. akshare/stock_feature/stock_ttm_lyr.py +18 -9
  290. akshare/stock_feature/stock_value_em.py +83 -0
  291. akshare/stock_feature/stock_yjbb_em.py +58 -32
  292. akshare/stock_feature/stock_yjyg_cninfo.py +6 -2
  293. akshare/stock_feature/stock_yjyg_em.py +1 -1
  294. akshare/stock_feature/stock_yzxdr_em.py +24 -22
  295. akshare/stock_feature/stock_zdhtmx_em.py +20 -6
  296. akshare/stock_feature/stock_zh_vote_baidu.py +4 -1
  297. akshare/stock_feature/stock_ztb_em.py +39 -24
  298. akshare/stock_fundamental/__init__.py +1 -1
  299. akshare/stock_fundamental/stock_basic_info_xq.py +119 -0
  300. akshare/stock_fundamental/{stock_finance_hk.py → stock_finance_hk_em.py} +23 -16
  301. akshare/stock_fundamental/{stock_finance.py → stock_finance_sina.py} +60 -7
  302. akshare/stock_fundamental/stock_finance_ths.py +524 -57
  303. akshare/stock_fundamental/stock_finance_us_em.py +268 -0
  304. akshare/stock_fundamental/stock_gbjg_em.py +80 -0
  305. akshare/stock_fundamental/stock_hold.py +26 -17
  306. akshare/stock_fundamental/stock_ipo_declare.py +1 -0
  307. akshare/stock_fundamental/stock_kcb_detail_sse.py +10 -10
  308. akshare/stock_fundamental/stock_kcb_sse.py +26 -25
  309. akshare/stock_fundamental/stock_notice.py +12 -3
  310. akshare/stock_fundamental/stock_profit_forecast_em.py +31 -13
  311. akshare/stock_fundamental/stock_profit_forecast_hk_etnet.py +64 -41
  312. akshare/stock_fundamental/stock_profit_forecast_ths.py +86 -35
  313. akshare/stock_fundamental/stock_recommend.py +20 -4
  314. akshare/stock_fundamental/stock_zygc.py +5 -62
  315. akshare/utils/context.py +43 -0
  316. akshare/utils/demjson.py +2009 -1338
  317. akshare/utils/func.py +49 -2
  318. akshare/utils/multi_decrypt.py +53 -0
  319. akshare/utils/token_process.py +6 -5
  320. {akshare-1.14.49.dist-info → akshare-1.17.99.dist-info}/METADATA +54 -80
  321. akshare-1.17.99.dist-info/RECORD +409 -0
  322. {akshare-1.14.49.dist-info → akshare-1.17.99.dist-info}/WHEEL +1 -1
  323. {akshare-1.14.49.dist-info → akshare-1.17.99.dist-info/licenses}/LICENSE +1 -1
  324. tests/test_func.py +3 -5
  325. akshare/bond/bond_futures.py +0 -50
  326. akshare/bond/bond_investing.py +0 -139
  327. akshare/crypto/crypto_hist_investing.py +0 -249
  328. akshare/fund/fund_announcement.py +0 -56
  329. akshare/futures/futures_international.py +0 -170
  330. akshare/futures/futures_news_baidu.py +0 -54
  331. akshare/futures/inventory_data.py +0 -100
  332. akshare/futures_derivative/futures_index_price_nh.py +0 -61
  333. akshare/futures_derivative/futures_index_return_nh.py +0 -47
  334. akshare/futures_derivative/futures_index_volatility_nh.py +0 -53
  335. akshare/futures_derivative/futures_other_index_nh.py +0 -145
  336. akshare/index/index_fear_greed_funddb.py +0 -78
  337. akshare/index/index_investing.py +0 -232
  338. akshare/sport/__init__.py +0 -6
  339. akshare/sport/sport_olympic.py +0 -27
  340. akshare/stock_feature/stock_wencai.py +0 -104
  341. akshare/stock_fundamental/stock_mda_ym.py +0 -40
  342. akshare-1.14.49.dist-info/RECORD +0 -387
  343. {akshare-1.14.49.dist-info → akshare-1.17.99.dist-info}/top_level.txt +0 -0
akshare/air/air_hebei.py CHANGED
@@ -15,70 +15,93 @@ https://110.249.223.67/publish
15
15
  发布单位:河北省环境应急与重污染天气预警中心 技术支持:中国科学院大气物理研究所 中科三清科技有限公司
16
16
  """
17
17
 
18
- from datetime import datetime
19
-
20
18
  import pandas as pd
21
19
  import requests
22
- from tqdm import tqdm
20
+ from bs4 import BeautifulSoup
23
21
 
24
22
 
25
- def air_quality_hebei(symbol: str = "唐山市") -> pd.DataFrame:
23
+ def air_quality_hebei() -> pd.DataFrame:
26
24
  """
27
25
  河北省空气质量预报信息发布系统-空气质量预报, 未来 6 天
28
- https://110.249.223.67/publish/
29
- :param symbol: choice of {'石家庄市', '唐山市', '秦皇岛市', '邯郸市', '邢台市', '保定市', '张家口市', '承德市', '沧州市', '廊坊市', '衡水市', '辛集市', '定州市'}
30
- :type symbol: str
26
+ http://218.11.10.130:8080/#/application/home
31
27
  :return: city = "", 返回所有地区的数据; city="唐山市", 返回唐山市的数据
32
28
  :rtype: pandas.DataFrame
33
29
  """
34
- url = (
35
- "http://110.249.223.67/server/api/CityPublishInfo/GetProvinceAndCityPublishData"
36
- )
37
- params = {"publishDate": f"{datetime.today().strftime('%Y-%m-%d')} 16:00:00"}
38
- r = requests.get(url, params=params)
39
- json_data = r.json()
40
- city_list = pd.DataFrame.from_dict(json_data["cityPublishDatas"], orient="columns")[
41
- "CityName"
42
- ].tolist()
43
- outer_df = pd.DataFrame()
44
- for i in tqdm(range(1, 7), leave=False):
45
- inner_df = pd.DataFrame(
46
- [item[f"Date{i}"] for item in json_data["cityPublishDatas"]],
47
- index=city_list,
48
- )
49
- outer_df = pd.concat([outer_df, inner_df])
50
- if symbol == "":
51
- temp_df = outer_df.reset_index()
52
- temp_df.columns = [
53
- "city",
54
- "date",
55
- "pollutant",
56
- "minAQI",
57
- "maxAQI",
58
- "level",
59
- ]
60
- temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
61
- temp_df["minaqi"] = pd.to_numeric(temp_df["minaqi"])
62
- temp_df["maxaqi"] = pd.to_numeric(temp_df["maxaqi"])
63
- return temp_df
64
- else:
65
- temp_df = outer_df.reset_index()
66
- temp_df.columns = [
67
- "city",
68
- "date",
69
- "pollutant",
70
- "minaqi",
71
- "maxaqi",
72
- "level",
73
- ]
74
- temp_df["date"] = pd.to_datetime(temp_df["date"]).dt.date
75
- temp_df["minaqi"] = pd.to_numeric(temp_df["minaqi"])
76
- temp_df["maxaqi"] = pd.to_numeric(temp_df["maxaqi"])
77
- temp_df = temp_df[temp_df["city"] == symbol]
78
- temp_df.reset_index(inplace=True, drop=True)
79
- 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
80
103
 
81
104
 
82
105
  if __name__ == "__main__":
83
- air_quality_hebei_df = air_quality_hebei(symbol="定州市")
106
+ air_quality_hebei_df = air_quality_hebei()
84
107
  print(air_quality_hebei_df)
akshare/air/air_zhenqi.py CHANGED
@@ -119,11 +119,7 @@ def air_quality_watch_point(
119
119
  ctx = MiniRacer()
120
120
  ctx.eval(file_data)
121
121
  method = "GETCITYPOINTAVG"
122
- ctx.call("encode_param", method)
123
- ctx.call("encode_param", start_date)
124
- ctx.call("encode_param", end_date)
125
122
  city_param = ctx.call("encode_param", city)
126
- ctx.call("encode_secret", method, city_param, start_date, end_date)
127
123
  payload = {
128
124
  "appId": "a01901d3caba1f362d69474674ce477f",
129
125
  "method": ctx.call("encode_param", method),
akshare/air/cons.py CHANGED
@@ -4,6 +4,7 @@
4
4
  Date: 2019/11/25 20:45
5
5
  Desc: 空气质量接口配置文件
6
6
  """
7
+
7
8
  city_chinese_list = [
8
9
  "北京",
9
10
  "重庆",
akshare/air/crypto.js CHANGED
@@ -136,4 +136,4 @@ function decode_result(a) {
136
136
  var hexcase = 0,
137
137
  b64pad = "",
138
138
  chrsz = 8,
139
- appId = "a01901d3caba1f362d69474674ce477f";
139
+ appId = "a01901d3caba1f362d69474674ce477f";
akshare/air/outcrypto.js CHANGED
@@ -4897,4 +4897,4 @@ CryptoJS.mode.ECB = function() {
4897
4897
  blockSize: 2
4898
4898
  });
4899
4899
  h.TripleDES = e._6(g)
4900
- })();
4900
+ })();
akshare/article/cons.py CHANGED
@@ -4,6 +4,7 @@
4
4
  Date: 2019/11/14 20:32
5
5
  Desc: 学术板块配置文件
6
6
  """
7
+
7
8
  # EPU
8
9
  epu_home_url = "http://www.policyuncertainty.com/index.html"
9
10
 
@@ -5,6 +5,7 @@ Date: 2024/1/20 22:00
5
5
  Desc: 经济政策不确定性指数
6
6
  https://www.policyuncertainty.com/index.html
7
7
  """
8
+
8
9
  import pandas as pd
9
10
 
10
11
 
@@ -28,7 +29,7 @@ def article_epu_index(symbol: str = "China") -> pd.DataFrame:
28
29
  symbol = "HK"
29
30
  epu_df = pd.read_excel(
30
31
  io=f"http://www.policyuncertainty.com/media/{symbol}_EPU_Data_Annotated.xlsx",
31
- engine="openpyxl"
32
+ engine="openpyxl",
32
33
  )
33
34
  return epu_df
34
35
  if symbol in ["Germany", "France", "Italy"]: # 欧洲
@@ -40,13 +41,13 @@ def article_epu_index(symbol: str = "China") -> pd.DataFrame:
40
41
  if symbol in ["Ireland", "Chile", "Colombia", "Netherlands", "Singapore", "Sweden"]:
41
42
  epu_df = pd.read_excel(
42
43
  io=f"http://www.policyuncertainty.com/media/{symbol}_Policy_Uncertainty_Data.xlsx",
43
- engine="openpyxl"
44
+ engine="openpyxl",
44
45
  )
45
46
  return epu_df
46
47
  if symbol == "Greece":
47
48
  epu_df = pd.read_excel(
48
49
  io=f"http://www.policyuncertainty.com/media/FKT_{symbol}_Policy_Uncertainty_Data.xlsx",
49
- engine="openpyxl"
50
+ engine="openpyxl",
50
51
  )
51
52
  return epu_df
52
53
  url = f"http://www.policyuncertainty.com/media/{symbol}_Policy_Uncertainty_Data.csv"
@@ -5,6 +5,7 @@ Date: 2024/1/20 22:30
5
5
  Desc: FF-data-library
6
6
  https://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html
7
7
  """
8
+
8
9
  from io import StringIO
9
10
 
10
11
  import pandas as pd
@@ -23,26 +24,31 @@ def article_ff_crr() -> pd.DataFrame:
23
24
  res = requests.get(ff_home_url)
24
25
  # first table
25
26
  list_index = (
26
- pd.read_html(StringIO(res.text), header=0, index_col=0)[4].iloc[2, :].index.tolist()
27
+ pd.read_html(StringIO(res.text), header=0, index_col=0)[4]
28
+ .iloc[2, :]
29
+ .index.tolist()
27
30
  )
28
31
  list_0 = [
29
32
  item
30
33
  for item in pd.read_html(StringIO(res.text), header=0, index_col=0)[4]
31
- .iloc[0, :].iloc[0]
34
+ .iloc[0, :]
35
+ .iloc[0]
32
36
  .split(" ")
33
37
  if item != ""
34
38
  ]
35
39
  list_1 = [
36
40
  item
37
41
  for item in pd.read_html(StringIO(res.text), header=0, index_col=0)[4]
38
- .iloc[0, :].iloc[1]
42
+ .iloc[0, :]
43
+ .iloc[1]
39
44
  .split(" ")
40
45
  if item != ""
41
46
  ]
42
47
  list_2 = [
43
48
  item
44
49
  for item in pd.read_html(StringIO(res.text), header=0, index_col=0)[4]
45
- .iloc[0, :].iloc[2]
50
+ .iloc[0, :]
51
+ .iloc[2]
46
52
  .split(" ")
47
53
  if item != ""
48
54
  ]
@@ -63,26 +69,31 @@ def article_ff_crr() -> pd.DataFrame:
63
69
 
64
70
  # second table
65
71
  list_index = (
66
- pd.read_html(StringIO(res.text), header=0, index_col=0)[4].iloc[1, :].index.tolist()
72
+ pd.read_html(StringIO(res.text), header=0, index_col=0)[4]
73
+ .iloc[1, :]
74
+ .index.tolist()
67
75
  )
68
76
  list_0 = [
69
77
  item
70
78
  for item in pd.read_html(StringIO(res.text), header=0, index_col=0)[4]
71
- .iloc[1, :].iloc[0]
79
+ .iloc[1, :]
80
+ .iloc[0]
72
81
  .split(" ")
73
82
  if item != ""
74
83
  ]
75
84
  list_1 = [
76
85
  item
77
86
  for item in pd.read_html(StringIO(res.text), header=0, index_col=0)[4]
78
- .iloc[1, :].iloc[1]
87
+ .iloc[1, :]
88
+ .iloc[1]
79
89
  .split(" ")
80
90
  if item != ""
81
91
  ]
82
92
  list_2 = [
83
93
  item
84
94
  for item in pd.read_html(StringIO(res.text), header=0, index_col=0)[4]
85
- .iloc[1, :].iloc[2]
95
+ .iloc[1, :]
96
+ .iloc[2]
86
97
  .split(" ")
87
98
  if item != ""
88
99
  ]
@@ -6,6 +6,7 @@ Desc: Economic Research from Federal Reserve Bank of St. Louis
6
6
  https://research.stlouisfed.org/econ/mccracken/fred-databases/
7
7
  FRED-MD and FRED-QD are large macroeconomic databases designed for the empirical analysis of “big data.” The datasets of monthly and quarterly observations mimic the coverage of datasets already used in the literature, but they add three appealing features. They are updated in real-time through the FRED database. They are publicly accessible, facilitating the replication of empirical work. And they relieve the researcher of the task of incorporating data changes and revisions (a task accomplished by the data desk at the Federal Reserve Bank of St. Louis).
8
8
  """
9
+
9
10
  import pandas as pd
10
11
 
11
12
 
@@ -17,7 +18,9 @@ def fred_md(date: str = "2020-01") -> pd.DataFrame:
17
18
  :return: Monthly Data
18
19
  :rtype: pandas.DataFrame
19
20
  """
20
- url = f"https://s3.amazonaws.com/files.fred.stlouisfed.org/fred-md/monthly/{date}.csv"
21
+ url = (
22
+ f"https://s3.amazonaws.com/files.fred.stlouisfed.org/fred-md/monthly/{date}.csv"
23
+ )
21
24
  temp_df = pd.read_csv(url)
22
25
  return temp_df
23
26
 
@@ -4,6 +4,7 @@
4
4
  Date: 2024/1/20 20:51
5
5
  Desc: 修大成主页-Risk Lab-Realized Volatility; Oxford-Man Institute of Quantitative Finance Realized Library
6
6
  """
7
+
7
8
  import json
8
9
 
9
10
  import pandas as pd
@@ -64,11 +65,8 @@ def article_oman_rv(symbol: str = "FTSE", index: str = "rk_th2") -> pd.DataFrame
64
65
  res = requests.get(url)
65
66
  soup = BeautifulSoup(res.text, "lxml")
66
67
  soup_text = soup.find("p").get_text()
67
- data_json = json.loads(soup_text[soup_text.find("{"): soup_text.rfind("};") + 1])
68
+ data_json = json.loads(soup_text[soup_text.find("{") : soup_text.rfind("};") + 1])
68
69
  date_list = data_json[f".{symbol}"]["dates"]
69
- title_fore = data_json[f".{symbol}"][index]["name"]
70
- title_last = data_json[f".{symbol}"][index]["measure"]
71
- title_list = title_fore + "-" + title_last
72
70
  temp_df = pd.DataFrame([date_list, data_json[f".{symbol}"][index]["data"]]).T
73
71
  temp_df.index = pd.to_datetime(temp_df.iloc[:, 0], unit="ms")
74
72
  temp_df = temp_df.iloc[:, 1]
@@ -107,10 +105,7 @@ def article_oman_rv_short(symbol: str = "FTSE") -> pd.DataFrame:
107
105
  res = requests.get(url, headers=headers, verify=False)
108
106
  soup = BeautifulSoup(res.text, "lxml")
109
107
  soup_text = soup.find("p").get_text()
110
- data_json = json.loads(soup_text[soup_text.find("{"): soup_text.rfind("}") + 1])
111
- title_fore = data_json[f".{symbol}"]["name"]
112
- title_last = data_json[f".{symbol}"]["measure"]
113
- title_list = title_fore + "-" + title_last
108
+ data_json = json.loads(soup_text[soup_text.find("{") : soup_text.rfind("}") + 1])
114
109
  temp_df = pd.DataFrame(data_json[f".{symbol}"]["data"])
115
110
  temp_df.index = pd.to_datetime(temp_df.iloc[:, 0], unit="ms")
116
111
  temp_df = temp_df.iloc[:, 1]
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding:utf-8 -*-
3
3
  """
4
- Date: 2024/2/18 12:00
4
+ Date: 2025/2/4 23:00
5
5
  Desc: 中国银行保险监督管理委员会-首页-政务信息-行政处罚-银保监分局本级-XXXX行政处罚信息公开表
6
- https://www.cbirc.gov.cn/cn/view/pages/ItemList.html?itemPId=923&itemId=4115&itemUrl=ItemListRightList.html&itemName=%E9%93%B6%E4%BF%9D%E7%9B%91%E5%88%86%E5%B1%80%E6%9C%AC%E7%BA%A7&itemsubPId=931&itemsubPName=%E8%A1%8C%E6%94%BF%E5%A4%84%E7%BD%9A#2
6
+ https://www.nfra.gov.cn/cn/view/pages/ItemList.html?itemPId=923&itemId=4115&itemUrl=ItemListRightList.html&itemName=%E9%93%B6%E4%BF%9D%E7%9B%91%E5%88%86%E5%B1%80%E6%9C%AC%E7%BA%A7&itemsubPId=931&itemsubPName=%E8%A1%8C%E6%94%BF%E5%A4%84%E7%BD%9A#2
7
7
  提取 具体页面 html 页面的 json 接口
8
- https://www.cbirc.gov.cn/cn/static/data/DocInfo/SelectByDocId/data_docId=881446.json
8
+ https://www.nfra.gov.cn/cn/static/data/DocInfo/SelectByDocId/data_docId=881446.json
9
9
  2020 新接口
10
10
  """
11
11
 
@@ -22,7 +22,7 @@ from akshare.bank.cons import cbirc_headers_without_cookie_2020
22
22
  def bank_fjcf_total_num(item: str = "分局本级") -> int:
23
23
  """
24
24
  首页-政务信息-行政处罚-银保监分局本级 总页数
25
- https://www.cbirc.gov.cn/cn/view/pages/ItemList.html?itemPId=923&itemId=4115&itemUrl=ItemListRightList.html&itemName=%E9%93%B6%E4%BF%9D%E7%9B%91%E5%88%86%E5%B1%80%E6%9C%AC%E7%BA%A7&itemsubPId=931
25
+ https://www.nfra.gov.cn/cn/view/pages/ItemList.html?itemPId=923&itemId=4115&itemUrl=ItemListRightList.html&itemName=%E9%93%B6%E4%BF%9D%E7%9B%91%E5%88%86%E5%B1%80%E6%9C%AC%E7%BA%A7&itemsubPId=931
26
26
  :param item: choice of {"机关", "本级", "分局本级"}
27
27
  :type item: str
28
28
  :return: 总页数
@@ -34,7 +34,7 @@ def bank_fjcf_total_num(item: str = "分局本级") -> int:
34
34
  "分局本级": "4115",
35
35
  }
36
36
  cbirc_headers = cbirc_headers_without_cookie_2020.copy()
37
- main_url = "https://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
37
+ main_url = "https://www.nfra.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
38
38
  params = {
39
39
  "itemId": item_id_list[item],
40
40
  "pageSize": "18",
@@ -47,7 +47,7 @@ def bank_fjcf_total_num(item: str = "分局本级") -> int:
47
47
  def bank_fjcf_total_page(item: str = "分局本级", begin: int = 1) -> int:
48
48
  """
49
49
  获取首页-政务信息-行政处罚-银保监分局本级的总页数
50
- https://www.cbirc.gov.cn/cn/view/pages/ItemList.html?itemPId=923&itemId=4115&itemUrl=ItemListRightList.html&itemName=%E9%93%B6%E4%BF%9D%E7%9B%91%E5%88%86%E5%B1%80%E6%9C%AC%E7%BA%A7&itemsubPId=931
50
+ https://www.nfra.gov.cn/cn/view/pages/ItemList.html?itemPId=923&itemId=4115&itemUrl=ItemListRightList.html&itemName=%E9%93%B6%E4%BF%9D%E7%9B%91%E5%88%86%E5%B1%80%E6%9C%AC%E7%BA%A7&itemsubPId=931
51
51
  :param item: choice of {"机关", "本级", "分局本级"}
52
52
  :type item: str
53
53
  :param begin: 开始页数
@@ -61,7 +61,7 @@ def bank_fjcf_total_page(item: str = "分局本级", begin: int = 1) -> int:
61
61
  "分局本级": "4115",
62
62
  }
63
63
  cbirc_headers = cbirc_headers_without_cookie_2020.copy()
64
- main_url = "https://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
64
+ main_url = "https://www.nfra.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
65
65
  params = {
66
66
  "itemId": item_id_list[item],
67
67
  "pageSize": "18",
@@ -93,7 +93,7 @@ def bank_fjcf_page_url(
93
93
  "分局本级": "4115",
94
94
  }
95
95
  cbirc_headers = cbirc_headers_without_cookie_2020.copy()
96
- main_url = "https://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
96
+ main_url = "https://www.nfra.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild"
97
97
  temp_df = pd.DataFrame()
98
98
  for i_page in tqdm(range(begin, page + begin), leave=False):
99
99
  params = {
@@ -125,7 +125,7 @@ def bank_fjcf_table_detail(
125
125
  id_list = bank_fjcf_page_url(page=page, item=item, begin=begin)["docId"]
126
126
  big_df = pd.DataFrame()
127
127
  for item in id_list:
128
- url = f"https://www.cbirc.gov.cn/cn/static/data/DocInfo/SelectByDocId/data_docId={item}.json"
128
+ url = f"https://www.nfra.gov.cn/cn/static/data/DocInfo/SelectByDocId/data_docId={item}.json"
129
129
  res = requests.get(url)
130
130
  try:
131
131
  table_list = pd.read_html(StringIO(res.json()["data"]["docClob"]))[0]
@@ -148,7 +148,7 @@ def bank_fjcf_table_detail(
148
148
  table_list.insert(2, pd.NA)
149
149
  else:
150
150
  print(
151
- f"{item} 异常,请通过 https://www.cbirc.gov.cn/cn/view/pages/ItemDetail.html?docId={item} 查看"
151
+ f"{item} 异常,请通过 https://www.nfra.gov.cn/cn/view/pages/ItemDetail.html?docId={item} 查看"
152
152
  )
153
153
  continue
154
154
 
@@ -170,7 +170,7 @@ def bank_fjcf_table_detail(
170
170
  big_df.columns = [
171
171
  "行政处罚决定书文号",
172
172
  "姓名",
173
- "单位", # 20200108新增
173
+ "单位", # 20200108 新增
174
174
  "单位名称",
175
175
  "主要负责人姓名",
176
176
  "主要违法违规事实(案由)",
akshare/bank/cons.py CHANGED
@@ -4,17 +4,18 @@
4
4
  Date: 2023/4/3 21:06
5
5
  Desc: 银保监会配置文件
6
6
  """
7
+
7
8
  cbirc_headers_without_cookie_2020 = {
8
9
  "Accept": "*/*",
9
10
  "Accept-Encoding": "gzip, deflate",
10
11
  "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
11
12
  "Cache-Control": "no-cache",
12
13
  "Connection": "keep-alive",
13
- "Host": "www.cbirc.gov.cn",
14
+ "Host": "www.nfra.gov.cn",
14
15
  "Pragma": "no-cache",
15
- "Referer": "http://www.cbirc.gov.cn/cn/view/pages/ItemList.html?itemPId=923&itemId=4115&itemUrl=ItemListRightList.html&itemName=%E9%93%B6%E4%BF%9D%E7%9B%91%E5%88%86%E5%B1%80%E6%9C%AC%E7%BA%A7&itemsubPId=931&itemsubPName=%E8%A1%8C%E6%94%BF%E5%A4%84%E7%BD%9A",
16
+ "Referer": "http://www.nfra.gov.cn/cn/view/pages/ItemList.html?itemPId=923&itemId=4115&itemUrl=ItemListRightList.html&itemName=%E9%93%B6%E4%BF%9D%E7%9B%91%E5%88%86%E5%B1%80%E6%9C%AC%E7%BA%A7&itemsubPId=931&itemsubPName=%E8%A1%8C%E6%94%BF%E5%A4%84%E7%BD%9A",
16
17
  "X-Requested-With": "XMLHttpRequest",
17
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36"
18
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36",
18
19
  }
19
20
 
20
21
  cbirc_headers_without_cookie_2019 = {
@@ -23,9 +24,9 @@ cbirc_headers_without_cookie_2019 = {
23
24
  "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
24
25
  "Cache-Control": "no-cache",
25
26
  "Connection": "keep-alive",
26
- "Host": "www.cbirc.gov.cn",
27
+ "Host": "www.nfra.gov.cn",
27
28
  "Pragma": "no-cache",
28
- "Referer": "http://www.cbirc.gov.cn/cn/list/9103/910305/ybjjcf/1.html",
29
+ "Referer": "http://www.nfra.gov.cn/cn/list/9103/910305/ybjjcf/1.html",
29
30
  "Upgrade-Insecure-Requests": "1",
30
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36"
31
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36",
31
32
  }