stock-tracker

This commit is contained in:
C菌
2026-07-04 00:17:11 +08:00
commit 6087341a48
6463 changed files with 1929869 additions and 0 deletions
@@ -0,0 +1,6 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2019/12/10 21:55
Desc:
"""
@@ -0,0 +1,95 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2024/8/4 17:22
Desc: 历年世界 500 强榜单数据
https://www.fortunechina.com/fortune500/index.htm
特殊情况说明:
2010年由于网页端没有公布公司所属的国家, 故 2010 年数据没有国家这列
"""
from functools import lru_cache
from io import StringIO
import pandas as pd
import requests
from bs4 import BeautifulSoup
from tqdm import tqdm
@lru_cache()
def _fortune_rank_year_url_map() -> dict:
"""
年份和网址映射
https://www.fortunechina.com/fortune500/index.htm
:return: 年份和网址映射
:rtype: dict
"""
url = "https://www.fortunechina.com/fortune500/index.htm"
r = requests.get(url)
soup = BeautifulSoup(r.text, features="lxml")
url_2023 = "https://www.fortunechina.com/fortune500/c/2023-08/02/content_436874.htm"
node_list = soup.find_all(name="div", attrs={"class": "swiper-slide"})
url_list = [item.find("a")["href"] for item in node_list]
year_list = [item.find("a").text for item in node_list]
year_url_map = dict(zip(year_list, url_list))
year_url_map["2023"] = url_2023
return year_url_map
def fortune_rank(year: str = "2015") -> pd.DataFrame:
"""
财富 500 强公司从 1996 年开始的排行榜
https://www.fortunechina.com/fortune500/index.htm
:param year: str 年份
:return: pandas.DataFrame
"""
year_url_map = _fortune_rank_year_url_map()
url = year_url_map[year]
r = requests.get(url)
r.encoding = "utf-8"
if int(year) < 2007:
df = pd.read_html(StringIO(r.text))[0].iloc[1:-1,]
df.columns = pd.read_html(StringIO(r.text))[0].iloc[0, :].tolist()
return df
elif 2006 < int(year) < 2010:
df = pd.read_html(StringIO(r.text))[0].iloc[1:,]
df.columns = pd.read_html(StringIO(r.text))[0].iloc[0, :].tolist()
for page in tqdm(range(2, 11), leave=False):
# page =2
r = requests.get(url.rsplit(".", maxsplit=1)[0] + "_" + str(page) + ".htm")
r.encoding = "utf-8"
temp_df = pd.read_html(StringIO(r.text))[0].iloc[1:,]
temp_df.columns = pd.read_html(StringIO(r.text))[0].iloc[0, :].tolist()
df = pd.concat(objs=[df, temp_df], ignore_index=True)
return df
else:
df = pd.read_html(StringIO(r.text))[0]
return df
if __name__ == "__main__":
fortune_rank_df = fortune_rank(year="2023") # 2010 不一样
print(fortune_rank_df)
fortune_rank_df = fortune_rank(year="2022") # 2010 不一样
print(fortune_rank_df)
fortune_rank_df = fortune_rank(year="2008") # 2010 不一样
print(fortune_rank_df)
fortune_rank_df = fortune_rank(year="2008") # 2010 不一样
print(fortune_rank_df)
fortune_rank_df = fortune_rank(year="2009") # 2010 不一样
print(fortune_rank_df)
for item in range(1996, 2008):
print(item)
fortune_rank_df = fortune_rank(year=str(item)) # 2010 不一样
print(fortune_rank_df)
for item in range(2010, 2023):
print(item)
fortune_rank_df = fortune_rank(year=str(item)) # 2010 不一样
print(fortune_rank_df)
@@ -0,0 +1,117 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2022/4/10 18:24
Desc: 彭博亿万富豪指数
https://www.bloomberg.com/billionaires/
"""
import pandas as pd
import requests
from bs4 import BeautifulSoup
def index_bloomberg_billionaires_hist(year: str = "2021") -> pd.DataFrame:
"""
Bloomberg Billionaires Index
https://stats.areppim.com/stats/links_billionairexlists.htm
:param year: choice of {"2021", "2019", "2018", ...}
:type year: str
:return: 彭博亿万富豪指数历史数据
:rtype: pandas.DataFrame
"""
url = f"https://stats.areppim.com/listes/list_billionairesx{year[-2:]}xwor.htm"
r = requests.get(url)
soup = BeautifulSoup(r.text, "lxml")
trs = soup.findAll("table")[0].findAll("tr")
heads = trs[1]
if "Rank" not in heads.text:
heads = trs[0]
dic_keys = []
dic = {}
for head in heads:
head = head.text
dic_keys.append(head)
for dic_key in dic_keys:
dic[dic_key] = []
for ll in trs:
item = ll.findAll("td")
for i in range(len(item)):
v = item[i].text
if i == 0 and not v.isdigit():
break
dic[dic_keys[i]].append(v)
temp_df = pd.DataFrame(dic)
temp_df = temp_df.rename(
{
"Rank": "rank",
"Name": "name",
"Age": "age",
"Citizenship": "country",
"Country": "country",
"Net Worth(bil US$)": "total_net_worth",
"Total net worth$Billion": "total_net_worth",
"$ Last change": "last_change",
"$ YTD change": "ytd_change",
"Industry": "industry",
},
axis=1,
)
return temp_df
def index_bloomberg_billionaires() -> pd.DataFrame:
"""
Bloomberg Billionaires Index
https://www.bloomberg.com/billionaires/
:return: 彭博亿万富豪指数
:rtype: pandas.DataFrame
"""
url = "https://www.bloomberg.com/billionaires"
headers = {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
"cache-control": "no-cache",
"pragma": "no-cache",
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "same-origin",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
"referer": "https://www.bloomberg.com/",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
}
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, "lxml")
big_content_list = list()
soup_node = soup.find(attrs={"class": "table-chart"}).find_all(
attrs={"class": "table-row"}
)
for row in soup_node:
temp_content_list = row.text.strip().replace("\n", "").split(" ")
content_list = [item for item in temp_content_list if item != ""]
big_content_list.append(content_list)
temp_df = pd.DataFrame(big_content_list)
temp_df.columns = [
"rank",
"name",
"total_net_worth",
"last_change",
"YTD_change",
"country",
"industry",
]
return temp_df
if __name__ == "__main__":
index_bloomberg_billionaires_df = index_bloomberg_billionaires()
print(index_bloomberg_billionaires_df)
index_bloomberg_billionaires_hist_df = index_bloomberg_billionaires_hist(
year="2021"
)
print(index_bloomberg_billionaires_hist_df)
@@ -0,0 +1,46 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2022/1/26 15:10
Desc: 福布斯中国-榜单
https://www.forbeschina.com/lists
"""
import pandas as pd
import requests
from bs4 import BeautifulSoup
def forbes_rank(symbol: str = "2021福布斯中国创投人100") -> pd.DataFrame:
"""
福布斯中国-榜单
https://www.forbeschina.com/lists
https://www.forbeschina.com/lists/1750
:param symbol: choice of {"2020福布斯美国富豪榜", "2020福布斯新加坡富豪榜", "2020福布斯中国名人榜", *}
:type symbol: str
:return: 具体指标的榜单
:rtype: pandas.DataFrame
"""
url = "https://www.forbeschina.com/lists"
r = requests.get(url, verify=False)
soup = BeautifulSoup(r.text, "lxml")
need_list = [
item.find_all("a") for item in soup.find_all("div", attrs={"class": "col-sm-4"})
]
all_list = []
for item in need_list:
all_list.extend(item)
name_url_dict = dict(
zip(
[item.text.strip() for item in all_list],
["https://www.forbeschina.com" + item["href"] for item in all_list],
)
)
r = requests.get(name_url_dict[symbol], verify=False)
temp_df = pd.read_html(r.text)[0]
return temp_df
if __name__ == "__main__":
forbes_rank_df = forbes_rank(symbol="2021福布斯中国香港富豪榜")
print(forbes_rank_df)
@@ -0,0 +1,338 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2023/12/22 20:00
Desc: 胡润排行榜
https://www.hurun.net/
"""
import warnings
import pandas as pd
import requests
from bs4 import BeautifulSoup
def hurun_rank(indicator: str = "胡润百富榜", year: str = "2023") -> pd.DataFrame:
"""
胡润排行榜
https://www.hurun.net/CN/HuList/Index?num=3YwKs889SRIm
:param indicator: choice of {"胡润百富榜", "胡润全球富豪榜", "胡润印度榜", "胡润全球独角兽榜", "全球瞪羚企业榜", "胡润Under30s创业领袖榜", "胡润中国500强民营企业", "胡润世界500强", "胡润艺术榜"}
:type indicator: str
:param year: 指定年份; {"胡润百富榜": "2014-至今", "胡润全球富豪榜": "2019-至今", "胡润印度榜": "2018-至今", "胡润全球独角兽榜": "2019-至今", "中国瞪羚企业榜": "2021-至今", "全球瞪羚企业榜": "2021-至今", "胡润Under30s创业领袖榜": "2019-至今", "胡润中国500强民营企业": "2019-至今", "胡润世界500强": "2020-至今", "胡润艺术榜": "2019-至今"}
:type year: str
:return: 指定 indicator 和 year 的数据
:rtype: pandas.DataFrame
"""
url = "https://www.hurun.net/zh-CN/Rank/HsRankDetails?pagetype=rich"
r = requests.get(url)
soup = BeautifulSoup(r.text, "lxml")
url_list = []
for item in soup.find_all("ul", attrs={"class": "dropdown-menu"}):
for inner_item in item.find_all("a"):
url_list.append("https://www.hurun.net" + inner_item["href"])
name_list = []
for item in soup.find_all("ul", attrs={"class": "dropdown-menu"}):
for inner_item in item.find_all("a"):
name_list.append(inner_item.text.strip())
name_url_map = dict(zip(name_list, url_list))
r = requests.get(name_url_map[indicator])
soup = BeautifulSoup(r.text, "lxml")
code_list = [
item["value"].split("=")[2]
for item in soup.find(attrs={"id": "exampleFormControlSelect1"}).find_all(
"option"
)
]
year_list = [
item.text.split(" ")[0]
for item in soup.find(attrs={"id": "exampleFormControlSelect1"}).find_all(
"option"
)
]
year_code_map = dict(zip(year_list, code_list))
params = {
"num": year_code_map[year],
"search": "",
"offset": "0",
"limit": "20000",
}
if year == "2018":
warnings.warn("正在下载中")
offset = 0
limit = 20
big_df = pd.DataFrame()
while offset < 2200:
try:
params.update(
{
"offset": offset,
"limit": limit,
}
)
url = "https://www.hurun.net/zh-CN/Rank/HsRankDetailsList"
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["rows"])
offset = offset + 20
big_df = pd.concat([big_df, temp_df], ignore_index=True)
except requests.exceptions.JSONDecodeError:
offset = offset + 40
continue
big_df.rename(
columns={
"hs_Rank_Rich_Ranking": "排名",
"hs_Rank_Rich_Wealth": "财富",
"hs_Rank_Rich_Ranking_Change": "排名变化",
"hs_Rank_Rich_ChaName_Cn": "姓名",
"hs_Rank_Rich_ComName_Cn": "企业",
"hs_Rank_Rich_Industry_Cn": "行业",
},
inplace=True,
)
big_df = big_df[
[
"排名",
"财富",
"姓名",
"企业",
"行业",
]
]
return big_df
url = "https://www.hurun.net/zh-CN/Rank/HsRankDetailsList"
r = requests.get(url, params=params)
data_json = r.json()
temp_df = pd.DataFrame(data_json["rows"])
if indicator == "胡润百富榜":
temp_df.rename(
columns={
"hs_Rank_Rich_Ranking": "排名",
"hs_Rank_Rich_Wealth": "财富",
"hs_Rank_Rich_Ranking_Change": "排名变化",
"hs_Rank_Rich_ChaName_Cn": "姓名",
"hs_Rank_Rich_ComName_Cn": "企业",
"hs_Rank_Rich_Industry_Cn": "行业",
},
inplace=True,
)
temp_df = temp_df[
[
"排名",
"财富",
"姓名",
"企业",
"行业",
]
]
elif indicator == "胡润全球富豪榜":
temp_df.rename(
columns={
"hs_Rank_Global_Ranking": "排名",
"hs_Rank_Global_Wealth": "财富",
"hs_Rank_Global_Ranking_Change": "排名变化",
"hs_Rank_Global_ChaName_Cn": "姓名",
"hs_Rank_Global_ComName_Cn": "企业",
"hs_Rank_Global_Industry_Cn": "行业",
},
inplace=True,
)
temp_df = temp_df[
[
"排名",
"财富",
"姓名",
"企业",
"行业",
]
]
elif indicator == "胡润印度榜":
temp_df.rename(
columns={
"hs_Rank_India_Ranking": "排名",
"hs_Rank_India_Wealth": "财富",
"hs_Rank_India_Ranking_Change": "排名变化",
"hs_Rank_India_ChaName_Cn": "姓名",
"hs_Rank_India_ComName_Cn": "企业",
"hs_Rank_India_Industry_Cn": "行业",
},
inplace=True,
)
temp_df = temp_df[
[
"排名",
"财富",
"姓名",
"企业",
"行业",
]
]
elif indicator == "胡润全球独角兽榜":
temp_df.rename(
columns={
"hs_Rank_Unicorn_Ranking": "排名",
"hs_Rank_Unicorn_Wealth": "财富",
"hs_Rank_Unicorn_Ranking_Change": "排名变化",
"hs_Rank_Unicorn_ChaName_Cn": "姓名",
"hs_Rank_Unicorn_ComName_Cn": "企业",
"hs_Rank_Unicorn_Industry_Cn": "行业",
},
inplace=True,
)
temp_df = temp_df[
[
"排名",
"财富",
"姓名",
"企业",
"行业",
]
]
elif indicator == "中国瞪羚企业榜":
temp_df.rename(
columns={
"hs_Rank_CGazelles_ComHeadquarters_Cn": "企业总部",
"hs_Rank_CGazelles_Name_Cn": "掌门人/联合创始人",
"hs_Rank_CGazelles_ComName_Cn": "企业信息",
"hs_Rank_CGazelles_Industry_Cn": "行业",
},
inplace=True,
)
temp_df = temp_df[
[
"企业信息",
"掌门人/联合创始人",
"企业总部",
"行业",
]
]
elif indicator == "全球瞪羚企业榜":
temp_df.rename(
columns={
"hs_Rank_GGazelles_ComHeadquarters_Cn": "企业总部",
"hs_Rank_GGazelles_Name_Cn": "掌门人/联合创始人",
"hs_Rank_GGazelles_ComName_Cn": "企业信息",
"hs_Rank_GGazelles_Industry_Cn": "行业",
},
inplace=True,
)
temp_df = temp_df[
[
"企业信息",
"掌门人/联合创始人",
"企业总部",
"行业",
]
]
elif indicator == "胡润Under30s创业领袖榜":
temp_df.rename(
columns={
"hs_Rank_U30_ComHeadquarters_Cn": "企业总部",
"hs_Rank_U30_ChaName_Cn": "姓名",
"hs_Rank_U30_ComName_Cn": "企业信息",
"hs_Rank_U30_Industry_Cn": "行业",
},
inplace=True,
)
temp_df = temp_df[
[
"姓名",
"企业信息",
"企业总部",
"行业",
]
]
elif indicator == "胡润中国500强民营企业":
temp_df.rename(
columns={
"hs_Rank_CTop500_Ranking": "排名",
"hs_Rank_CTop500_Wealth": "企业估值",
"hs_Rank_CTop500_Ranking_Change": "排名变化",
"hs_Rank_CTop500_ChaName_Cn": "CEO",
"hs_Rank_CTop500_ComName_Cn": "企业信息",
"hs_Rank_CTop500_Industry_Cn": "行业",
},
inplace=True,
)
temp_df = temp_df[
[
"排名",
"排名变化",
"企业估值",
"企业信息",
"CEO",
"行业",
]
]
elif indicator == "胡润世界500强":
temp_df.rename(
columns={
"hs_Rank_GTop500_Ranking": "排名",
"hs_Rank_GTop500_Wealth": "企业估值",
"hs_Rank_GTop500_Ranking_Change": "排名变化",
"hs_Rank_GTop500_ChaName_Cn": "CEO",
"hs_Rank_GTop500_ComName_Cn": "企业信息",
"hs_Rank_GTop500_Industry_Cn": "行业",
},
inplace=True,
)
temp_df = temp_df[
[
"排名",
"排名变化",
"企业估值",
"企业信息",
"CEO",
"行业",
]
]
elif indicator == "胡润艺术榜":
temp_df.rename(
columns={
"hs_Rank_Art_Ranking": "排名",
"hs_Rank_Art_Turnover": "成交额",
"hs_Rank_Art_Ranking_Change": "排名变化",
"hs_Rank_Art_Name_Cn": "姓名",
"hs_Rank_Art_Age": "年龄",
"hs_Rank_Art_ArtCategory_Cn": "艺术类别",
},
inplace=True,
)
temp_df = temp_df[
[
"排名",
"排名变化",
"成交额",
"姓名",
"年龄",
"艺术类别",
]
]
return temp_df
if __name__ == "__main__":
hurun_rank_df = hurun_rank(indicator="胡润百富榜", year="2023")
print(hurun_rank_df)
hurun_rank_df = hurun_rank(indicator="胡润全球富豪榜", year="2023")
print(hurun_rank_df)
hurun_rank_df = hurun_rank(indicator="胡润全球独角兽榜", year="2023")
print(hurun_rank_df)
hurun_rank_df = hurun_rank(indicator="胡润印度榜", year="2021")
print(hurun_rank_df)
hurun_rank_df = hurun_rank(indicator="全球瞪羚企业榜", year="2021")
print(hurun_rank_df)
hurun_rank_df = hurun_rank(indicator="胡润Under30s创业领袖榜", year="2021")
print(hurun_rank_df)
hurun_rank_df = hurun_rank(indicator="胡润世界500强", year="2022")
print(hurun_rank_df)
hurun_rank_df = hurun_rank(indicator="胡润艺术榜", year="2023")
print(hurun_rank_df)
@@ -0,0 +1,76 @@
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Date: 2022/10/30 21:12
Desc: 新财富 500 人富豪榜
http://www.xcf.cn/zhuanti/ztzz/hdzt1/500frb/index.html
"""
import json
import pandas as pd
import requests
def xincaifu_rank(year: str = "2022") -> pd.DataFrame:
"""
新财富 500 人富豪榜
http://www.xcf.cn/zhuanti/ztzz/hdzt1/500frb/index.html
:param year: 具体排名年份, 数据从 2003-至今
:type year: str
:return: 排行榜
:rtype: pandas.DataFrame
"""
url = "http://service.ikuyu.cn/XinCaiFu2/pcremoting/bdListAction.do"
params = {
"method": "getPage",
"callback": "jsonpCallback",
"sortBy": "",
"order": "",
"type": "4",
"keyword": "",
"pageSize": "1000",
"year": year,
"pageNo": "1",
"from": "jsonp",
}
r = requests.get(url, params=params)
data_text = r.text
data_json = json.loads(data_text[data_text.find("{") : -1])
temp_df = pd.DataFrame(data_json["data"]["rows"])
temp_df.columns
temp_df.rename(
columns={
"assets": "财富",
"year": "年份",
"sex": "性别",
"name": "姓名",
"rank": "排名",
"company": "主要公司",
"industry": "相关行业",
"id": "-",
"addr": "公司总部",
"rankLst": "-",
"age": "年龄",
},
inplace=True,
)
temp_df = temp_df[
[
"排名",
"财富",
"姓名",
"主要公司",
"相关行业",
"公司总部",
"性别",
"年龄",
"年份",
]
]
return temp_df
if __name__ == "__main__":
xincaifu_rank_df = xincaifu_rank(year="2022")
print(xincaifu_rank_df)