数据分析学习之路——(六)用数据分析教你如何买基金(1)

        最近基金行情感觉很不错,想着再入手几只,于是有了通过数据分析来帮我做决策这个想法。由于我手里的是一只南方基金的产品,因此为了对比决定把南方基金的基金信息(截止2017.10.27)给扒下来。我仔细分析了该网站我要的产品信息所在的页面,最终决定将所有的产品信息保存为两个文件。一个文件记录基金的基本信息,比如:基金代码、基金名称、基金类型、风险等级等;另一个文件则记录基金的历史净值和收益等信息。

        由于每只基金详细信息必须通过基金列表页面的链接点击过去,才能看到。因此第一步爬取列表页面,再通过正则表达式匹配所有的基金代码,再将代码拼接成请求每个基金产品数据的url。

def get_page_fundinfo(self,fundurl):
    url = fundurl
    headers={
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
        'Cookie' : 'skillId=6; skillId=6; pageReferrInSession=https%3A//www.baidu.com/link%3Furl%3D54aALJ8xAviE_YUY4z_oXlXPauU2IzKa73YN60b5'
                   'tTe%26wd%3D%26eqid%3Df187ca530001f47d0000000459f4ac0f; skillId=6; JSESSIONID=sFYfZ1Ld9rq1nVDrw4QTLyvrjvVq0P0ZQzr5JnvyYPQY'
                   'c8kLJ6Kb!471155903; Hm_lvt_53143ec1a9124a0122dd24b077a6082d=1507820096,1509207062,1509207076,1509207130; Hm_lpvt_53143ec1a'
                   '9124a0122dd24b077a6082d=1509265974',
        'Referer':'http://www.nffund.com/'
    }
    try:
        request=urllib2.Request(url,headers=headers)
        respose=urllib2.urlopen(request)
        return respose.read()
    except Exception,e:
        print e
def get_fundcode_list(self, fundurl):
    # fundurl = 'http://www.nffund.com/new/fundproduct/'
    fundinfo = self.get_page_fundinfo(fundurl)
    pattern = re.compile('href="/new/fundproduct/static/searchjjgk_(.*?)_jjgk.html".*?title=', re.S)  # 正则匹配基金代码
    items = re.findall(pattern, fundinfo)
    fundcodelist = []
    for item in items:
        fundcodelist.append(item)
    # print len(fundList)   # 229只基金产品代码,正确
    return fundcodelist

        如上,将所有的基金代码保存在fundcodelist里面,通过循环取数据。由于基金详情页面用的模板生成,所以不能通过请求页面得到真实数据。解决办法是通过抓包获取页面通过get或post方式请求的后台地址,如下面的/FundNewServlet.java,再根据这个请求返回的结果组装数据。

for fundcode in fundcodelist:
    # 获取基金基本信息
    fundinfo_url = self.url + '/FundNewServlet.java?action=searchjjgk&fundcode=' + fundcode
    # 获取基金历史净值和收益
    fundvalue_url = self.url + '/FundNewServlet.java?action=searchjjjz&pageSize=99999&timestart=&timeend=&pageNo=&only_syl=1&fundcode=' + fundcode
    nfspider.save_fundinfo(fundinfo_url,1)
    nfspider.save_fundinfo(fundvalue_url,2)

抓包结果示例如下:

        003534_IVHX_3642529.png

        接下来是最重要的处理部分,上面通过直接请求Servlet后返回的是json格式的数据,在Python中,可以用字典类型来处理。

'''基金产品基本信息'''
def get_compile_fundinfo(self,fundurl):
    page_fundinfo = self.get_page_fundinfo(fundurl)  # 请求severlet返回json格式数据
    dic_fundinfo=json.loads(page_fundinfo)
    # ['基金代码', '基金名称', '基金类型', '运作方式', '风险等级', '资产规模', '基金托管人', '基金状态']
    fundcode=fundname=styledes=operatorstyle=risk=jjtgr=statedes=''
    fundasset=0
    '''由于dicFundInfo可能部分产品属性不全,这样判断后处理能兼容很多错误情况'''
    if dic_fundinfo.get('data').get('fund_info') and dic_fundinfo.get('data').get('fund_info').get('fundCode'):
        fundcode=dic_fundinfo.get('data').get('fund_info').get('fundCode')
    if dic_fundinfo.get('data').get('fund_info') and dic_fundinfo.get('data').get('fund_info').get('fundName'):
        fundname = dic_fundinfo.get('data').get('fund_info').get('fundName')
    if dic_fundinfo.get('data').get('fund_info') and dic_fundinfo.get('data').get('fund_info').get('style_des'):
        styledes=dic_fundinfo.get('data').get('fund_info').get('style_des')
    if dic_fundinfo.get('data').get('fund_info') and dic_fundinfo.get('data').get('fund_info').get('operatorStyle'):
        operatorstyle=dic_fundinfo.get('data').get('fund_info').get('operatorStyle')
    if dic_fundinfo.get('data').get('fundRiskRating') and dic_fundinfo.get('data').get('fundRiskRating').get('RISKRATING'):
        risk=dic_fundinfo.get('data').get('fundRiskRating').get('RISKRATING')
    if dic_fundinfo.get('data').get('quarter') and dic_fundinfo.get('data').get('quarter').get('FUNDASSET'):
        fundasset=dic_fundinfo.get('data').get('quarter').get('FUNDASSET')
    if dic_fundinfo.get('data').get('fund_info') and dic_fundinfo.get('data').get('fund_info').get('jjtgr'):
        jjtgr=dic_fundinfo.get('data').get('fund_info').get('jjtgr')
    if dic_fundinfo.get('data').get('fund_info') and dic_fundinfo.get('data').get('fund_info').get('state_des'):
        statedes=dic_fundinfo.get('data').get('fund_info').get('state_des')
    # print [fundcode, fundname, styledes, operatorstyle, risk, fundasset, jjtgr, statedes]
    return [fundcode, fundname, styledes, operatorstyle, risk, fundasset, jjtgr, statedes]
'''基金产品历史净值'''
def get_compile_fundvalue(self,fundurl):
    page_fundvalue = self.get_page_fundinfo(fundurl)  # 请求severlet返回json格式数据
    dic_fundvalue=json.loads(page_fundvalue)
    #['基金代码', '基金名称', '净值日期', '基金净值', '累积净值', '日涨幅', '最近半年涨幅', '最近一年涨幅', '今年以来涨幅', '成立以来涨幅']
    fundcode=fundname=funddate=''
    fundasset=fundnav=ljfundnav=upratio=recent_halfyear=recent_oneyear=thisyear=since=0
    fundnavlist = dic_fundvalue.get('data').get('jjjzList')  # 每只产品多条净值数据
    fundnavarr=[]
    '''同样由于dicFundValue可能部分产品属性不全,会报NoneType错误,因此先要判断'''
    for fnav in fundnavlist:
        if fnav.get('fundCode'):
            fundcode=fnav.get('fundCode')
        if fnav.get('fundName'):
            fundname=fnav.get('fundName')
        if fnav.get('fdate'):
            funddate=fnav.get('fdate')
        if fnav.get('fundNav'):
            fundnav=fnav.get('fundNav')
        if fnav.get('ljfundNav'):
            ljfundnav=fnav.get('ljfundNav')
        if fnav.get('upRatio'):
            upratio=fnav.get('upRatio')
        if fnav.get('sylBo') and fnav.get('sylBo').get('recentHalfYear'):
            recent_halfyear=fnav.get('sylBo').get('recentHalfYear')
        if fnav.get('sylBo') and fnav.get('sylBo').get('recentOneYear'):
            recent_oneyear=fnav.get('sylBo').get('recentOneYear')
        if fnav.get('sylBo') and fnav.get('sylBo').get('thisYear'):
            thisyear=fnav.get('sylBo').get('thisYear')
        if fnav.get('sylBo') and fnav.get('sylBo').get('since'):
            since=fnav.get('sylBo').get('since')
        fundnavarr.append([fundcode, fundname, funddate, fundnav, ljfundnav, upratio, recent_halfyear, recent_oneyear, thisyear, since])
    # print fundnavarr
    return fundnavarr

        上面两个方法分别获取基金的基本信息和历史净值收益信息,而每个基金代码对应一条基本信息,每个基金代码对应多条净值及收益数据,因此处理略有不同。

        通过Python爬虫获取南方基金所有基金产品数据大致就是这样。最后将爬取的数据保存下来。

基金产品基本信息,共229只基金(截止2017.10.27):

        005203_Eh5G_3642529.png

基金净值、收益信息,共153762条数据(截止2017.10.27):

        005413_QU6I_3642529.png

        至此,爬数据的过程就算完成了,接下来就需要根据这些数据来获取我想要的信息了。

转载于:https://my.oschina.net/nekyo/blog/1557963

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值