一、大体思路
获取以去年(2020年)前为节点的基金数据:2019-2020年基金增长情况(近一年)、2018-2020年基金增长情况(近两年)、2019-2021年基金增长情况(近三年)、2020年末累计净值、基金经理收益率排行、基金公司规模排行作为特征向量.
由于固定基金的基金公司是不可能变化的,基金经理的变动概率也较小,所以我们将这两个向量做以下处理:
按照基金规模将基金公司和基金经理分别进行排名。
目前基金市场上大约存在187家基金公司,所以若某基金所属的基金公司是在基金公司排行榜前50,则我们将对应数值置1,否则置0.
目前手上持有基金的基金经理大约有2900人左右,所以若某基金所属的基金经理是在基金经理排行榜前150,则我们将对应数值置1,否则置0.
一、 爬取天天基金网基金排行榜
进入天天基金网排行榜页面,可以发现每个页面可显示50条基金信息,在进入下一页时,url没有变化,所以我们没法通过改变url来爬取所有数据。但是通过点击页面右下角的”“不分页”选项,可在此页面上获得所有排行榜上的基金。
我们使用selenium加载网页,获取页面信息,利用pyquery提取所需要的信息,并将数据以csv文件存储。爬虫代码如下:
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from pyquery import PyQuery as pq
import csv
import json
from lxml import etree
import pymongo
# client = pymongo.MongoClient(host='localhost', port=27017)
# db = client.天天基金 # 指定数据库,若不存在,则直接创建一个test数据库
# collection = db.基金排行
def gethtml(url):
brower = webdriver.Chrome()
brower.get(url)
html = brower.page_source
return html
def getinformation(html, csvfile):
# 打开csv文件
with open(csvfile, 'a', encoding='utf-8-sig') as f:
# 设定标题
filename = ['index', '代码', '网址', '简称', '收益']
writer = csv.DictWriter(f, fieldnames=filename)
writer.writeheader()
# 网页实例化
doc = pq(html)
# 获取相应标签下的元素,空格代表子孙节点、class的值写在小数点 . 后面、标签直接写(ID是写在#后面)
items = doc(
'html body div.mainFrame div.dbtable table#dbtable tbody tr ').items()
for item in items:
list = []
infors = item.find('td').items()
for i, infor in enumerate(infors):
if i == 1 or i == 2 or i == 3 or i == 17:
list.append(str(infor.text().strip()))
if i == 2:
href = infor.find('a').attr('href')
# write(href)
list.append(href)
print(list)
print(len(list))
writer = csv.writer(f)
writer.writerow(list)
if __name__ == "__main__":
# 获得2019-2020年基金收益情况
url_oneyear = 'http://fund.eastmoney.com/data/fundranking.html#tall;c0;r;s6yzf;pn10000;ddesc;qsd20191231;qed20201231;qdii;zq;gg;gzbd;gzfs;bbzt;sfbb'
html_oneyear = gethtml(url_oneyear)
getinformation(html_oneyear, 'Fund_19-20_oneyear.csv')
# 获得2018-2020年基金收益情况
url_twoyear = 'http://fund.eastmoney.com/data/fundranking.html#tall;c0;r;s6yzf;pn10000;ddesc;qsd20181231;qed20201231;qdii;zq;gg;gzbd;gzfs;bbzt;sfbb'
html_twoyear = gethtml(url_twoyear)
getinformation(html_twoyear, 'Fund_19-20_twoyear.csv')
# 获得2017-2020年基金收益情况
url_threeyear = 'http://fund.eastmoney.com/data/fundranking.html#tall;c0;r;s6yzf;pn10000;ddesc;qsd20171231;qed20201231;qdii;zq;gg;gzbd;gzfs;bbzt;sfbb'
html_threeyear = gethtml(url_threeyear)
getinformation(html_threeyear, 'Fund_19-20_threeyear.csv')
我们将所得到的三个文件进行整合,可得到以下结果如下图:
二、基金的基金经理和基金公司
判断基金的发展潜力,需要了解其基金经理和基金公司的相关信息。
首先我们对每个基金的基金经理和基金公司进行爬取,代码如下:
import csv
from time import sleep
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, StaleElementReferenceException
import pandas as pd
import numpy
from selenium.webdriver.common.by import By
stand_num = []
company_name = []
manager_name = []
manager_gain = []
if __name__ == "__main__":
with open(r'Fund_19-20_oneyear.csv', 'rt', encoding='ISO-8859-1') as rfile:
reader = csv.reader(rfile)
col = [row[1] for row in reader]
for i in col:
s = str(i)
num = i.zfill(6)
stand_num.append(num)
print(stand_num)
rfile.close()
browser = webdriver.Chrome()
n = 0
for i in stand_num:
n = n+1
if n > 3:
break
browser = webdriver.Chrome()
# browser.get('http://fund.eastmoney.com/005669.html')
# http://fund.eastmoney.com/005669.html
browser.get('http://fund.eastmoney.com/' + i + '.html')
# sleep(1)
manager = browser.find_element(By.XPATH, '//*[@id="body"]/div[11]/div/div/div[3]/div[1]/div[2]/table/tbody/tr[1]/td[3]/a')
company = browser.find_element(By.XPATH, '//*[@id="body"]/div[11]/div/div/div[3]/div[1]/div[2]/table/tbody/tr[2]/td[2]/a')
if manager.text is not None:
manager_name.append(manager.text)
else:
manager_name.append("None")
if company.text is not None:
company_name.append(company.text)
else:
company_name.append("None")
print(manager.text+" "+company.text)
with open('Fund_manager.csv', 'a', encoding='utf-8-sig') as f:
# 设定标题
filename = ['company', 'manager_name']
writer = csv.DictWriter(f, fieldnames=filename)
writer.writeheader()
for c, n, in company_name, manager_name:
list = []
list.append(c)
list.append(n)
writer = csv.writer(f)
writer.writerow(list)
获得Fund_manager.csv文档后,可将此文档与上面所获得的Fund_2020.csv进行整合。
到此为止,我们的获得了每个基金的基金经理和基金公司的信息,接下来我们将文字信息转化为计算机可处理的数字信息,处理策略如下:
我们通过天天基金网,可以看到基金公司和基金经理(我们按照基金经理现任基金资产总规模进行排名)的排名情况。目前有187家基金公司在排行榜上,所以我们定义排名在top50的公司为优质基金公司。若某基金的基金的基金公司为优质基金公司,那么我们将其基金公司用1/(排行榜名次)来表示,否则用0表示。目前大约有2900名基金经理存在于基金网的排行榜上,所我们定义排名在top150的基金经理为优质经理。若某基金的基金的基金经理为优质经理,那么我们将其基金经理用1/(排行榜名次)来表示,否则用0表示。数据处理代码如下:
在这里插入代码片
ps:对数据进行清洗,去除空值、无效值后数据由10000–>6657