关注“发发与柴柴”,鼓捣赚钱的秘密
登高而招,臂非加长也,而见者远
———荀子《劝学》
在《如何利用Python天天基金获取基金单位净值、累计净值、增长率(上)》
如何利用Python天天基金获取基金单位净值、累计净值、增长率(上)中描述了手工从天天基金获取基金数据的全部过程。
手工获取数据过于繁琐,而且数据格式可能存在不统一的情况,不利于后续的数据分析。
故本文记录如何利用Python从天天基金批量获取相关的数据
# 导入需要的模块
# 若无相关module, 可以在jupyter note中可以 ! pip install <模块名>
import requests
import re
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from bs4 import BeautifulSoup
# 定义获取天天基金html的函数
# 该函数也是参考别的大神写的
# 该函数用于访问指定url,即按照基金代码、开始和截止日期访问到相应的页面
def get_html(code, start_date, end_date, page=1, per=20):
''' 需要输入的参数为code:即基金代码,starte_date: 开始日期'''
'''end_date:结束日期'''
url = 'http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code={0}&page={1}&sdate={2}&edate={3}&per={4}'.format(
code, page, start_date, end_date, per)
rsp = requests.get(url)
html = rsp.text
return html
# 定义获取基金数值的函数
# 通过上文的get_html函数访问到相应的页面后,需要通过beautifulsoup对html页面进行解析
# 解析后的数据写入dataframe, 并进行返回
def get_fund(code, start_date, end_date, page=1, per=20):
# 获取html
html = get_html(code, start_date, end_date, page, per)
soup = BeautifulSoup(html, 'html.parser')
# 获取总页数
pattern = re.compile('pages:(.*),')
result = re.search(pattern, html).group(1)
total_page = int(result)
# 获取表头信息
heads = []
for head in soup.findAll("th"):
heads.append(head.contents[0])
# 数据存取列表
records = []
# 获取每一页的数据
current_page = 1
while current_page <= total_page:
html = get_html(code, start_date, end_date, current_page, per)
soup = BeautifulSoup(html, 'html.parser')
# 获取数据
for row in soup.findAll("tbody")[0].findAll("tr"):
row_records = []
for record in row.findAll('td'):
val = record.contents
# 处理空值
if val == []:
row_records.append(np.nan)
else:
row_records.append(val[0])
# 记录数据
records.append(row_records)
# 下一页
current_page = current_page + 1
# 将数据转换为Dataframe对象
np_records = np.array(records)
fund_df = pd.DataFrame()
for col, col_name in enumerate(heads):
fund_df[col_name] = np_records[:, col]
# 按照日期排序
fund_df['净值日期'] = pd.to_datetime(fund_df['净值日期'], format='%Y/%m/%d')
fund_df = fund_df.sort_values(by='净值日期', axis=0, ascending=True).reset_index(drop=True)
fund_df = fund_df.set_index('净值日期')
# 数据类型处理
fund_df['单位净值'] = fund_df['单位净值'].astype(float)
fund_df['累计净值'] = fund_df['累计净值'].astype(float)
fund_df['日增长率'] = fund_df['日增长率'].str.strip('%').astype(float)
return fund_df
小结:在上文中,我们主要定义了2个函数,分别为get_html 和 get_fund。其中(1)get_html用于访问指定的url,获取页面;(2)get_fund用于解析页面,获取相应的数据,并将整合进dataframe中进行返回.
在定义了函数后,我们接下来进行实操。
为了方便同时获取多只基金的数据,需要将基金代码以字典的形式批量输入。比如我希望获取广发纳指100,银河收益混合,易方达稳健收益B,易方达安心回报债券A等4只基金的数据。
#需要获取的基金代码
my_dict={'广发纳指100':'270042',
'银河收益混合':'151002',
'易方达稳健收益B':'110008',
'易方达安心回报债券A':'110027'}
在my_dict输入基金的名称和代码。注意,字典元素索引名,如‘广发纳指100’并不是重要的关键字,可以根据喜好任意输入。但请务必保证值,即基金代码‘270042’正确,否则将无法访问到指定的基金数据。
# 此代码用于将上文提及的基金名称、代码等,由字典类型转换成 dataframe类型
my_df = pd.DataFrame.from_dict(my_dict, orient='index',columns=['code'])
my_df=my_df.reset_index().rename(columns={'index':'name'})
正式获取基金相关数据的代码。假设希望获取2014-02-01到2020-12-27的数据,需要在for 循环中的get_fund()函数中,分别令start_date=
'2014-02-01'
,end_date=
'2020-12-27'
# 先创立一个local化的变量,用于在for循环中自动创建dataframe
fund_df_=locals()
for i in range(len(my_df)):
# 根据输入的基金名称和数量,自动创建相应个数的dataframe
fund_df_[i]=pd.DataFrame()
# 获取基金数据
fund_df_[i]=get_fund(my_df['code'][i],start_date='2014-02-01',end_date='2020-12-27')
# 将基金数据作为xlsx文件写入本地
fund_df_[i].to_excel(my_df['name'][i]+'.xlsx')
由于我们获取的基金数据,分别存储在几个变量中,且拥有7个表头。
如果我们只对每只基金的累计净值感兴趣,那么我们需要获取每个变量的“累计净值”数据。
# 先创立一个local化的变量,用于在for循环中自动获取dataframe变量名
fund_df_=locals()
# 创建1个名为datas的列表,用于存放每次循环获取到的基金的累计净值数据
# 每一次循环即可获取某只基金的全部累计净值数据
datas=[]
for i in range(len(my_df)):
jingzhi=fund_df_[i]['累计净值'].to_frame()
jingzhi=jingzhi.rename(columns={'累计净值':my_df['name'][i]})
datas.append(jingzhi)
在生成datas变量后,我们利用concat函数,按照列进行拼接即可
df = pd.concat(datas,axis=1)
# 显示前5行的数据
df.head()
最终获取的数据前5行如下:
后续即可根据自己的需求,获取相应的数据,对基金数据进行分析了。
本文地址:http://www.cj8815.cn/101925.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 931614094@qq.com 举报,一经查实,本站将立刻删除。