一、选题背景

  基金业发展历史。20世纪70年代以来,基金业随着世界投资规模的剧增、基金业现代金融业的创新,品种繁多、基金业名目各异的基金风起云涌,基金业形成了一个庞大的产业。目前,基金业从世界范围来看.基金产业已经与银行业、证券业、保险业并驾齐驭,基金业成为现代金触体系的四大支柱之一。而在如今的投资理财市场中,基金产品非常多,比如货币基金、债券基金等,所有基金产品都受到投资者关注,基金已经成为当下特别火爆的赚钱工具。

 

二、主题式网络爬虫设计方案

1.主题式网络爬虫名称

爬取基金金融网历史净值

2.主题式网络爬虫爬取的内容与数据特征分析

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据

 

 

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_html_02

 

 

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据_03

 

 

 

 对数据元素分析可知,数据在tr标签的td标签下

3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)

思路:通过分析网页源代码,找出所需的数据所在的标签,通过爬虫读取数据保存到xlsx文件中,读取文件,对文件进行数据清洗和处理,数据分析和可视化处理。 

技术难点:对数据处理还有其他方面包括乱码的情况处理比较生疏。

 导入包

import requests
from bs4 import BeautifulSoup
import re
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
from sklearn import  linear_model
# 处理乱码
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['font.family']='sans-serif'
matplotlib.rcParams['axes.unicode_minus'] = False
#函数用于获取来自这个接口的返回结果,以便于后面的调用
def get_html(code, start_date, end_date, page=1, per=20):
    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
#用于返回获取得到基金数据的函数
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
if __name__ == '__main__':
    # 导入需要的模块
    
    import requests
    from bs4 import BeautifulSoup
    import re
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import matplotlib
    import time
    from datetime import date
    
    enddate = date.today().isoformat()
    
    fund_df = get_fund('512120' ,start_date='2021-01-01',end_date=enddate)
    print(fund_df)
    fund_df.to_csv('s医药50ETF512120.csv')
    print("输出完成")

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据_04

 

 数据分析

data = pd.read_csv("酒ETF512690.csv")
data.head()

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据_05

 

 

data.info()

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据_06

 

 

data = DataFrame([ data["净值日期"],data["单位净值"],data["累计净值"],data["日增长率"]]).T
data.head()

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据存取_07

 

 相关系数

data.corr()

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据存取_08

 

 峰度

data.kurt()

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据_09

 

 偏度

data.skew()

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据_10

 

 方差

data.var()

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据存取_11

 

 平均绝对偏差

data.mad()

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据_12

 

 标准差

data.std()

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据存取_13

 

 单位净值、累计净值和日增长率 进行可视化分析

from pylab import *   
mpl.rcParams['font.sans-serif'] = ['SimHei']
def pic_data(name, data):
    dwjz = [i for i in data['单位净值']]
    ljjz = [i for i in data['累计净值']]
    rzzl = [i for i in data['日增长率']]
    mean_lj = np.mean(ljjz) # 累计净值均值
    mean_rz = np.mean(rzzl) # 日增长率均值
    
    x = range(len(dwjz))
    plt.plot(x, dwjz, 'r-',label='单位净值')
    plt.plot(x, ljjz, 'b-',label='累计净值')
    plt.axhline(y=mean_lj,ls='--',c="gray",label='累计净值均值')#添加水平直线
    plt.legend()
    plt.title("{}的近一年净值变化".format(name))
    plt.show()
    plt.plot(x, rzzl, 'g-',label='日增长率')
    plt.axhline(y=mean_rz,ls='--',c="gray",label='日增长率均值')#添加水平直线
    plt.legend()
    plt.title("{}的近一年的日增长率变化".format(name))
    plt.show()
pic_data('酒ETF', data)

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据_14

 

 

from sklearn import  linear_model
model = linear_model.LinearRegression()
x=gp['单位净值'].values
y=gp['累计净值'].values
x=x.reshape(-1,1)
model.fit(x,y)
print("回归方程系数{}".format(model.coef_))
print("回归方程截距:{}".format(model.intercept_))

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据存取_15

 

 

x = np.random.uniform(gp['单位净值'])
y = np.log(x) + np.random.normal(gp['累计净值'])
 
pl.scatter(x, y, s=1, label="log(x) with noise")
pl.plot(np.arange(1, 100), np.log(np.arange(1, 100)), c="b", label="log(x) true function")
pl.xlabel("x")
pl.ylabel("f(x) = log(x)")
pl.legend(loc="best")
pl.title("A Basic Log Function")
pl.show()

利用requests库爬取基金网站的基金净值信息 爬虫爬取基金_数据存取_16

 

总代码

1 # 导入需要的模块
  2 import requests
  3 from bs4 import BeautifulSoup
  4 import re
  5 import numpy as np
  6 import pandas as pd
  7 import matplotlib.pyplot as plt
  8 import matplotlib
  9 from sklearn import  linear_model
 10 # 处理乱码
 11 matplotlib.rcParams['font.sans-serif'] = ['SimHei']
 12 matplotlib.rcParams['font.family']='sans-serif'
 13 matplotlib.rcParams['axes.unicode_minus'] = False
 14 #函数用于获取来自这个接口的返回结果,以便于后面的调用
 15 def get_html(code, start_date, end_date, page=1, per=20):
 16     url = 'http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code={0}&page={1}&sdate={2}&edate={3}&per={4}'.format(
 17         code, page, start_date, end_date, per)
 18     rsp = requests.get(url)
 19     html = rsp.text
 20     return html
 21 #用于返回获取得到基金数据的函数
 22 def get_fund(code, start_date, end_date, page=1, per=20):
 23     # 获取html
 24     html = get_html(code, start_date, end_date, page, per)
 25     soup = BeautifulSoup(html, 'html.parser')
 26     # 获取总页数
 27     pattern = re.compile('pages:(.*),')
 28     result = re.search(pattern, html).group(1)
 29     total_page = int(result)
 30     # 获取表头信息
 31     heads = []
 32     for head in soup.findAll("th"):
 33         heads.append(head.contents[0])
 34  
 35  
 36     # 数据存取列表
 37     records = []
 38     # 获取每一页的数据
 39     current_page = 1
 40     while current_page <= total_page:
 41         html = get_html(code, start_date, end_date, current_page, per)
 42         soup = BeautifulSoup(html, 'html.parser')
 43         # 获取数据
 44         for row in soup.findAll("tbody")[0].findAll("tr"):
 45             row_records = []
 46             for record in row.findAll('td'):
 47                 val = record.contents
 48                 # 处理空值
 49                 if val == []:
 50                     row_records.append(np.nan)
 51                 else:
 52                     row_records.append(val[0])
 53             # 记录数据
 54             records.append(row_records)
 55         # 下一页
 56         current_page = current_page + 1
 57  
 58  
 59     # 将数据转换为Dataframe对象
 60     np_records = np.array(records)
 61     fund_df = pd.DataFrame()
 62     for col, col_name in enumerate(heads):
 63         fund_df[col_name] = np_records[:, col]
 64  
 65  
 66     # 按照日期排序
 67     fund_df['净值日期'] = pd.to_datetime(fund_df['净值日期'], format='%Y/%m/%d')
 68     fund_df = fund_df.sort_values(by='净值日期', axis=0, ascending=True).reset_index(drop=True)
 69     fund_df = fund_df.set_index('净值日期')
 70  
 71  
 72     # 数据类型处理
 73     fund_df['单位净值'] = fund_df['单位净值'].astype(float)
 74     fund_df['累计净值'] = fund_df['累计净值'].astype(float)
 75     fund_df['日增长率'] = fund_df['日增长率'].str.strip('%').astype(float)
 76     return fund_df
 77  
 78 if __name__ == '__main__':
 79     # 导入需要的模块
 80     
 81     import requests
 82     from bs4 import BeautifulSoup
 83     import re
 84     import numpy as np
 85     import pandas as pd
 86     import matplotlib.pyplot as plt
 87     import matplotlib
 88     import time
 89     from datetime import date
 90     
 91     enddate = date.today().isoformat()
 92     
 93     fund_df = get_fund('512120' ,start_date='2021-01-01',end_date=enddate)
 94     print(fund_df)
 95     fund_df.to_csv('s医药50ETF512120.csv')
 96     print("输出完成")
 97 data = pd.read_csv("酒ETF512690.csv")
 98 data.head()
 99 data.info()
100 data = DataFrame([ data["净值日期"],data["单位净值"],data["累计净值"],data["日增长率"]]).T
101 data.cov()
102 data.corr()
103 data.kurt()
104 data.skew()
105 data.var()
106 data.mad()
107 data.std()
108 #单位净值、累计净值和日增长率 进行可视化分析
109 from pylab import *   
110 mpl.rcParams['font.sans-serif'] = ['SimHei']
111 def pic_data(name, data):
112     dwjz = [i for i in data['单位净值']]
113     ljjz = [i for i in data['累计净值']]
114     rzzl = [i for i in data['日增长率']]
115     mean_lj = np.mean(ljjz) # 累计净值均值
116     mean_rz = np.mean(rzzl) # 日增长率均值
117     
118     x = range(len(dwjz))
119     plt.plot(x, dwjz, 'r-',label='单位净值')
120     plt.plot(x, ljjz, 'b-',label='累计净值')
121     plt.axhline(y=mean_lj,ls='--',c="gray",label='累计净值均值')#添加水平直线
122     plt.legend()
123     plt.title("{}的近一年净值变化".format(name))
124     plt.show()
125     plt.plot(x, rzzl, 'g-',label='日增长率')
126     plt.axhline(y=mean_rz,ls='--',c="gray",label='日增长率均值')#添加水平直线
127     plt.legend()
128     plt.title("{}的近一年的日增长率变化".format(name))
129     plt.show()
130 pic_data('酒ETF', data)
131 #回顾方程
132 from sklearn import  linear_model
133 model = linear_model.LinearRegression()
134 x=gp['单位净值'].values
135 y=gp['累计净值'].values
136 x=x.reshape(-1,1)
137 model.fit(x,y)
138 print("回归方程系数{}".format(model.coef_))
139 print("回归方程截距:{}".format(model.intercept_))
140 
141 x = np.random.uniform(gp['单位净值'])
142 y = np.log(x) + np.random.normal(gp['累计净值'])
143  
144 pl.scatter(x, y, s=1, label="log(x) with noise")
145 pl.plot(np.arange(1, 100), np.log(np.arange(1, 100)), c="b", label="log(x) true function")
146 pl.xlabel("x")
147 pl.ylabel("f(x) = log(x)")
148 pl.legend(loc="best")
149 pl.title("A Basic Log Function")
150 pl.show()

 

 一通过前段时间python课程的学习,加上这段时间爬虫程序的设计与实践。发现运用python可以做许多事情,编写各种程序,而爬虫程序更是可以进行数据获取及整合,通过清洗后可视化能更好的进行数据分析。可惜自身学识有限,在爬虫过程中遇到许多问题并不能很好解决,在查找资料的过程中无不为他人厉害的爬虫程序所驻足,忍不住想要一试,例如爬取歌单等等。这便是爬虫的魅力,做许多本想不到的事。此次制作更是让我明白,纸上功夫是没用的,想要学好还得实践才行,实践了才明白如何运用库,函数。
二、经过对主题数据的分析与可视化,可以得到哪些结论?
结论:通过对数据的分析与可视化,各数据之间的关系和呈现出来的分布,让数据的分析变的更容易起来。对于绘制图形方面的时候我们需要整理好正确的数据,这样才可以绘制出正确的图示。