环境 :mac + pycharm + anaconda(配置3.6)
问题,用tushare的get_h_data取数据的时候,单进程太慢,想着用多进程跑起来:
def down_stk_all(qx,finx):
'''
根据finx股票列表文件,下载所有,或追加日线数据
自动去重,排序
'''
dinx = pd.read_csv(finx,encoding='gbk') ;print(finx);
xn9=len(dinx['code']);
# for i,xc in enumerate(dinx['code']):
# code="%06d" %xc
# print("\n",i,"/",xn9,"code,",code)
# #---
# qx.code=code;
# down_stk_cn010(qx);
pool = multiprocessing.Pool(processes=16)
for i,xc in enumerate(dinx['code']):
code="%06d" %xc
print("\n",i,"/",xn9,"code,",code)
#---
qx.code=code;
# down_stk_cn010(qx);
pool.apply(down_stk_cn010,(qx,))
pool.close()
pool.join()
def down_stk_cn010(qx):
''' 中国A股数据下载子程序
【输入】
qx (zwDatX):
xtyp (str):数据类型,9,Day9,简版股票数据,可下载到2001年,其他的全部是扩充版数据,只可下载近3年数据
D=日k线 W=周 M=月 默认为D
:ivar xcod (int): 股票代码
:ivar fss (str): 保存数据文件名
'''
xcod,rss,=qx.code,qx.rDay;
tim0='1994-01-01';#tim0='2012-01-01';
#
fss=rss+xcod+'.csv'
#-------------------
xfg=os.path.exists(fss);xd0=[];xd=[];
if xfg:
xd0= pd.read_csv(fss,index_col=0,parse_dates=[0],encoding='gbk')
#print(xd0.head())
xd0=xd0.sort_index(ascending=False);
#tim0=xd0.index[0];
_xt=xd0.index[0];#xt=xd0.index[-1];###
s2=str(_xt);tim0=s2.split(" ")[0]
print('\n',xfg,fss,",",tim0);
#-----------
try:
xd=ts.get_h_data(xcod,start=tim0,end=None,retry_count=5,pause=1) #Day9
#xd=ts.get_hist_data(xcod,start=tim0,end=None,retry_count=5,pause=1,ktype=xtyp);
#-------------
if xd is not None:
if (len(xd0)>0):
xd2 =xd0.append(xd)
# flt.dup
xd2["index"]=xd2.index
xd2.drop_duplicates(subset='index', keep='last', inplace=True);
del(xd2["index"]);
#xd2.index=pd.to_datetime(xd2.index)
xd=xd2;
xd=xd.sort_index(ascending=False);
xd=np.round(xd,3);
xd.to_csv(fss,encoding='gbk')
except IOError:
pass #skip,error
return xd
源代码注释掉了,for循环挨个取。用多进程,扔到进程池里,这样快很多。
问题来了,因为用的pool.apply,阻塞方式,跑起来以后卡住不动了。
一路追踪:_parse_fq_data --> urlopen --> build_opener -->
for klass in default_classes:
opener.add_handler(klass())
跟进:
class ProxyHandler(BaseHandler):
# Proxies must be in front
handler_order = 100
def __init__(self, proxies=None):
if proxies is None:
proxies = getproxies()
assert hasattr(proxies, 'keys'), "proxies must be a mapping"
self.proxies = proxies
for type, url in proxies.items():
setattr(self, '%s_open' % type,
lambda r, proxy=url, type=type, meth=self.proxy_open:
meth(r, proxy, type))
def getproxies():
return getproxies_environment() or getproxies_macosx_sysconf()
getproxies_environment()没问题,返回为空。
def getproxies_macosx_sysconf():
"""Return a dictionary of scheme -> proxy server URL mappings.
This function uses the MacOSX framework SystemConfiguration
to fetch the proxy information.
"""
return _get_proxies()
想进入_get_proxies 跟踪的时候,代码飞了。
点击代码跟进,来到这里。
# encoding: utf-8
# module _scproxy
# from 省略路径/anaconda/envs/for36/lib/python3.6/lib-dynload/_scproxy.cpython-36m-darwin.so
# by generator 1.145
# no doc
# no imports
# functions
def _get_proxies(*args, **kwargs): # real signature unknown
pass
def _get_proxy_settings(*args, **kwargs): # real signature unknown
pass
# no classes
# variables with complex values
__loader__ = None # (!) real value is ''
__spec__ = None # (!) real value is ''
这段代码在:
省略路径/Library/Caches/PyCharm2017.1/python_stubs/720200485/_scproxy.py下。惆怅,我python纯新爪。
单独跑了一次,就取一只的数据,发现getproxies_macosx_sysconf返回的是空!!!!
what,还能这样???难道是多进程的时候抢占系统资源了???
反正是空,那就注释掉你!
def getproxies():
return getproxies_environment() #or getproxies_macosx_sysconf()
跑起来吧。。能取到数据了,泪流满面。
修改pool方式为非阻塞。
最终代码:
def down_stk_all(qx,finx):
'''
根据finx股票列表文件,下载所有,或追加日线数据
自动去重,排序
'''
dinx = pd.read_csv(finx,encoding='gbk') ;print(finx);
xn9=len(dinx['code']);
# for i,xc in enumerate(dinx['code']):
# code="%06d" %xc
# print("\n",i,"/",xn9,"code,",code)
# #---
# qx.code=code;
# down_stk_cn010(qx);
pool = multiprocessing.Pool(processes=8)
for i,xc in enumerate(dinx['code']):
qxtemp= copy.deepcopy(qx)
code="%06d" %xc
# print("\n",i,"/",xn9,"code,",code)
#---
qxtemp.code=code;
# down_stk_cn010(qx);
pool.apply_async(down_stk_cn010,(qxtemp,)) # 维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
pool.close()
pool.join() # 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
小问题还是有,比如tushare的进度条就费了,print到一起了。
不过,享受多进程同时下载的快感吧。。。