python爬虫抓取易方达指数基金网数据的一些实践

易方达指数基金网(http://www.indexfunds.com.cn)是中国最早的指数和指数基金研究网站,2012年8月份就上线了。
易方达指数基金网使用的是wind的授权数据,其免费、简洁、强大,是深受保险、券商、社保等机构投资者,基金代销机构的理财经理,基金持有人,指数领域从业者,财经记者,研究分析人员等各路人马好评的神器。
我们怎么用python爬虫把有用的公开数据抓取下来,用来自己研究呢?
我们先来看看这个网站。选择「指数分区」。

以「沪深300」指数基金为例,曲线图上展示的数据有:指数名称、指数代码、某日价格、较前日涨跌、日期,这就是我们想要的数据。
怎么得到我们想要的数据呢?
在调试工具的Network里找到文件 http://static.indexfunds.com.cn/market/ifs/000300.SH_cy_nv.js ,这是2018年往后的数据,其数据格式为:

http://static.indexfunds.com.cn/market/his/ifs/000300.SH_all_nv.js
这是基金成立之日起,至2017年年底的数据。两个文件的内容相加,即为全部数据。
我们观察数据‘20180102_4087.4012_0.014028’,很明显,「20180102」为日期,「4087.4012」为价格,「0.014028」为涨跌。
那么,我们只需要找到指数基金对应的文件,就可以解构出所需的数据了。
核心代码:

#传入url,获取指数详情
def getFundInfo(url):
    fundinfo=[]
    headers = {
        'User-Agent': random.choice(USER_AGENTS),
    }
    response = requests.request("GET", url, headers=headers)
    s=response.text.split('[')[-1]#字符串分割,将=号后面的内容保存下来
    s = s.split(']')[0]
    s=s.replace("'", "")#去掉字符串本身的引号
    data = s.split(',')#按逗号将str数据转为list
    for i in data:
        time=i.split('_')[0]#时间
        price=i.split('_')[1]#价格
        change=i.split('_')[-1]#涨跌
        fundinfo.append({'时间':time,'数值':price,'涨跌':change
        })
    return fundinfo

还有两个问题,怎么获取指数基金对应的文件?
200多个指数基金代码,又怎么获取?
第一个问题,很简单,可以这样构造文件的url地址:
url1 = 'http://static.indexfunds.com.cn/market/his/ifs/' + id + '_all_nv.js'
url2 = 'http://static.indexfunds.com.cn/market/ifs/' + id + '_cy_nv.js'
第二个问题,获取指数基金的代码、id:

#获取指数列表
def getFundList():
    url = "http://www.indexfunds.com.cn/analyse/trend"
    headers = {
            'User-Agent': random.choice(USER_AGENTS),
            }
    response = requests.request("GET", url,headers=headers)
    #print(response.text)
    response.encoding = response.apparent_encoding
    soup = BeautifulSoup(response.text, "lxml")
    selFundList = soup.find(attrs={'class': 'm-selFundListwrap'})
    li=selFundList.find_all(name='li')
    fundlist=[]
    for i in li:
        class_name=i.get('class')[-1]#所属分类名
        id=i.find(name='input').get('id')#指数ID
        indexname=i.find(name='input').get('indexname')#指数名称
        codeshow=i.find(name='input').get('codeshow')#指数代码
        fundlist.append({'id':id,'分类':class_name,'指数名称':indexname,'指数代码':codeshow
        })
    print(len(fundlist))
    return fundlist

 
注:
本文仅作学习记录之用。
本栏目所载数据的版权归万得信息技术股份有限公司所有。万得信息技术股份有限公司对本栏目所载数据保留一切权利。未经万得信息技术股份有限公司事先授权,本栏目所载数据的任何部分均不得以任何方式制作成任何形式的拷贝、复印件或复制品,或再次分发给任何其他人,或以任何侵犯万得信息技术股份有限公司权利的其他方式使用。