TuShare1.2.18中源码分析


今天,我们来分析下TuShare中的源码,TuShare源码的入口是__init__.py文件,我们从这个文件开始分析,找到获取个股历史交易记录并进行分析。

1、入口

# -*- coding:utf-8 -*- 
import codecs
import os

__version__ = codecs.open(os.path.join(os.path.dirname(__file__), 'VERSION.txt')).read()
__author__ = 'Jimmy Liu'

上面的代码是TuShare的版本和作者

2、个股交易数据

"""
for trading data
"""
from tushare.stock.trading import (get_hist_data, get_tick_data,
                                   get_today_all, get_realtime_quotes,
                                   get_h_data, get_today_ticks,
                                   get_index, get_hists,
                                   get_k_data, get_day_all,
                                   get_sina_dd, bar, tick,
                                   get_markets, quotes,
                                   get_instrument, reset_instrument)

上面代码说明TuShare的16个交易数据API是从stock下的trading模块打包出来的。
我们打开源码stock目录下的trading.py文件,先分析trading.py的依赖项

from __future__ import division

import time
import json
import lxml.html
from lxml import etree
import pandas as pd
import numpy as np
import datetime
from tushare.stock import cons as ct	# 引入cons.py,包含股票相关常量定义
import re
from pandas.compat import StringIO
from tushare.util import dateu as du	# 引入dateu.py,日期、交易日历的处理
from tushare.util.formula import MA		# 引入formula.py,包含股票常用指标
import os
from tushare.util.conns import get_apis, close_apis		# 引入conns.py,连接爬取外部数据的API
from tushare.stock.fundamental import get_stock_basics	# 引入fundamental.py,包含基本面数据接口 
try:
    from urllib.request import urlopen, Request
except ImportError:
    from urllib2 import urlopen, Request

我们可以看出,引入了5个模块:cons.py包含股票相关常量定义,dateu.py包含对日期、交易日历的处理,formula.py包含股票常用指标,conns.py包含连接爬取外部数据的API,fundamental.py包含基本面数据接口 。

2.1、API:获取凤凰财经个股历史交易记录


def get_hist_data(code=None, start=None, end=None,
                  ktype='D', retry_count=3,
                  pause=0.001):

代码中有获取个股历史交易记录API的详细说明:

    """
        获取个股历史交易记录
    Parameters
    ------
      code:string
                  股票代码 e.g. 600848
      start:string
                  开始日期 format:YYYY-MM-DD 为空时取到API所提供的最早日期数据
      end:string
                  结束日期 format:YYYY-MM-DD 为空时取到最近一个交易日数据
      ktype:string
                  数据类型,D=日k线 W=M=5=5分钟 15=15分钟 30=30分钟 60=60分钟,默认为D
      retry_count : int, 默认 3
                 如遇网络等问题重复执行的次数 
      pause : int, 默认 0
                重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题
    return
    -------
      DataFrame
          属性:日期 ,开盘价, 最高价, 收盘价, 最低价, 成交量, 价格变动 ,涨跌幅,5日均价,10日均价,20日均价,5日均量,10日均量,20日均量,换手率
    """
参数缺省值说明
ktype‘D’表示数据类型缺省是日线
retry_count3表示爬取外部数据请求时最多尝试3次
pause0.001表示多次尝试爬取请求过程中暂停0.001秒
    symbol = ct._code_to_symbol(code)

我们在cons.py中找到_code_to_symbol

def _code_to_symbol(code):
    '''
        生成symbol代码标志
    '''
    if code in INDEX_LABELS:
        return INDEX_LIST[code]
    elif code[:3] == 'gb_':
        return code
    else:
        if len(code) != 6 :	# 如果输入的不是一个6位数的股票代码
            return code		# 直接返回代码
        else:
            return 'sh%s'%code if code[:1] in ['5', '6', '9'] or code[:2] in ['11', '13'] else 'sz%s'%code	
            # 输入的是一个6位数的股票代码,代码前1位是569,或者前2位是1113,是上证股票代码,
            # 否则是深证股票代码,返回带市场的股票代码

_code_to_symbol主要是对输入的股票代码进行判断,然后格式化成股票代码的标准格式,例如:sh600000

代码cons.py中对应内容说明
return INDEX_LIST[code]INDEX_LABELS = [‘sh’, ‘sz’, ‘hs300’, ‘sz50’, ‘cyb’, ‘zxb’, ‘zx300’, ‘zh500’] \n INDEX_LIST = {‘sh’: ‘sh000001’, ‘sz’: ‘sz399001’, ‘hs300’: ‘sh000300’,‘sz50’: ‘sh000016’, ‘zxb’: ‘sz399005’, ‘cyb’: ‘sz399006’, ‘zx300’: ‘sz399008’, ‘zh500’:‘sh000905’}根据缩写指标代码返回指标对应的完整指标代码
    url = ''
    if ktype.upper() in ct.K_LABELS:
        url = ct.DAY_PRICE_URL%(ct.P_TYPE['http'], ct.DOMAINS['ifeng'],
                                ct.K_TYPE[ktype.upper()], symbol)
        # 拼装日线对应凤凰网数据请求API的url
代码cons.py中对应内容说明
ct.K_LABELSK_LABELS = [‘D’, ‘W’, ‘M’]数据类型,D:日线,W:周线,M:月线
ct.DAY_PRICE_URLDAY_PRICE_URL = ‘%sapi.finance.%s/%s/?code=%s&type=last’凤凰网获取日线的URL
ct.P_TYPE[‘http’]-P_TYPE = {‘http’: ‘http://’, ‘ftp’: ‘ftp://’}-http请求类型
ct.DOMAINS[‘ifeng’]-‘ifeng’: ‘ifeng.com’-数据来源凤凰
ct.K_TYPEK_TYPE = {‘D’: ‘akdaily’, ‘W’: ‘akweekly’, ‘M’: ‘akmonthly’}数据类型和凤凰网对应的数据类型,D:日线,W:周线,M:月线
    elif ktype in ct.K_MIN_LABELS:
        url = ct.DAY_PRICE_MIN_URL%(ct.P_TYPE['http'], ct.DOMAINS['ifeng'],
                                    symbol, ktype)
		# 拼装分钟线对应凤凰网数据请求API的url
    else:
        raise TypeError('ktype input error.')
代码cons.py中对应内容说明
ct.K_MIN_LABELSK_MIN_LABELS = [‘5’, ‘15’, ‘30’, ‘60’]分钟线:5分钟线、15分钟线、30分钟线、小时线
ct.DAY_PRICE_MIN_URLDAY_PRICE_MIN_URL = ‘%sapi.finance.%s/akmin?scode=%s&type=%s’凤凰网获取分钟线的URL
ct.P_TYPE[‘http’]-P_TYPE = {‘http’: ‘http://’, ‘ftp’: ‘ftp://’}-http请求类型
ct.DOMAINS[‘ifeng’]-‘ifeng’: ‘ifeng.com’-数据来源凤凰财经
ct.K_TYPEK_TYPE = {‘D’: ‘akdaily’, ‘W’: ‘akweekly’, ‘M’: ‘akmonthly’}数据类型,D:日线,W:周线,M:月线

我们在这里给出两上请求凤凰网数据的示例,
a、请求上海证券交易所600000浦发银行的日线数据对应的URL:

http://api.finance.ifeng.com/akdaily/?code=sh600000&type=last

在这里插入图片描述

b、请求上海证券交易所600000浦发银行的周线数据对应的URL:

http://api.finance.ifeng.com/akweekly/?code=sh600000&type=last

在这里插入图片描述
c、请求一个不个不存在的股票数据,返回空数据

http://api.finance.ifeng.com/akdaily/?code=sh69999&type=last

返回内容为13个字节的空记录内容

{"record":{}}

在这里,我们展开说一下,我们可以通过凤凰财经的页面来分析爬取数据的URL,我们以浦发银行sh600000为例,打开浦发银行的行情页面:

http://finance.ifeng.com/app/hq/stock/sh600000/

在这里插入图片描述
按F12打开开发者工具,切换到Network页面,在行情页面点击日k、周k、月k、15分、30分等进行数据类型切换,在Network页面查看请求的变化,分析对应的请求,我们就可以找到数据请求的API。
在这里插入图片描述

    for _ in range(retry_count):	# 尝试爬取retry_count次
        time.sleep(pause)			# 休眠pause秒
        try:
            request = Request(url)	# 请求打开URL页面
            lines = urlopen(request, timeout = 10).read()	# 保存返回页面内容到lines中
            if len(lines) < 15: # 根据返回内容的长度来判断是否有数据,空数据返回{"record":{}}
                return None
        except Exception as e:
            print(e)			# 如果出现异常,打印异常信息
        else:

凤凰财经返回的数据是JSON格式,下面代码是对爬取数据的处理

            js = json.loads(lines.decode('utf-8') if ct.PY3 else lines)
            cols = []
            if (code in ct.INDEX_LABELS) & (ktype.upper() in ct.K_LABELS):
                cols = ct.INX_DAY_PRICE_COLUMNS
            else:
                cols = ct.DAY_PRICE_COLUMNS
            if len(js['record'][0]) == 14:	# 如果第列是14个元素,代表是指标数据
                cols = ct.INX_DAY_PRICE_COLUMNS
            # 根据行记录数据创建DataFrame对象
            df = pd.DataFrame(js['record'], columns=cols)
            if ktype.upper() in ['D', 'W', 'M']:
                df = df.applymap(lambda x: x.replace(u',', u''))
                df[df==''] = 0
            for col in cols[1:]:
                df[col] = df[col].astype(float)	# 进行类型转换
            if start is not None:
                df = df[df.date >= start]		# 保留开始时间之后的数据
            if end is not None:
                df = df[df.date <= end]			# 保留结束时间之前的数据
            if (code in ct.INDEX_LABELS) & (ktype in ct.K_MIN_LABELS):
                df = df.drop('turnover', axis=1)
            df = df.set_index('date')			# 按date字段设置索引
            df = df.sort_index(ascending = False)	# 按索引进行排序
            return df
    raise IOError(ct.NETWORK_URL_ERROR_MSG)
代码cons.py中对应内容说明
ct.INDEX_LABELSINDEX_LABELS = [‘sh’, ‘sz’, ‘hs300’, ‘sz50’, ‘cyb’, ‘zxb’, ‘zx300’, ‘zh500’]凤凰财经对应的指数代码
ct.INX_DAY_PRICE_COLUMNSINX_DAY_PRICE_COLUMNS = [‘date’, ‘open’, ‘high’, ‘close’, ‘low’, ‘volume’, ‘price_change’, ‘p_change’,‘ma5’, ‘ma10’, ‘ma20’, ‘v_ma5’, ‘v_ma10’, ‘v_ma20’]指标日线数据每列的元素
ct.DAY_PRICE_COLUMNSDAY_PRICE_COLUMNS = [‘date’, ‘open’, ‘high’, ‘close’, ‘low’, ‘volume’, ‘price_change’, ‘p_change’,‘ma5’, ‘ma10’, ‘ma20’, ‘v_ma5’, ‘v_ma10’, ‘v_ma20’, ‘turnover’]股票日线数据每列的元素

2.2、API:获取分笔数据

def get_tick_data(code=None, date=None, retry_count=3, pause=0.001,
                  src='sn'):

代码中有获取分笔数据API的详细说明:

    """
        获取分笔数据
    Parameters
    ------
        code:string
                  股票代码 e.g. 600848
        date:string
                  日期 format: YYYY-MM-DD
        retry_count : int, 默认 3
                  如遇网络等问题重复执行的次数
        pause : int, 默认 0
                 重复请求数据过程中暂停的秒数,防止请求间隔时间太短出现的问题
        src : 数据源选择,可输入sn(新浪)、tt(腾讯)、nt(网易),默认sn
     return
     -------
        DataFrame 当日所有股票交易数据(DataFrame)
              属性:成交时间、成交价格、价格变动,成交手、成交金额(),买卖类型
    """
参数缺省值说明
retry_count3表示爬取外部数据请求时最多尝试3次
pause0.001表示多次尝试爬取请求过程中暂停0.001秒
src‘sn’表示数据源选择新浪
    if (src.strip() not in ct.TICK_SRCS):
        print(ct.TICK_SRC_ERROR)
        return None				# 非法数据源,返回None
    symbol = ct._code_to_symbol(code)	# 根据code获取symbol代码
    symbol_dgt = ct._code_to_symbol_dgt(code)	# 根据code获取symbol_dgt代码
    datestr = date.replace('-', '')		# 日期YYYY-MM-DD格式调整至YYYYMMDD格式
代码cons.py中对应内容说明
ct.TICK_SRCSTICK_SRCS = [‘sn’, ‘tt’, ‘nt’]分笔数据源,sn(新浪)、tt(腾讯)、nt(网易)
ct.INX_DAY_PRICE_COLUMNSINX_DAY_PRICE_COLUMNS = [‘date’, ‘open’, ‘high’, ‘close’, ‘low’, ‘volume’, ‘price_change’, ‘p_change’,‘ma5’, ‘ma10’, ‘ma20’, ‘v_ma5’, ‘v_ma10’, ‘v_ma20’]指标日线数据每列的元素
ct.DAY_PRICE_COLUMNSDAY_PRICE_COLUMNS = [‘date’, ‘open’, ‘high’, ‘close’, ‘low’, ‘volume’, ‘price_change’, ‘p_change’,‘ma5’, ‘ma10’, ‘ma20’, ‘v_ma5’, ‘v_ma10’, ‘v_ma20’, ‘turnover’]股票日线数据每列的元素
    url = {
            ct.TICK_SRCS[0] : ct.TICK_PRICE_URL % (ct.P_TYPE['http'], ct.DOMAINS['sf'], ct.PAGES['dl'],
                                date, symbol),
            ct.TICK_SRCS[1] : ct.TICK_PRICE_URL_TT % (ct.P_TYPE['http'], ct.DOMAINS['tt'], ct.PAGES['idx'],
                                           symbol, datestr),
            ct.TICK_SRCS[2] : ct.TICK_PRICE_URL_NT % (ct.P_TYPE['http'], ct.DOMAINS['163'], date[0:4], 
                                         datestr, symbol_dgt)
             }
             # 拼装分笔数据请求的URL
代码cons.py中对应内容说明
ct.TICK_PRICE_URLTICK_PRICE_URL = ‘%smarket.%s/%s?date=%s&symbol=%s’新浪分笔数据请求
ct.DOMAINS[‘sf’]‘sf’: ‘finance.sina.com.cn’数据来源新浪
ct.PAGES[‘dl’]‘dl’: ‘downxls.php’数据来源页面
ct.TICK_PRICE_URL_TTTICK_PRICE_URL_TT = ‘%sstock.%s/data/%s?appn=detail&action=download&c=%s&d=%s’腾讯分笔数据请求
ct.DOMAINS[‘tt’]‘tt’: ‘gtimg.cn’数据来源腾讯
ct.PAGES[‘idx’]‘idx’: ‘index.php’数据来源页面
ct.TICK_PRICE_URL_NTTICK_PRICE_URL_NT = ‘%squotes.%s/cjmx/%s/%s/%s.xls’网易分笔数据请求
ct.DOMAINS[‘163’]‘163’: ‘money.163.com’数据来源网易

新浪分笔数据请求示例:

http://market.finance.sina.com.cn/downxls.php?date=20200826&symbol=sh600000

服务已经下线,可惜。
在这里插入图片描述
腾讯分笔数据请求示例:

http://stock.gtimg.cn/data/index.php?appn=detail&action=download&c=sh600000&d=20200826

请求的Excel数据如下:
在这里插入图片描述

网易分笔数据请求示例:

http://quotes.money.163.com/cjmx/2020/20200826/0600000.xls

说明:

http://quotes.money.163.com/cjmx/[今年年份]/[日期]/[股票代码].xls
返回结果:获取历史成交明细XLS文件。
注意,只能获取5日内的数据,之前的数据不会存在。
注意,该方法为网易公开获取数据方法,推荐使用。

在这里插入图片描述
下面代码是对爬取数据的处理

    for _ in range(retry_count):	# 尝试爬取retry_count次
        time.sleep(pause)			# 休眠pause秒
        try:
            if src == ct.TICK_SRCS[2]:
                df = pd.read_excel(url[src])	# 操作读取excel文件
                df.columns = ct.TICK_COLUMNS
            else:
                re = Request(url[src])		# 请求打开URL页面
                lines = urlopen(re, timeout=10).read()	# 保存返回页面内容到lines中
                lines = lines.decode('GBK') 
                if len(lines) < 20:
                    return None
                df = pd.read_table(StringIO(lines), names=ct.TICK_COLUMNS,
                                   skiprows=[0])      
        except Exception as e:
            print(e)
        else:
            return df
    raise IOError(ct.NETWORK_URL_ERROR_MSG)

3、基本面数据

"""
for trading data
"""
from tushare.stock.fundamental import (get_stock_basics, get_report_data,
                                       get_profit_data,
                                       get_operation_data, get_growth_data,
                                       get_debtpaying_data, get_cashflow_data,
                                       get_balance_sheet, get_profit_statement, get_cash_flow)

上面代码说明TuShare的10个基本面数据API是从stock下的fundamental模块打包出来的。
我们打开源码stock目录下的fundamental.py文件,先分析fundamental.py的依赖项

import pandas as pd
from tushare.stock import cons as ct	# 引入cons.py,包含股票相关常量定义
import lxml.html
from lxml import etree
import re
import time
from pandas.compat import StringIO
from tushare.util import dateu as du	# 引入dateu.py,日期、交易日历的处理
try:
    from urllib.request import urlopen, Request
except ImportError:
    from urllib2 import urlopen, Request

3.1、API:获取沪深上市公司基本情况

def get_stock_basics(date=None):

代码中有获取获取沪深上市公司基本情况API的详细说明:

"""
        获取沪深上市公司基本情况
    Parameters
    date:日期YYYY-MM-DD,默认为上一个交易日,目前只能提供2016-08-09之后的历史数据

    Return
    --------
    DataFrame
               code,代码
               name,名称
               industry,细分行业
               area,地区
               pe,市盈率
               outstanding,流通股本
               totals,总股本()
               totalAssets,总资产()
               liquidAssets,流动资产
               fixedAssets,固定资产
               reserved,公积金
               reservedPerShare,每股公积金
               eps,每股收益
               bvps,每股净资
               pb,市净率
               timeToMarket,上市日期
    """
    wdate = du.last_tddate() if date is None else date	# 获取最后一个交易日
    wdate = wdate.replace('-', '')						# 日期YYYY-MM-DD格式调整至YYYYMMDD格式
    if wdate < '20160809':
        return None				// 2016年8月9日之前没有数据
  	# 获取日期前缀,格式如:'201608/'
    datepre = '' if date is None else wdate[0:4] + wdate[4:6] + '/'
    # 拼接URL并Request
    request = Request(ct.ALL_STOCK_BASICS_FILE%(datepre, '' if date is None else wdate))
    text = urlopen(request, timeout=10).read()	# 保存返回的内容到text中
    text = text.decode('GBK')
    text = text.replace('--', '')
    df = pd.read_csv(StringIO(text), dtype={'code':'object'})	# 读取vsv文件
    df = df.set_index('code')		# 设置code字段为索引
    return df

我们在dateu.py中找到last_tddate,这个函数用于获取最后一个交易日

def last_tddate():
    today = datetime.datetime.today().date()	# 获取当天的日期
    today=int(today.strftime("%w"))				# %w 星期(0-6),获取当天是星期几
    if today == 0:
        return day_last_week(-2)				# 周日,返回上这个星期的两一天的日期(周五)
    else:
        return day_last_week(-1)				# 非周日,返回上这个星期的上一天的日期
        

我们在dateu.py中找到day_last_week,这个函数用于获取最后一个星期第几天的日期

def day_last_week(days=-7):
    lasty = datetime.datetime.today().date() + datetime.timedelta(days)
    return str(lasty)
代码cons.py中对应内容说明
ct.ALL_STOCK_BASICS_FILEALL_STOCK_BASICS_FILE = P_TYPE[‘http’] + DOMAINS[‘oss’] + ‘/tsdata/%sall%s.csv’Tushare财经数据包拼接URL格式
DOMAINS[‘oss’]‘oss’: ‘file.tushare.org’Tushare财经数据包

示例,获取2020年8月26日的沪深上市公司基本情况:

http://file.tushare.org/tsdata/202008/all20200826.csv

返回csv结果文件如下:
在这里插入图片描述

3.2、API:获取业绩报表数据

我们打开源码stock目录下的fundamental.py文件,找到获取业绩报表数据API函数get_report_data

def get_report_data(year, quarter):

代码中有获取业绩报表数据API的详细说明:

    """
        获取业绩报表数据
    Parameters
    --------
    year:int 年度 e.g:2014
    quarter:int 季度 :1234,只能输入这4个季度
       说明:由于是从网站获取的数据,需要一页页抓取,速度取决于您当前网络速度
       
    Return
    --------
    DataFrame
        code,代码
        name,名称
        eps,每股收益
        eps_yoy,每股收益同比(%)
        bvps,每股净资产
        roe,净资产收益率(%)
        epcf,每股现金流量()
        net_profits,净利润(万元)
        profits_yoy,净利润同比(%)
        distrib,分配方案
        report_date,发布日期
    """
    if ct._check_input(year,quarter) is True:	# 检查输入的年度、季度是否准确
        ct._write_head()
        df =  _get_report_data(year, quarter, 1, pd.DataFrame())
        if df is not None:
#             df = df.drop_duplicates('code')
            df['code'] = df['code'].map(lambda x:str(x).zfill(6))
        return df

我们在cons.py中找到_check_input,这个函数用于校验输入的年度、季度

def _check_input(year, quarter):
    if isinstance(year, str) or year < 1989 :
        # 年度不是字符串或年小于1989,抛出类型错误异常
        # DATE_CHK_MSG = '年度输入错误:请输入1989年以后的年份数字,格式:YYYY'
        raise TypeError(DATE_CHK_MSG)	
    elif quarter is None or isinstance(quarter, str) or quarter not in [1, 2, 3, 4]:
        # 季度不是字符串或不是1234,抛出类型错误异常
        # DATE_CHK_Q_MSG = '季度输入错误:请输入1、2、3或4数字'
        raise TypeError(DATE_CHK_Q_MSG)
    else:
        return True

我们在cons.py中找到_write_head,这个函数用于写头部标识

def _write_head():
    sys.stdout.write(DATA_GETTING_TIPS)	# DATA_GETTING_TIPS = '[Getting data:]'
    sys.stdout.flush()

我们在fundamental.py中找到_get_report_data,这个函数用于获取业绩报表数据

def _get_report_data(year, quarter, pageNo, dataArr,
                     retry_count=3, pause=0.001):
参数说明
year年度
quarter季度
pageNo分页编码,编号从1开始
retry_count爬取数据重连次数
pause爬取数据重连时睡眠秒数
    ct._write_console()
    for _ in range(retry_count):
        time.sleep(pause)
        try:
	        # 拼接获取业绩报表数据URL并Request
            request = Request(ct.REPORT_URL%(ct.P_TYPE['http'], ct.DOMAINS['vsf'], ct.PAGES['fd'],
                             year, quarter, pageNo, ct.PAGE_NUM[1]))
            text = urlopen(request, timeout=10).read()	# 保存业绩报表数据
            text = text.decode('GBK')
            text = text.replace('--', '')	# 清除<td>--</td>格式数据
            html = lxml.html.parse(StringIO(text))
            # 解析<table class="list_table" id="dataTable">中的数据内容
            res = html.xpath("//table[@class=\"list_table\"]/tr")
            if ct.PY3:
                sarr = [etree.tostring(node).decode('utf-8') for node in res]
            else:
                sarr = [etree.tostring(node) for node in res]
            sarr = ''.join(sarr)
            sarr = '<table>%s</table>'%sarr	# 把list_table中的数据再拼接成一个table
            # 通过read_html直接获取表格数据,得到table表格的list集合。
            df = pd.read_html(sarr)[0]
            df = df.drop(11, axis=1)
            df.columns = ct.REPORT_COLS
            # 把表格数据保存到DataFrame对象dataArr中
            dataArr = dataArr.append(df, ignore_index=True)
            nextPage = html.xpath('//div[@class=\"pages\"]/a[last()]/@onclick')
            if len(nextPage)>0:
                pageNo = re.findall(r'\d+', nextPage[0])[0]	# 通过正则查找下一页的页码
                # 继续获取下一页的业绩报表数据
                return _get_report_data(year, quarter, pageNo, dataArr)
            else:
                return dataArr
        except Exception as e:
            pass
    raise IOError(ct.NETWORK_URL_ERROR_MSG)
代码cons.py中对应内容说明
ct.PORT_URLREPORT_URL = ‘%s%s/q/go.php/vFinanceAnalyze/kind/mainindex/%s?s_i=&s_a=&s_c=&reportdate=%s&quarter=%s&p=%s&num=%s’新浪业绩报表URL格式
ct.DOMAINS[‘vsf’]‘vsf’: ‘vip.stock.finance.sina.com.cn’新浪财经股票数据中心
ct.PAGE_NUM[1]PAGE_NUM = [40, 60, 80, 100]第页包含的数据记录条数

示例,获取2020年1季度的业绩报表数据:

http://vip.stock.finance.sina.com.cn/q/go.php/vFinanceAnalyze/kind/mainindex/2020?s_i=&s_a=&s_c=&reportdate=%s&quarter=1&p=1&num=40

返回结果页面如下:
在这里插入图片描述
我们查看页面源代码,业绩报表数据都在table中
在这里插入图片描述

4、宏观数据

for macro data
"""
from tushare.stock.macro import (get_gdp_year, get_gdp_quarter,
                                 get_gdp_for, get_gdp_pull,
                                 get_gdp_contrib, get_cpi,
                                 get_ppi, get_deposit_rate,
                                 get_loan_rate, get_rrr,
                                 get_money_supply, get_money_supply_bal,
                                 get_gold_and_foreign_reserves)

上面代码说明TuShare的13个宏观数据API是从stock下的macro模块打包出来的。
我们打开源码stock目录下的macro.py文件,先分析macro.py的依赖项

import pandas as pd
import numpy as np
import re
import json
from tushare.stock import macro_vars as vs	# 引入macro_vars.py,包含宏观数据相关常量定义
from tushare.stock import cons as ct		# 引入cons.py,包含股票相关常量定义
try:
    from urllib.request import urlopen, Request
except ImportError:
    from urllib2 import urlopen, Request

4.1、API:获取年度国内生产总值数据

def get_gdp_year():

代码中有获取年度国内生产总值数据API的详细说明:

    """
        获取年度国内生产总值数据
    Return
    --------
    DataFrame
        year :统计年度
        gdp :国内生产总值(亿元)
        pc_gdp :人均国内生产总值()
        gnp :国民生产总值(亿元)
        pi :第一产业(亿元)
        si :第二产业(亿元)
        industry :工业(亿元)
        cons_industry :建筑业(亿元)
        ti :第三产业(亿元)
        trans_industry :交通运输仓储邮电通信业(亿元)
        lbdy :批发零售贸易及餐饮业(亿元)
    """
    rdint = vs.random()
    # 拼接获取年度国内生产总值数据的URL
    request = Request(vs.MACRO_URL%(vs.P_TYPE['http'], vs.DOMAINS['sina'],
                                    rdint, vs.MACRO_TYPE[0], 0, 70,
                                    rdint))
    text = urlopen(request, timeout=10).read()
    text = text.decode('gbk') if ct.PY3 else text
    regSym = re.compile(r'\,count:(.*?)\}')
    datastr = regSym.findall(text)
    datastr = datastr[0]
    datastr = datastr.split('data:')[1]
    datastr = datastr.replace('"', '').replace('null', '0')
    js = json.loads(datastr)
    df = pd.DataFrame(js, columns=vs.GDP_YEAR_COLS)
    df[df==0] = np.NaN
    return df
代码cons.py中对应内容说明
vs.MACRO_URLMACRO_URL = ‘%smoney.finance.%s/mac/api/jsonp.php/SINAREMOTECALLCALLBACK%s/MacPage_Service.get_pagedata?cate=%s&event=%s&from=0&num=%s&condition=&_=%s’新浪获取年度国内生产总值数据URL格式
ct.DOMAINS[‘sina’]‘sina’: ‘sina.com.cn’新浪财经股票数据中心
vs.MACRO_TYPE[0]MACRO_TYPE = [‘nation’,‘price’,‘fininfo’]

示例,获取年度国内生产总值数据:

http://money.finance.sina.com.cn/mac/api/jsonp.php/SINAREMOTECALLCALLBACK5564253726144/MacPage_Service.get_pagedata?cate=nation&event=0&from=0&num=70&condition=&_=5564253726144

这个地址无法正常获取,代码还需要完善。
http://finance.sina.com.cn/mac/#nation-0-0-31-1中我们可以查看新浪的宏观数据,如果需要,我们需要自己扩展。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值