rakuten_rssを使って株価を取得しようとすると、
fail: code@ 9501.T
と表示されます。
DDE通信?を使っているらしいです。
pdb(後述)を使ってデバッグをしました。
ddeclient.pyのrequest関数の中で条件分岐で
if not hDdeData:
raise DDEError("Unable to request item", self._idInst)
hDdeDataがFalseみたいです。
self._idInstとhszItemはきちんと値が入っています。
どうすればいいでしょうか。
ddeclient.pyの一部
ddeclient.pyの一部
1from ctypes import POINTER, WINFUNCTYPE, c_char_p, c_void_p, c_int, c_ulong, c_char_p 2from ctypes.wintypes import BOOL, DWORD, BYTE, INT, LPCWSTR, UINT, ULONG 3 4# DECLARE_HANDLE(name) typedef void *name; 5HCONV = c_void_p # = DECLARE_HANDLE(HCONV) 6HDDEDATA = c_void_p # = DECLARE_HANDLE(HDDEDATA) 7HSZ = c_void_p # = DECLARE_HANDLE(HSZ) 8LPBYTE = c_char_p # POINTER(BYTE) 9LPDWORD = POINTER(DWORD) 10LPSTR = c_char_p 11ULONG_PTR = c_ulong 12 13# See windows/ddeml.h for declaration of struct CONVCONTEXT 14PCONVCONTEXT = c_void_p 15 16DMLERR_NO_ERROR = 0 17 18# Predefined Clipboard Formats 19CF_TEXT = 1 20CF_BITMAP = 2 21CF_METAFILEPICT = 3 22CF_SYLK = 4 23CF_DIF = 5 24CF_TIFF = 6 25CF_OEMTEXT = 7 26CF_DIB = 8 27CF_PALETTE = 9 28CF_PENDATA = 10 29CF_RIFF = 11 30CF_WAVE = 12 31CF_UNICODETEXT = 13 32CF_ENHMETAFILE = 14 33CF_HDROP = 15 34CF_LOCALE = 16 35CF_DIBV5 = 17 36CF_MAX = 18 37 38DDE_FACK = 0x8000 39DDE_FBUSY = 0x4000 40DDE_FDEFERUPD = 0x4000 41DDE_FACKREQ = 0x8000 42DDE_FRELEASE = 0x2000 43DDE_FREQUESTED = 0x1000 44DDE_FAPPSTATUS = 0x00FF 45DDE_FNOTPROCESSED = 0x0000 46 47DDE_FACKRESERVED = (~(DDE_FACK | DDE_FBUSY | DDE_FAPPSTATUS)) 48DDE_FADVRESERVED = (~(DDE_FACKREQ | DDE_FDEFERUPD)) 49DDE_FDATRESERVED = (~(DDE_FACKREQ | DDE_FRELEASE | DDE_FREQUESTED)) 50DDE_FPOKRESERVED = (~(DDE_FRELEASE)) 51 52XTYPF_NOBLOCK = 0x0002 53XTYPF_NODATA = 0x0004 54XTYPF_ACKREQ = 0x0008 55 56XCLASS_MASK = 0xFC00 57XCLASS_BOOL = 0x1000 58XCLASS_DATA = 0x2000 59XCLASS_FLAGS = 0x4000 60XCLASS_NOTIFICATION = 0x8000 61 62XTYP_ERROR = (0x0000 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 63XTYP_ADVDATA = (0x0010 | XCLASS_FLAGS) 64XTYP_ADVREQ = (0x0020 | XCLASS_DATA | XTYPF_NOBLOCK) 65XTYP_ADVSTART = (0x0030 | XCLASS_BOOL) 66XTYP_ADVSTOP = (0x0040 | XCLASS_NOTIFICATION) 67XTYP_EXECUTE = (0x0050 | XCLASS_FLAGS) 68XTYP_CONNECT = (0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK) 69XTYP_CONNECT_CONFIRM = (0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 70XTYP_XACT_COMPLETE = (0x0080 | XCLASS_NOTIFICATION ) 71XTYP_POKE = (0x0090 | XCLASS_FLAGS) 72XTYP_REGISTER = (0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK ) 73XTYP_REQUEST = (0x00B0 | XCLASS_DATA ) 74XTYP_DISCONNECT = (0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK ) 75XTYP_UNREGISTER = (0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK ) 76XTYP_WILDCONNECT = (0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK) 77XTYP_MONITOR = (0x00F0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 78 79XTYP_MASK = 0x00F0 80XTYP_SHIFT = 4 81 82TIMEOUT_ASYNC = 0xFFFFFFFF 83 84def get_winfunc(libname, funcname, restype=None, argtypes=(), _libcache={}): 85 """Retrieve a function from a library, and set the data types.""" 86 from ctypes import windll 87 88 if libname not in _libcache: 89 _libcache[libname] = windll.LoadLibrary(libname) 90 func = getattr(_libcache[libname], funcname) 91 func.argtypes = argtypes 92 func.restype = restype 93 94 return func 95 96 97DDECALLBACK = WINFUNCTYPE(HDDEDATA, UINT, UINT, HCONV, HSZ, HSZ, HDDEDATA, 98 ULONG_PTR, ULONG_PTR) 99 100class DDE(object): 101 """Object containing all the DDE functions""" 102 AccessData = get_winfunc("user32", "DdeAccessData", LPBYTE, (HDDEDATA, LPDWORD)) 103 ClientTransaction = get_winfunc("user32", "DdeClientTransaction", HDDEDATA, (LPBYTE, DWORD, HCONV, HSZ, UINT, UINT, DWORD, LPDWORD)) 104 Connect = get_winfunc("user32", "DdeConnect", HCONV, (DWORD, HSZ, HSZ, PCONVCONTEXT)) 105 CreateStringHandle = get_winfunc("user32", "DdeCreateStringHandleW", HSZ, (DWORD, LPCWSTR, UINT)) 106 Disconnect = get_winfunc("user32", "DdeDisconnect", BOOL, (HCONV,)) 107 GetLastError = get_winfunc("user32", "DdeGetLastError", UINT, (DWORD,)) 108 Initialize = get_winfunc("user32", "DdeInitializeW", UINT, (LPDWORD, DDECALLBACK, DWORD, DWORD)) 109 FreeDataHandle = get_winfunc("user32", "DdeFreeDataHandle", BOOL, (HDDEDATA,)) 110 FreeStringHandle = get_winfunc("user32", "DdeFreeStringHandle", BOOL, (DWORD, HSZ)) 111 QueryString = get_winfunc("user32", "DdeQueryStringA", DWORD, (DWORD, HSZ, LPSTR, DWORD, c_int)) 112 UnaccessData = get_winfunc("user32", "DdeUnaccessData", BOOL, (HDDEDATA,)) 113 Uninitialize = get_winfunc("user32", "DdeUninitialize", BOOL, (DWORD,)) 114 115class DDEError(RuntimeError): 116 """Exception raise when a DDE errpr occures.""" 117 def __init__(self, msg, idInst=None): 118 if idInst is None: 119 RuntimeError.__init__(self, msg) 120 else: 121 RuntimeError.__init__(self, "%s (err=%s)" % (msg, hex(DDE.GetLastError(idInst)))) 122 123class DDEClient(object): 124 """The DDEClient class. 125 126 Use this class to create and manage a connection to a service/topic. To get 127 classbacks subclass DDEClient and overwrite callback.""" 128 129 def __init__(self, service, topic): 130 """Create a connection to a service/topic.""" 131 from ctypes import byref 132 self._idInst = DWORD(0) 133 self._hConv = HCONV() 134 self._callback = DDECALLBACK(self._callback) 135 res = DDE.Initialize(byref(self._idInst), self._callback, 0x00000010, 0) 136 if res != DMLERR_NO_ERROR: 137 raise DDEError("Unable to register with DDEML (err=%s)" % hex(res)) 138 hszService = DDE.CreateStringHandle(self._idInst, service, 1200) 139 hszTopic = DDE.CreateStringHandle(self._idInst, topic, 1200) 140 self._hConv = DDE.Connect(self._idInst, hszService, hszTopic, PCONVCONTEXT()) 141 DDE.FreeStringHandle(self._idInst, hszTopic) 142 DDE.FreeStringHandle(self._idInst, hszService) 143 if not self._hConv: 144 raise DDEError("Unable to establish a conversation with server", self._idInst) 145 146 def __del__(self): 147 """Cleanup any active connections.""" 148 if self._hConv: 149 DDE.Disconnect(self._hConv) 150 if self._idInst: 151 DDE.Uninitialize(self._idInst) 152 153 def advise(self, item, stop=False): 154 """Request updates when DDE data changes.""" 155 from ctypes import byref 156 hszItem = DDE.CreateStringHandle(self._idInst, item, 1200) 157 hDdeData = DDE.ClientTransaction(LPBYTE(), 0, self._hConv, hszItem, CF_TEXT, XTYP_ADVSTOP if stop else XTYP_ADVSTART, TIMEOUT_ASYNC, LPDWORD()) 158 DDE.FreeStringHandle(self._idInst, hszItem) 159 if not hDdeData: 160 raise DDEError("Unable to %s advise" % ("stop" if stop else "start"), self._idInst) 161 DDE.FreeDataHandle(hDdeData) 162 163 def execute(self, command, timeout=5000): 164 """Execute a DDE command.""" 165 pData = c_char_p(command) 166 cbData = DWORD(len(command) + 1) 167 hDdeData = DDE.ClientTransaction(pData, cbData, self._hConv, HSZ(), CF_TEXT, XTYP_EXECUTE, timeout, LPDWORD()) 168 if not hDdeData: 169 raise DDEError("Unable to send command", self._idInst) 170 DDE.FreeDataHandle(hDdeData) 171 172 def request(self, item, timeout=5000): 173 """Request data from DDE service.""" 174 from ctypes import byref 175 hszItem = DDE.CreateStringHandle(self._idInst, item, 1200) 176 hDdeData = DDE.ClientTransaction(LPBYTE(), 0, self._hConv, hszItem, CF_TEXT, XTYP_REQUEST, timeout, LPDWORD()) 177 DDE.FreeStringHandle(self._idInst, hszItem) 178 print(self._hConv, hszItem) 179 if not hDdeData: 180 raise DDEError("Unable to request item", self._idInst) 181 182 if timeout != TIMEOUT_ASYNC: 183 pdwSize = DWORD(0) 184 pData = DDE.AccessData(hDdeData, byref(pdwSize)) 185 if not pData: 186 DDE.FreeDataHandle(hDdeData) 187 raise DDEError("Unable to access data", self._idInst) 188 # TODO: use pdwSize 189 DDE.UnaccessData(hDdeData) 190 else: 191 pData = None 192 DDE.FreeDataHandle(hDdeData) 193 return pData
rakuten_rss.pyのコード
Python
1from lib.ddeclient import DDEClient 2 3 4def rss(code, item): 5 dde = DDEClient("rss", str(code)) 6 try: 7 res = dde.request(item).decode('sjis').strip() 8 except: 9 print('fail: code@', code) 10 res = 0 11 finally: 12 dde.__del__() 13 return res 14 15 16def rss_dict(code, *args): 17 dde = DDEClient("rss", str(code)) 18 res = {} 19 try: 20 for item in args: 21 res[item] = dde.request(item).decode('sjis').strip() 22 except: 23 print('fail: code@', code) 24 res = {} 25 finally: 26 dde.__del__() 27 return res 28 29 30def fetch_open(code): 31 """ 始値を返す(SQ計算用に関数切り出し,入力int) 32 33 Parameters 34 ---------- 35 code : int 36 Examples 37 --------- 38 >>> fetch_open(9551) 39 50050 40 """ 41 42 return float(rss(str(code) + '.T', '始値'))
powershell
1python -m pdb request.py
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。