@[toc]
1. 获取券商研报网站的表格数据
和讯研报网是和讯网旗下专注于披露券商分析师研究报告信息的网站。
和讯研报网将延保分为不同的种类,如目标涨幅最大股、机构强烈推荐股等,这里以券商评级调升股为例进行相关数据的获取和分析。
网址:http://yanbao.stock.hexun.com/ybsj5.shtml
1.1 表格数据的常规获取方法
这里分两种情况来介绍:第一种是文件形式的表格数据,如世界银行的项目表格数据;第二种是网页形式的表格数据,如新浪财经的大宗交易表格数据。
- 文件形式的表格数据——世界银行项目表
在浏览器中打开世界银行项目数据官网(https://datacatalog.worldbank.org/dataset/world-bank-projects-operations),利用F12查看源码,发现存储数据的csv文件的下载链接是固定的,因此我们可以直接采用Requests库访问该下载链接,即可下载csv文件。
import requests
url = 'https://search.worldbank.org/api/projects/all.csv'
res = requests.get(url)
file = open('data.csv', 'wb')
file.write(res.content)
file.close()
- 网页形式的表格数据——新浪财经大宗交易表
表格直接呈现在网页上,如下图所示为新浪财经数据中心提供的大宗交易的表格数据。网址为:http://vip.stock.finance.sina.com.cn/q/go.php/vInvestConsult/kind/dzjy/index.phtml大宗交易针对的是一笔数额较大的股票或债券交易,有时可以透露出较强的交易信号。
这里通过pandas库即可获取网页中的表格。
url = 'http://vip.stock.finance.sina.com.cn/q/go.php/vInvestConsult/kind/dzjy/index.phtml'
table = pd.read_html(url)[0]
table.to_excel('大宗交易表.xlsx', index=False)
1.2 用Selenium库爬取和讯研报网表格数据
对于和讯研报网的表格数据,如果使用pd.read_html()方式解析,会被网站拒绝访问,因此这里采用Selenium库来访问网页并获取网页源代码,然后使用pd.read_html()函数进行解析。
chrome_option = webdriver.ChromeOptions()
chrome_option.add_argument('--headless')
browser = webdriver.Chrome(options=chrome_option)
url = 'http://yanbao.stock.hexun.com/ybsj5.shtml'
browser.get(url)
data = browser.page_source
table = pd.read_html(data)[0]
通过上面的操作已经获得了比较全面的评级数据,但为了便于后面获取股票信息,这里需要对股票代码信息进行补充,通过F12查看网页源码发现,源码中包含有股票代码信息,可通过编写正则化规则实现。
code_pattern = '<a href="yb_(.*?).shtml'
code = re.findall(code_pattern, data)
table['股票代码'] = code
如果想获取所有页的表格数据,可通过for循环语句来实现。
chrome_option = webdriver.ChromeOptions()
chrome_option.add_argument('--headless')
browser = webdriver.Chrome(options=chrome_option)
data_all = pd.DataFrame()
for pg in range(1, 90):
url = 'http://yanbao.stock.hexun.com/ybsj5_'+ str(pg) +'.shtml'
browser.get(url)
data = browser.page_source
table = pd.read_html(data)[0]
code_pattern = '<a href="yb_(.*?).shtml'
code = re.findall(code_pattern, data)
table['股票代码'] = code
data_all = pd.concat([data_all, table], ignore_index=True)
data_all.to_excel('分析师评级报告.xlsx', index=False)
2. 评估券商分析师预测准确度
2.1 读取分析师评级报告数据进行数据预处理
# 代码为数字,如果直接读进来,那么以0开头的代码会省略掉0
df = pd.read_excel('分析师评级报告.xlsx', dtype={'股票代码': str})
# 删除重复行和空行
df = df.drop_duplicates()
df = df.dropna(thresh=5) # 如果该行的非空值少于5个,则删除
# 连接‘研究机构’列和‘分析师’列
df['研究机构-分析师'] = df.apply(lambda x: x['研究机构'] + '-' + x['分析师'], axis=1)
# 选取需要的列
columns = ['股票名称', '股票代码', '研究机构-分析师', '最新评级', '评级调整', '报告日期']
df = df[columns]
# 筛选日期:预测之后30天内的股票涨跌幅作为判断标准,所以这里需要将距离当前日期不足30天的数据剔除
today = datetime.datetime.now()
t = today - datetime.timedelta(days=30)
t = t.strftime('%Y-%m-%d')
df = df[df['报告日期'] < t]
2.2 用Tushare库计算股票收益率
def calculate_rate(df_use):
rate = [] # 创建一个空列表,用来存储每只股票的收益率
for i, row in df_use.iterrows():
code = row['股票代码']
analysist_date = row['报告日期']
# 推算开始日,即第二天
begin_date = datetime.datetime.strptime(analysist_date, '%Y-%m-%d') #转化成datetime.datetime格式
begin_date = begin_date + datetime.timedelta(days=1)
begin_date = begin_date.strftime('%Y-%m-%d') # 转化成字符串格式
# 推算结束日,即第30天
end_date = datetime.datetime.strptime(analysist_date, '%Y-%m-%d')
end_date = end_date + datetime.timedelta(days=30)
end_date = end_date.strftime('%Y-%m-%d')
# 通过Tushare库计算股票收益率
ts_result = ts.get_hist_data(code, begin_date, end_date)
if ts_result is None or len(ts_result)<5: # 防止无数据或数据较少
return_rate = 0
else:
start_price = ts_result.iloc[-1]['open']
end_price = ts_result.iloc[0]['close']
return_rate = (end_price / start_price) - 1.0
print('收益率:{}'.format(return_rate))
rate.append(return_rate)
return rate
主函数调用:
df_use = df.iloc[0:100] # 取一部分数据
df_use['30天收益率'] = calculate_rate(df_use)
for i, row in df_use.iterrows():
print(i)
print(row)
df_use.to_excel('30天收益率.xlsx')
2.3 计算平均收益率并进行分析师预测准确度排名
接下来计算各个分析师所推荐股票的30天平均收益率及分析师的预测次数,并对分析师的预测准确度进行排名。
df = pd.read_excel('30天收益率.xlsx')
means = df.groupby('研究机构-分析师')[['30天收益率']].mean()
count = df.groupby('研究机构-分析师')[['30天收益率']].mean()
count = count.rename(columns={'30天收益率':'预测次数'})
df_final = pd.concat([means, count], axis=1)
df_final.sort_values(by='30天收益率', ascending=False, inplace=True)
df_final.to_excel('分析师预测结果.xlsx')