如何批量获取年报中数据?
10 个回答
其实上市公司的年报都是免费的,也有很多网站进行了整理,尤其是对于报表,可以批量获取。
一、完整版年报获取方式
通常上市公司会在每年的4月份左右发布上年年报,在该公司的网站上会有下载链接,这是最权威的年报获取手段。
比如安琪酵母:
打开其官方网站,能够看到“投资者关系”一栏,里面就是放的各种公告,包括历年财报。
这里其实是一个PDF的下载链接,使用下载工具下载即可。
如果大量分析年报的话,这样的下载方式略显繁琐。
绝大多数证券网站都做了搜集整理,可以方便的查找下载,比如新浪股票、网易财经、腾讯证券。
我习惯使用腾讯证券,地址在此:http://gu.qq.com/sh600291/gp/jbnb/nos1203336037
敲入股票代码或者简写,就可以下载PDF格式的年报。
二、数字版报表下载方式
通过上文的方式下载的年报,动辄一二百页,对于深度分析某个公司基本面是有帮助的,但很多时候我们只是想了解一下连续几年来的某个项目变动情况,F10里不全,PDF一个个看起来会累瞎眼,那怎么办呢?
有两种方式,一种是高昂的国泰安数据库、Wind客户端等专业软件,内置了年报资料,另一种是一些免费的网站,提供了Excel格式的下载链接。
比如网易财经。
http://quotes.money.163.com/service/zcfzb_600001.html (股票代码为600001的资产负债表)
http://quotes.money.163.com/service/lrb_600001.html (股票代码为600001的利润表)
http://quotes.money.163.com/service/xjllb_600001.html (股票代码为600001的现金流量表)
下载的都是格式为csv的Excel表格,为该公司上市以来所有报表。替换掉代码即可下载你想要的公司的报表。
报表格式如下:
可见利用这些数据进行历年分析是非常简单的。
三、一点点编程代码,批量下载和处理
对于财经数据分析,Python提供了非常友好的处理模式,不过因为我当时在学Ruby,就写了一段Ruby代码下载。
作为初学者,很多代码优化学得不好,在编程高手们面前,这段代码有点献丑了。不过幸亏我脸皮厚,既然许多朋友咨询,我就恬不知耻的放上来了。
# -*- coding: UTF-8 -*-
require 'rubygems'
require 'hpricot'
require 'open-uri'
################################本程序实现财务指定股票上市以来全部财务报表的下载
x = 0
#获取股票列表文件stocklist.txt的总行数
def wc(filename)
$nline = $nword = $nchar = 0 #$符号表示全局变量,普通变量不在def外起作用
File.open(filename) do |io|
io.each_line do |line|
words = line.split(/\s+/).reject{|w| w.empty? }
#本例中使用了split方法分割单词,当行首有空白字符时,split方法的执行结果中会产生空白字符串,因此我们
#会删除该空白字符串。
$nline += 1
$nword += words.length
$nchar += line.length
end
end
#puts "文件的行数为:#{$nline}\n文件的单词数为:#{$nword}\n文件的字符数为:#{$nchar}"
puts "股票池股票数:#{$nword}\n"
end
wc("d:/rb/stock/downreports/stocklist.txt")
#puts $nword
#循环开始
while x <= $nword - 1
#puts "轮询中:"
stock_lines = File.readlines("d:/rb/stock/downreports/stocklist.txt");
s_code = stock_lines[x]
scode = s_code.chomp # chomp用来删除文本里带过来的换行符
puts "====================="
puts "正在下载#{scode}的资产负债表,共计#{$nword}只,当前第#{x}只。"
#确定csv文件命名规则
file1_path = "d:\\stock\\zcfzb\\"
file1_name = scode + "zcfzb.csv"
file1_name_path = file1_path + file1_name
#将网易财经接口的数据保存为csv文件
File.open(file1_name_path, 'wb') {|f| f.write(open('http://quotes.money.163.com/service/zcfzb_' + "#{scode}"+'.html') {|f1| f1.read})}
#防止接口调用过频被踢,暂停3秒
sleep(3)
puts "资产负债表下载完毕"
puts "====================="
puts "正在下载#{scode}的利润表"
#确定csv文件命名规则
file2_path = "d:\\stock\\lrb\\"
file2_name = scode + "lrb.csv"
file2_name_path = file2_path + file2_name
#将网易财经接口的数据保存为csv文件
File.open(file2_name_path, 'wb') {|f| f.write(open('http://quotes.money.163.com/service/lrb_' + "#{scode}"+'.html') {|f1| f1.read})}
#防止接口调用过频被踢,暂停3秒
sleep(3)
puts "利润表下载完毕"
puts "====================="
puts "正在下载#{scode}的现金流量表"
#确定csv文件命名规则
file3_path = "d:\\stock\\xjllb\\"
file3_name = scode + "xjllb.csv"
file3_name_path = file3_path + file3_name
#将网易财经接口的数据保存为csv文件
File.open(file3_name_path, 'wb') {|f| f.write(open('http://quotes.money.163.com/service/xjllb_' + "#{scode}"+'.html') {|f1| f1.read})}
#防止接口调用过频被踢,暂停3秒
sleep(3)
puts "现金流量表下载完毕"
puts "====================="
puts "正在下载#{scode}的主要财务指标表"
#确定csv文件命名规则
file4_path = "d:\\stock\\zycwzb\\"
file4_name = scode + "zycwzb.csv"
file4_name_path = file4_path + file4_name
#将网易财经接口的数据保存为csv文件
File.open(file4_name_path, 'wb') {|f| f.write(open('http://quotes.money.163.com/service/zycwzb_' + "#{scode}"+'.html') {|f1| f1.read})}
#防止接口调用过频被踢,暂停3秒
sleep(3)
puts "主要财务指标表下载完毕"
x = x + 1
end
本段代码的核心就是这一行了:
f.write(open('http://quotes.money.163.com/service/zcfzb_' + "#{scode}"+'.html') {|f1| f1.read})}
学过一丁点代码的,应该一看就明白了。此处虽然用的Ruby,你换Python也很容易。
下载完毕后,还是很壮观的:
有了这些基础数据,你就可以随意分析任意上市公司的历年财报了。
和国泰安数据库、Wind数据相比,起码省了几万块,还不赶快去加个鸡腿?
题主问题不清晰,简单的回答一下思路,最关键的点在于:程序只能按照你的思路做机械的批量化的操作,如果整个过程中有只有人能够识别操作的行为(比如年报地址分散得找,年报格式不统一得去识别等),那你就只能手工去做了。如果其中有重复的模式,那可以考虑编程解决。
- 年报已经有了文件,还是得去找?
- 如果没有,得去下载的话,有没有有规律的可以机械化处理的方式(比如某个网站你提供名称就能下载到)?没有的话请放弃。
如果你能够描述出来怎样用固定的步骤解决这个问题,那你可以考虑找个懂编程的人来解决。如果自己都说不清怎么操作,那就别浪费时间了,自己慢慢干吧。