#使用的是 pywinauto 0.6.4 和 python3.7.2
# 注意,python3.7.4以上不行的。在github的issue有写
# 在win10_64也是有问题,tree会选错选择
# 向edit控件输入内容,要使用type_keys(""),用set_text失败的。
#
import pywinauto
from pywinauto import clipboard
from pywinauto import keyboard
from .captcha_recognize import captcha_recognize
import pandas as pd
import io
from .const import BALANCE_CONTROL_ID_GROUP
import time
class THSTrader:
def __init__(self, exe_path=r"C:\同花顺软件\同花顺\xiadan.exe"):
print("正在连接客户端:", exe_path, "......")
#self.app = pywinauto.Application().start(exe_path)
try:
self.app = pywinauto.Application().connect(path= exe_path, timeout=10)
except Exception as ex:
self.app = pywinauto.Application().start(exe_path)
time.sleep(2)
pass
print("连接成功!!!")
self.main_wnd = self.app.window(title=u"网上股票交易系统5.0")
def buy(self, stock_no, price, amount):
""" 买入 """
time.sleep(1)
self.__select_menu(['买入[F1]'])
return self.__trade(stock_no, price, amount)
def sell(self, stock_no, price, amount):
""" 卖出 """
time.sleep(1)
self.__select_menu(['卖出[F2]'])
return self.__trade(stock_no, price, amount)
def cancel_entrust(self, entrust_no):
""" 撤单 """
time.sleep(1)
self.__select_menu(['撤单[F3]'])
cancelable_entrusts = self.__get_grid_data(is_entrust=True) # 获取可以撤单的条目
for i, entrust in enumerate(cancelable_entrusts):
if str(entrust["合同编号"]) == str(entrust_no): # 对指定合同进行撤单
return self.__cancel_by_double_click(i)
return {"success": False, "msg": "没找到指定订单"}
def get_balance(self):
""" 获取资金情况 """
time.sleep(1)
self.__select_menu(['查询[F4]', '资金股票'])
result = {}
for key, control_id in BALANCE_CONTROL_ID_GROUP.items():
result[key] = float(
self.main_wnd.window(control_id=control_id, class_name='Static').window_text()
)
return result
def check_trade_finished(self, entrust_no):
""" 判断订单是否完成 """
time.sleep(1)
self.__select_menu(['卖出[F2]'])
time.sleep(1)
self.__select_menu(['撤单[F3]'])
cancelable_entrusts = self.__get_grid_data(is_entrust=True)
# print(cancelable_entrusts)
for i, entrust in enumerate(cancelable_entrusts):
if str(entrust["合同编号"]) == str(entrust_no): # 如果订单未完成,就意味着可以撤单
if entrust["成交数量"] == 0:
return False
return True
def get_position(self):
""" 获取持仓 """
time.sleep(1)
self.__select_menu(['查询[F4]', '资金股票'])
return self.__get_grid_data()
def get_today_entrusts(self):
""" 获取当日委托 """
time.sleep(1)
self.__select_menu(['查询[F4]', '当日委托'])
return self.__get_grid_data()
def get_today_trades(self):
time.sleep(1)
self.__select_menu(['查询[F4]', '当日成交'])
return self.__get_grid_data()
def add_old_user(self,user_item):
""" 增加账户 """
#print(self.main_wnd.window(control_id=0x912, class_name="ComboBox").texts())
""" 开始增加账户 """
self.main_wnd.window(control_id=0x69B, class_name="Button").click()
#弹出窗口
time.sleep(0.3)
#self.main_wnd.window(handle = self.main_wnd.popup_window()).window(control_id=0x3e9, class_name="Edit").type_keys("75084160000")
popup_window1 = self.main_wnd.window(handle = self.main_wnd.popup_window())
#combobox 从0开始的。
popup_window1.window(control_id=0x3f3, class_name="ComboBox").select(user_item)
popup_window1.window(control_id=0x3ee, class_name="Button").click()
#popup_window1.window(control_id=0x959, class_name="Button").click()
#popup_window1.window(handle =popup_window1.popup_window()).print_control_identifiers()
#popup_window1.window(handle =popup_window1.popup_window()).window(class_name="CPanel")
return "ok"
def __trade(self, stock_no, price, amount):
#time.sleep(1)
self.main_wnd.window(control_id=0x3ef, class_name="Button").click() #重置
self.main_wnd.window(control_id=0x408, class_name="Edit").wait('ready', 3) # sometime can't find handle ready, must retry
self.main_wnd.window(control_id=0x408, class_name="Edit").type_keys(str(stock_no)) # 设置股票代码
time.sleep(0.3)
text_len = self.main_wnd.window(control_id=0x409, class_name="Edit").line_length(0)
for i in range(text_len):
self.main_wnd.window(control_id=0x409, class_name="Edit").type_keys("{BACKSPACE}") #删除自动获取的价格
self.main_wnd.window(control_id=0x409, class_name="Edit").type_keys(str(price)) # 设置价格
self.main_wnd.window(control_id=0x40A, class_name="Edit").type_keys(str(amount)) # 设置股数目
time.sleep(0.2)
self.main_wnd.window(control_id=0x3EE, class_name="Button").click() # 点击卖出or买入
time.sleep(0.2)
#keyboard.SendKeys("{ENTER}")
#print(hex(self.app.top_window().handle))#topwindow 不是弹出窗口,要搜索 【下错价格,有提示信息】
#try:
# if "提示信息" in self.main_wnd.window(handle = self.main_wnd.popup_window()).window(control_id=0x555, class_name='Static').window_text():
# self.main_wnd.window(handle = self.main_wnd.popup_window()).window(control_id=0x553, class_name='Button').click()
#except:
# pass
popup_win_hwd = self.main_wnd.popup_window()
print(hex(popup_win_hwd))
self.main_wnd.window(handle = popup_win_hwd).window(control_id=0x6, class_name='Button').click() # 确定买入
#self.main_wnd.window(handle = popup_win_hwd).set_focus()
time.sleep(0.3)
try:
#在弹出的窗口还是一样的句柄 +0x10000。
popup_win_hwd = popup_win_hwd+0x10000
self.main_wnd.window(handle = popup_win_hwd).window(control_id=0x3EC, class_name='Static').wait('ready', 3)
result = self.main_wnd.window(handle = popup_win_hwd).window(control_id=0x3EC, class_name='Static').window_text()
self.main_wnd.window(handle = popup_win_hwd).set_focus()
time.sleep(0.2)
self.main_wnd.window(handle = popup_win_hwd).window(control_id=0x2, class_name='Button').click() # 确定
except:
return {
"success": False
}
return self.__parse_result(result)
def __get_grid_data(self, is_entrust=False):
""" 获取grid里面的数据 """
time.sleep(0.1)
grid = self.main_wnd.window(control_id=0x417, class_name='CVirtualGridCtrl')
time.sleep(0.1)
grid.set_focus()
#grid.print_control_identifiers()
#print(self.main_wnd.PopupMenu.wait('ready').menu().items()) #想获取弹出菜单很难
#print(hex(grid.PopupMenu.Menu().handle))
keyboard.SendKeys('^c') #send_keys('^a^c') # select all (Ctrl+A) and copy to clipboard (Ctrl+C)
data = clipboard.GetData()
df = pd.read_csv(io.StringIO(data), delimiter='\t', na_filter=False)
return df.to_dict('records')
def __select_menu(self, path):
""" 点击左边菜单 """
if r"网上股票" not in self.app.top_window().window_text():
self.app.top_window().set_focus()
pywinauto.keyboard.SendKeys("{ENTER}")
self.__get_left_menus_handle().get_item(path).click()
def __get_left_menus_handle(self):
while True:
try:
handle = self.main_wnd.window(control_id=129, class_name='SysTreeView32')
handle.wait('ready', 3) # sometime can't find handle ready, must retry
return handle
except Exception as ex:
print(ex)
pass
def __cancel_by_double_click(self, row):
""" 通过双击撤单 """
x = 50
y = 30 + 16 * row
self.app.top_window().window(control_id=0x417, class_name='CVirtualGridCtrl').double_click(coords=(x, y))
self.app.top_window().window(control_id=0x6, class_name='Button').click() # 确定撤单
time.sleep(0.1)
if "网上股票交易系统5.0" not in self.app.top_window().window_text():
result = self.app.top_window().window(control_id=0x3EC, class_name='Static').window_text()
self.app.top_window().window(control_id=0x2, class_name='Button').click() # 确定撤单
return self.__parse_result(result)
else:
return {
"success": True
}
@staticmethod
def __parse_result(result):
""" 解析买入卖出的结果 """
# "您的买入委托已成功提交,合同编号:865912566。"
# "您的卖出委托已成功提交,合同编号:865967836。"
# "您的撤单委托已成功提交,合同编号:865967836。"
# "系统正在清算中,请稍后重试! "
if r"已成功提交,合同编号:" in result:
return {
"success": True,
"msg": result,
"entrust_no": result.split("合同编号:")[1].split("。")[0]
}
else:
return {
"success": False,
"msg": result
}
测试的时候发现几个问题,在win10下64位系统,那tree的item会点击错位的。例如想点 市价委托,但是最后点了上面的买入。
# -*- coding: utf-8 -*-
import pywinauto
import time
from pywinauto import application
class AccessDeniedError(Exception):
"""Raise when current user is not an administrator."""
def __init__(self, arg):
self.args = arg
class NoExistGroupError(Exception):
"""Raise when group Administrators is not exist."""
def __init__(self, arg):
self.args = arg
exe_path =r"C:\同花顺软件\同花顺\xiadan.exe"
print("正在连接客户端:", exe_path, "......")
#app = pywinauto.Application().connect(path=r'C:\同花顺软件\同花顺\xiadan.exe', timeout=10)
app = pywinauto.Application().connect(title_re='网上股票交易系统5.0')
print("连接成功!!!")
if r"网上股票" not in app.top_window().window_text():
app.top_window().set_focus()
pywinauto.keyboard.SendKeys("{ENTER}")
print("设置下单软件为第一界面,handle= ",hex(app.top_window().handle),"text = ",app.top_window().is_dialog())
#app.window(title=u"网上股票交易系统5.0").print_control_identifiers()
#app.window(title=u"网上股票交易系统5.0").window(best_match='#32770').print_control_identifiers()
app.window(title=u"网上股票交易系统5.0").window(control_id=129, class_name='SysTreeView32').print_control_identifiers()
tree = app.window(title=u"网上股票交易系统5.0").hexin_scroll_wnd2.tree_view
groups = tree.get_item(r'\市价委托\买入')
groups.click()
————————————————
版权声明:本文为CSDN博主「jhui123456」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jhui123456/article/details/104162759