wkeMiniblink.wke 源代码

# -*- coding:utf-8 -*-
import os,sys,platform,time
import binascii
from inspect import getmembers


from . import _LRESULT,WkeCallbackError,MINIBLINK_DLL_PATH,SetMiniblinkDLL,GetMiniblinkDLL
from .miniblink import MiniblinkInit
from .wkeStruct import *
from .wkeEvent import WkeEvent

from ctypes import (c_void_p,
    c_int,
    c_ushort,c_longlong,c_ulonglong,
    c_wchar_p,
    c_float,
    byref,
    CFUNCTYPE,
    py_object,
    cast
)


@CFUNCTYPE(None,_LRESULT,_LRESULT)
def _WkeJsBindCallback(execState,c_id):
    """
    jsBind的C-Python 回调函数,调用实际注册在Wke上下文中的Py函数
    """
    if c_id in Wke._jsBinderContext:
        context = Wke._jsBinderContext[c_id]
        return context["func"](es=execState,param=context["param"])   
    return None

[文档] class Wke(): """Wke全局接口 Examples: .. code:: python Wke.init("miniblink_4975_x32.dll") .... Wke.runMessageLoop() """ #动态库 dll = None #js管理 js = None #事件管理 event = None #接口版本数值 version = 0 _jsBinderContext = {} _localStagePath = None _cookiePath = None
[文档] @staticmethod def Version(): return Wke.dll.wkeVersionString()
[文档] @staticmethod def init(path=MINIBLINK_DLL_PATH,**kwargs): """加载动态库 初始化整个mb。此句必须在所有mb api前最先调用。并且所有mb api必须和调用wkeInit的线程为同个线程 Args: path(str): 动态库的文件位置 """ Wke.dll = MiniblinkInit(path) SetMiniblinkDLL(Wke.dll) Wke.event = WkeEvent() Wke.version = Wke.dll.wkeVersion() #复制动态库中所有wke开头的功能函数 for name,func in getmembers(Wke.dll): if name.startswith(("wke")): setattr(Wke,name,func) return
[文档] @staticmethod def getDLL(): """返回动态库DLL对象 Returns: cdll: 动态库DLL对象 """ return Wke.dll
[文档] @staticmethod def loaded(): """查询是否已加载动态库 Returns: bool: 已加载返回True,未加载返回False """ if Wke.dll is None: return False return True
[文档] @staticmethod def setCookieAndStagePath(**kwargs): """设置Cookie/LocalStage的存储路径 Keyword Args: cookie(str): Cookie的存储文件路径 localStagePath(str): LocalStage的存储目录路径 """ if "cookie" in kwargs: Wke._cookiePath = os.path.realpath(kwargs["cookie"]) if "localStage" in kwargs: Wke._localStagePath = os.path.realpath(kwargs["localStage"]) return
@staticmethod def _jsBindFunction(jsFuncName,pyCallback, param=0,arg_count=0): """设置一个python回调函数作为指定名称的js函数使用 Args: jsFuncName(str): js函数名 pyCallback(function): python函数 param(any, optional): 回调上下文 arg_count(int, optional): 参数个数 """ return Wke.dll.wkeJsBindFunction(jsFuncName,pyCallback,arg_count,param)
[文档] @staticmethod def runMessageLoop(): """Wke执行消息循环 也可以用win32gui.PumpMessages() """ Wke.dll.wkeRunMessageLoop(0)
[文档] @staticmethod def jsGC(): """JS触发垃圾回收 """ Wke.dll.jsGC()
[文档] @staticmethod def extend(func,name,param=0,arg_count=1): """使用一个指定的python函数作为js扩展实现的函数 Examples: .. code:: python webview = WebWindow() webview.create(0,0,0,800,600) def pyAction(**kwargs): es=kwargs['es'] context =kwargs['param'] webview = context arg_count=Wke.jsArgCount(es) val_ls=Wke.getJsArgs(es,arg_count) webview.runJsCode('alert("jsCallpy'+str(val_ls)+'")') return Wke.extend(pyAction,'jsCallpy', param=webview) 在HTML中 .. code:: html <button onclick="jsCallpy('jsCallpy', 666)" style='margin-right: 20px;cursor: pointer;'>jsCallpy</button> .. code-block:: c void wkeJsBindFunction(const char* name, wkeJsNativeFunction fn, void* param, unsigned int argCount); //C原型 Args: func(:obj:`function`): 扩展函数的python实现 name(:obj:`str`): 扩展的python函数在js中的名称 param(any, optional): python函数的回调上下文 arg_count(int, optional): 扩展函数的参数个数 Raise: SyntaxError : func为不可调用时抛出 """ if not callable(func) : raise SyntaxError(f"{func} not callable") rawname = name.encode() funcid = id(func) Wke._jsBinderContext[funcid]={"param":param,"name":name,"rawname":rawname,"func":func,"argcount":arg_count} return Wke._jsBindFunction(rawname,_WkeJsBindCallback,arg_count,_LRESULT(funcid))
[文档] @staticmethod def jsArgCount(arg): """获取JS对象中变量的个数 Args: arg(jsVar): JS对象 Returns: int: JS对象中变量的个数 """ return Wke.dll.jsArgCount(arg)
[文档] @staticmethod def getJsArgs(es,arg_count): """JS状态机中arg_count个对象转换成py对象列表 Args: es(str): JS状态机 arg_count(int, optional): 参数个数 Returns: jsVar: JS对象 """ val_ls=[None]*arg_count for i in range(arg_count): arg_type=Wke.dll.jsArgType(es,i) if arg_type==0: val=Wke.dll.jsArg(es,i) val=Wke.dll.jsToInt(es, c_longlong(val)) elif arg_type==1: val=Wke.dll.jsArg(es,i) val=Wke.dll.jsToTempStringW(es, c_longlong(val)) elif arg_type==2: val=Wke.dll.jsArg(es,i) val=Wke.dll.jsToTempStringW(es, c_longlong(val)) if val=='false': val=False else: val=True elif arg_type==5 or arg_type==7: val=None elif arg_type==6: val=Wke.dll.jsArg(es,i) lens=Wke.dll.jsGetLength(es,c_longlong(val)) tmp_arr=[None]*lens for j in range(lens): tmp_val=Wke.dll.jsGetAt(es,c_longlong(val),j) if Wke.dll.jsIsNumber(tmp_val)==1: tmp_val=Wke.dll.jsToInt(es, c_longlong(tmp_val)) elif Wke.dll.jsIsString(tmp_val)==1: tmp_val=Wke.dll.jsToTempStringW(es, c_longlong(tmp_val)) tmp_val=c_wchar_p(tmp_val).value elif Wke.dll.jsIsBoolean(tmp_val)==1: tmp_val=Wke.dll.jsToTempStringW(es, c_longlong(tmp_val)) if tmp_val=='false': tmp_val=False else: tmp_val=True tmp_arr[j]=tmp_val val=tmp_arr else: val=Wke.dll.jsArg(es,i) val=Wke.dll.jsToTempStringW(es, c_longlong(val)) val_ls[i]=val return val_ls
[文档] @staticmethod def setJsArgs(es,val): """将python对象val转换成JS状态机中的JS对象 Args: es(str): JS状态机 val(any): python对象 """ if isinstance(val,str): val=Wke.dll.jsStringW(es,val) elif isinstance(val,int): val=Wke.dll.jsInt(val) elif isinstance(val,float): val=Wke.dll.jsFloat(val) elif isinstance(val,bool): val=Wke.dll.jsBoolean(val) elif isinstance(val,list): lens=len(val) tmp_arr=Wke.dll.jsEmptyArray(es) for i in range(lens): if isinstance(val[i],int): tmp_val=Wke.dll.jsInt(val[i]) elif isinstance(val[i],str): tmp_val=Wke.dll.jsStringW(es,val[i]) elif isinstance(val[i],float): tmp_val=Wke.dll.jsFloat(c_float(val[i])) Wke.dll.jsSetAt(es, c_longlong(tmp_arr), i, c_longlong(tmp_val)) val=tmp_arr elif isinstance(val,dict): tmp_obj=Wke.dll.jsEmptyObject(es) for k,v in val.items(): if isinstance(v,int): v=Wke.dll.jsInt(v) elif isinstance(v,str): v=Wke.dll.jsStringW(es,v) elif isinstance(v,float): v=Wke.dll.jsFloat(c_float(v)) Wke.dll.jsSet(es,c_longlong(tmp_obj),k.encode(),c_longlong(v)) val=tmp_obj return val
[文档] @staticmethod def buildProxy(self,ip,port,proxy_type=1,user=None,password=None): """创建代理配置对象 Args: ip(str): 代理IP 地址 port(int): 代理端口 proxy_type(int): 代理类型 user(str): 代理账号 password(str): 代理账号密码 Returns: wkeProxy: 代理对象 """ if not all([ip,port]):return None if user==None: user=b'' else: user=user.encode('utf8') if password==None: password=b'' else: password=password.encode('utf8') ip=ip.encode('utf8') port=int(port) proxy= wkeProxy(type=c_int(proxy_type), hostname=ip, port=c_ushort(port),username=user,password=password) return proxy
[文档] @staticmethod def setProxy(ip,port,proxy_type=1,user=None,password=None): """ 设置全局代理 Args: ip(str): 代理IP 地址 port(int): 代理端口 proxy_type(wkeProxyType): 代理类型 user(str): 代理账号 password(str): 代理账号密码 Returns: wkeProxy: 代理对象 """ proxy= Wke.buildProxy(ip,port,proxy_type,user,password) if proxy is not None: Wke.dll.wkeSetProxy(proxy) return proxy
[文档] class WebView(): """Wke网页视图 实现离屏网页视图功能,包括加载/渲染/设置/Js/Cookie等。 并不实际创建一个窗口,需要绑定一个外部窗口,使用额外的API将Webview的内容绘制到窗口上并处理某些需要的窗口消息。 """ def __init__(self,*args,**kwargs): super().__init__() self.dll = Wke.getDLL() self.cId = 0 self.isZoom=False self.isTransparent=False self.factor = 1.0 self.type = -1 self.hwnd = None self.hdc = None self.x = -1 self.y = -1 self.w = -1 self.h = -1 self.name = None self._localStagePath = None self._cookiePath = None return
[文档] def setCookieAndStagePath(self,**kwargs): """设置Cookie/LocalStage的存储路径 Keyword Args: cookie(str): Cookie的存储文件路径 localStagePath(str): LocalStage的存储目录路径 """ if "cookie" in kwargs and os.path.exists(kwargs["cookie"]): self._cookiePath = os.path.realpath(kwargs["cookie"]) if "localStage" in kwargs and os.path.exists(kwargs["localStage"]): self._localStagePath = os.path.realpath(kwargs["localStage"]) if self._cookiePath is None: self._cookiePath = Wke._cookiePath self.setCookieJarFullPath(self._cookiePath) if self._localStagePath is None: self._localStagePath = Wke._localStagePath self.setLocalStorageFullPath(self._localStagePath) return
def __del__(self): if self.cId is not None: self.destroy() return @property def id(self): """页面的句柄 Returns: int: 视图页面的句柄,即c api获取的webview """ return self.cId @property def width(self): """页面宽度 Returns: int: 视图页面宽度 """ self.w = self.dll.wkeWidth(self.cId) return self.w @property def height(self): """页面高度 Returns: int: 视图页面高度 """ self.h = self.dll.wkeHeight(self.cId) return self.h @property def contentsWidth(self): """页面内容宽度 Returns: int: 视图页面内容宽度 """ return self.dll.wkeContentsWidth(self.cId) @property def contentsHeight(self): """页面内容高度 Returns: int: 视图页面内容高度 """ return self.dll.wkeContentsHeight(self.cId)
[文档] def create(self): """创建一个页面webview,但不创建真窗口 Returns: int: 页面的C句柄 """ self.cId = self.dll.wkeCreateWebView() return self.cId
[文档] def bind(self,hwnd,x=0,y=0,width=640,height=480): """为页面绑定一个实际的窗口 Args: hwnd (int): 窗口句柄 x (int): 窗口绑定区域左上角起始点的x坐标 y (int): y坐标 width (int): 宽度 height (int): 高度 Returns: int: 页面的C句柄 """ if hwnd==0: return 0 #创建一个页面,获取句柄 self.cId = self.dll.wkeCreateWebView() #为页面设定窗体句柄 self.setHandle(hwnd) #将页面缩放到适合窗体大小 self.resize(width,height) self.setHandleOffset(x,y) self.hwnd = hwnd self.x,self.y = x,y self.w,self.h = width,height return self.cId
[文档] def destroy(self): """销毁wkeWebView对应的所有数据结构,包括真实窗口等 """ self.dll.wkeDestroyWebView(self.cId) self.hwnd = 0 self.x,self.y = -1,-1 self.w,self.h = -1,-1 self.isZoom=False self.isTransparent=False return
[文档] def setWebViewName(self,name): """设置页面名称 Args: name(:obj:`str`): 窗口名称 """ self.dll.wkeSetWebViewName(self.cId,name.encode()) self.name = name return
[文档] def resize(self,width,height): """调整页面大小 Args: width(int): 宽度 height(int): 高度 Returns: bool: 参数合法返回True,否则False """ if width==0 or height==0:return False self.w ,self.h = width,height self.dll.wkeResize(self.cId,width,height) return True
[文档] def setWindowTitle(self,title:str): """设置页面标题 Args: title(str): 标题 """ return self.dll.wkeSetWindowTitleW(self.cId,title)
[文档] def getWindowTitle(self): """获取页面标题 Returns: str: 标题 """ return self.dll.wkeGetWindowTitle(self.cId)
[文档] def showWindow(self,show=True): """设置页面显示与隐藏 Args: show(bool): True显示,False隐藏 """ self.dll.wkeShowWindow(self.cId,show) return
[文档] def MoveWindow(self,x:int,y:int,w:int,h:int): """设置页面位置与大小 Args: x(int): 页面左上点x坐标 y(int): 页面左上点y坐标 w(int): 页面宽度 h(int): 页面高度 """ self.x,self.y = x,y self.w,self.h = w,h self.dll.wkeMoveWindow(self.cId,x,w,w,h) return
[文档] def moveToCenter(self): """移动页面到中央 """ self.dll.wkeMoveToCenter(self.cId) return
[文档] def setFocus(self): """设置webview是焦点态,如果webveiw关联了窗口,窗口也会有焦点 """ self.dll.wkeSetFocus(self.cId) return
[文档] def killFocus(self): """设置webview是焦点态,如果webveiw关联了窗口,窗口也会有焦点 """ self.dll.wkeKillFocus(self.cId) return
[文档] def setDragEnable(self,drag=True): """设置页面可拖拽与否 Args: drag(bool): True可拖拽,False不可拖拽 """ self.dll.wkeSetDragEnable(self.cId,drag) return
[文档] def setZoomFactor(self,factor): """设置页面缩放 Args: factor(float): 缩放倍率 """ self.factor =factor self.dll.wkeSetZoomFactor(self.cId,factor) return
[文档] def getZoomFactor(self,factor): """获取页面缩放 Returns: float: 缩放倍率 """ self.factor = self.dll.wkeGetZoomFactor(self.cId) return self.factor
[文档] def setTransparent(self,transparent): """设置页面透明模式与否 Args: transparent(bool): True透明,False不透明 """ self.dll.wkeSetTransparent(self.cId,transparent) return
[文档] def getCaretRect(self): """获取编辑框的游标的位置 Returns: int: 编辑框的游标的位置 """ return self.dll.wkeGetCaretRect()
[文档] def getMainFrameId(self): """查询主帧编号 Returns: int: 主帧编号 """ return self.dll.wkeWebFrameGetMainFrame(self.cId)
def getFrameUrl(self,frameId:int): """查询指定编号帧的链接 Args: int: 帧编号 Returns: str: 帧链接 """ url = self.dll.wkeGetFrameUrl(self.cId) return url
[文档] def isMainFrame(self,frameId): """查询指定编号的帧是否是主帧 Args: frameId(int): 帧编号 Returns: bool: 是主帧返回True,不是返回False """ return self.dll.wkeIsMainFrame(self.cId,frameId)
[文档] def getTempCallbackInfo(self): """获取视图当前回调函数的临时信息 Returns: WKETempCallbackInfo: 临时信息 """ return self.dll.wkeGetTempCallbackInfo(self.cId)
[文档] def setUserKeyValue(self,k,v): """为视图的c对象设置一个绑定的k:v对 Args: k(str): 绑定键 v(any): 绑定对象 """ val = py_object(v) k = k.encode() return self.dll.wkeSetUserKeyValue(self.cId,k,val)
[文档] def getUserKeyValue(self,k:str): """获取视图绑定的k键对应的对象 Args: k(str): 绑定键 Returns: object: 绑定对象 """ k = k.encode() cPtrOfPyobj = self.dll.wkeGetUserKeyValue(self.cId,k) cPyObj = cast(cPtrOfPyobj,py_object) return cPyObj.value
##############Res##############
[文档] def setHandleOffset(self,x,y): """设置无窗口模式下的绘制偏移。在某些情况下(主要是离屏模式),绘制的地方不在真窗口的(0, 0)处,就需要手动调用此接口 Args: x(int): 绘制偏移x y(int): 绘制偏移y """ self.dll.wkeSetHandleOffset(self.cId,x,y)
[文档] def setHandle(self,hwnd): """设置wkeWebView对应的窗口句柄 注意:只有在无窗口模式下才能使用。如果是用wkeCreateWebWindow创建的webview,已经自带窗口句柄了。 Args: hwnd(int): 窗口句柄 """ self.dll.wkeSetHandle(self.cId,hwnd) self.hwnd = hwnd return
[文档] def getWindowHandle(self): """获取wkeWebView对应的窗口句柄 Returns: int: 页面的窗口句柄 """ return self.dll.wkeGetWindowHandle(self.cId)
[文档] def getViewDC(self): """获取wkeWebView对应的设备上下文句柄 Returns: DC: 页面的设备上下文句柄 """ self.hdc = self.dll.wkeGetViewDC(self.cId) return self.hdc
[文档] def unlockViewDC(self): """解锁wkeWebView对应的设备上下文句柄 """ self.dll.wkeUnlockViewDC(self.cId) return
##############Setting##############
[文档] def setUserAgentW(self,ua): """设置页面对应的浏览器标识字符串 Args: ua(str): 浏览器标识字符串 """ self.dll.wkeSetUserAgentW(self.cId,ua)
[文档] def getUserAgent(self): """获取页面对应的浏览器标识字符串 Returns: str: ua浏览器标识字符串 """ ua=self.dll.wkeGetUserAgent(self.cId) return ua.decode()
[文档] def setProxy(self,ip,port,proxy_type=1,user=None,password=None): """设置页面专属的代理 Args: ip(str): 代理IP 地址 port(int): 代理端口 proxy_type(int): 代理类型 user(str): 代理账号 password(str): 代理账号密码 Returns: wkeProxy: 代理对象 """ proxy= Wke.buildProxy(ip,port,proxy_type,user,password) if proxy is not None: self.dll.wkeSetViewProxy(self.cId,proxy) return proxy
[文档] def setContextMenuEnabled(self,en:bool): """设置页面右键上下文菜单使能与否 Args: en(bool): True使能,False禁止 """ self.dll.wkeSetContextMenuEnabled(self.cId,en)
[文档] def addPluginDirectory(self,_path): """设置页面右键上下文菜单使能与否 Todo: API文档上没有这一段 Args: en(bool): True使能,False禁止 """ self.dll.wkeAddPluginDirectory(self.cId,_path) return
[文档] def setNpapiPluginsEnabled(self,en): """开启关闭npapi插件,如flash Args: en(bool): True使能,False禁止 """ self.dll.wkeSetNpapiPluginsEnabled(self.cId,en) return
[文档] def setCspCheckEnable(self,en=False): """关闭后,跨域检查将被禁止,此时可以做任何跨域操作,如跨域ajax,跨域设置iframe Args: en(bool): True使能,False禁止 """ self.dll.wkeSetCspCheckEnable(self.cId,en) return
[文档] def setDebugConfig(self,debugString:str,param): """开启一些实验性选项。 Args: debugString(str):选项名称 ========================= ======================================================== "showDevTools" 开启开发者工具,此时param要填写开发者工具的资源路径 "wakeMinInterval" 设置帧率,默认值是10,值越大帧率越低 "drawMinInterval" 设置帧率,默认值是3,值越大帧率越低 "antiAlias" 设置抗锯齿渲染。param必须设置为"1" "minimumFontSize" 最小字体 "minimumLogicalFontSize" 最小逻辑字体 "defaultFontSize" 默认字体 "defaultFixedFontSize" 默认fixed字体 ========================= ======================================================== param : relate to debugString *注意*:开发者工具设置时,param必须是utf8编码,如file:///c:/miniblink-release/front_end/inspector.html。 """ debug=debugString.encode() if isinstance(param,str): param=param.encode() self.dll.wkeSetDebugConfig(self.cId,debug,param)
[文档] def setHeadlessEnabled(self,en:bool): """开启无头模式与否 开启后,将不会渲染页面,提升了网页性能。 Args: en(bool): True使能,False禁止 """ self.dll.wkeSetHeadlessEnabled(self.cId,en) return
[文档] def setTouchEnabled(self,en:bool): """开启触摸模式与否 开启后,鼠标事件转换为触摸事件 Args: en(bool): True使能,False禁止 """ b=not en self.dll.wkeSetTouchEnabled(self.cId,en) self.dll.wkeSetMouseEnabled(self.cId,b) return
[文档] def setDeviceParameter(self,device,paramStr,paramInt,paramFloat): """设置设备模拟器选项 void wkeSetDeviceParameter(wkeWebView webView, const char* device, const char* paramStr, int paramInt, float paramFloat) (已废弃)设置mb模拟的硬件设备环境。主要用在伪装手机设备场 device:设备的字符串。可取值有: =========================== ================================================================================= "navigator.maxTouchPoints" 此时 paramInt 需要被设置,表示 touch 的点数 "navigator.platform" 此时 paramStr 需要被设置,表示js里获取的 navigator.platform字符串 "navigator.hardwareConcurrency" 此时 paramInt 需要被设置,表示js里获取的 navigator.hardwareConcurrency 整数值 "screen.width" 此时 paramInt 需要被设置,表示js里获取的 screen.width 整数值 "screen.height" 此时 paramInt 需要被设置,表示js里获取的 screen.height 整数值 "screen.availWidth" 此时 paramInt 需要被设置,表示js里获取的 screen.availWidth 整数值 "screen.availHeight" 此时 paramInt 需要被设置,表示js里获取的 screen.availHeight 整数值 "screen.pixelDepth" 此时 paramInt 需要被设置,表示js里获取的 screen.pixelDepth 整数值 "screen.pixelDepth" 目前等价于"screen.pixelDepth" "window.devicePixelRatio" 同上 =========================== ================================================================================= """ device=device.encode() if device=='': device=b'' else: device=device.encode() self.dll.wkeSetDeviceParameter(self.cId, device,paramStr,c_int(paramInt),c_float(paramFloat)) return
[文档] def setNavigationToNewWindowEnable(self,en): """设置新窗口跳转允许 Args: en(bool): True允许,False禁止,所有新窗口跳转都在本窗口进行 """ self.dll.wkeSetNavigationToNewWindowEnable(self.cId,en) return
##############File##############
[文档] def goForward(self): """页面前进,在历史列表中前进 """ self.dll.wkeGoForward(self.cId)
[文档] def canGoForward(self): """页面是否能前进 """ return self.dll.wkeCanGoForward(self.cId)
[文档] def goBack(self): """网页页面回退 """ self.dll.wkeGoBack(self.cId)
[文档] def canGoBack(self): """页面是否能回退 """ return self.dll.wkeCanGoBack(self.cId)
[文档] def editorSelectAll(self): """页面全选 """ return self.dll.wkeEditorSelectAll(self.cId)
[文档] def editorUnSelect(self): """页面反选 """ return self.dll.wkeEditorUnSelect(self.cId)
[文档] def editorCopy(self): """页面选择复制 """ return self.dll.wkeEditorCopy(self.cId)
[文档] def editorCut(self): """页面选择复制 """ return self.dll.wkeEditorCut(self.cId)
[文档] def editorDelete(self): """页面选择删除 """ return self.dll.wkeEditorDelete(self.cId)
[文档] def editorUndo(self): """页面选择撤销 """ return self.dll.wkeEditorUndo(self.cId)
[文档] def editorRedo(self): """页面选择重做 """ return self.dll.wkeEditorRedo(self.cId)
[文档] def loadURL(self,url:str): """网页页面加载指定的链接地址 Args: url(str): 网页链接地址 """ return self.dll.wkeLoadURL(self.cId,url.encode())
[文档] def loadURLW(self,url): """网页页面加载指定的链接地址,unicode Args: url(str): 网页链接地址 """ return self.dll.wkeLoadURLW(self.cId,url)
[文档] def loadHTML(self,html:str): """网页页面加载指定的HTML内容,string Args: html(str): HTML内容 """ self.dll.wkeLoadHTML(self.cId,html.encode())
[文档] def loadHTMLW(self,html): """网页页面加载指定的HTML内容,unicode Args: html(str): HTML内容 """ self.dll.wkeLoadHTMLW(self.cId,html)
[文档] def loadFile(self,file_path): """网页页面加载指定的HTML文件 Args: file_path(str): HTML文件路径 """ file_path=file_path.encode() self.dll.wkeLoadFile(self.cId,file_path) return
[文档] def postURL(self,data): """ """ data=data.encode() lens=len(data) self.dll.wkeLoadURLW(self.cId,data,lens) return
[文档] def reload(self): """网页刷新 """ return self.dll.wkeReload(self.cId)
[文档] def stopLoading(self): """网页停止加载 """ return self.dll.wkeStopLoading(self.cId)
[文档] def getURL(self): """获取页面的地址 Returns: str: 地址 """ url=self.dll.wkeGetURL(self.cId) return url.decode()
[文档] def getFrameUrl(self,frameId): """获取页面的指定编号的frame的链接地址 Args: frameId(int): 帧编号 Returns: str: 地址 """ url=self.dll.wkeGetFrameUrl(self.cId,frameId) return url.decode('utf8')
[文档] def getSource(self): """获取页面的内容 Returns: str: 内容 """ source=self.dll.wkeGetSource(self.cId) return source.decode()
[文档] def utilSerializeToMHTML(self): """ Todo: API文档上没有这一段 """ mhtml_content=self.dll.wkeUtilSerializeToMHTML(self.cId) return mhtml_content
[文档] def setResponseData(self,job,data='',file_name=None): """ Todo: API文档上没有这一段 """ lens=len(data) if lens!=0: self.dll.wkeNetSetData(job,data,lens) return True elif file_name!=None: with open(file_name) as f: data=f.read() data=data.encode() lens=len(data) if lens!=0: if '.js' in file_name: self.dll.wkeNetSetMIMEType(job,b'text/javascript') elif '.html' in file_name: self.dll.wkeNetSetMIMEType(job,b'text/html') self.dll.wkeNetSetData(job,data,lens) return True return False
[文档] def cancelRequest(self,job,url,ident_ls=['.jpg']): """ FIXME: 没修正 """ for x in ident_ls: if x in url: self.dll.wkeNetCancelRequest(job) return True return False
[文档] def getPostData(self,job,url,ident=''): """ FIXME: 没修正 """ if ident not in url:return '',0,None elements=self.dll.wkeNetGetPostBody(job) try: data=elements.contents.element.contents.contents.data.contents.data lens=elements.contents.element.contents.contents.data.contents.length except: return '',0,None data=data[:lens].decode('utf8','ignore') print('post_data',data,lens) return data,lens,elements
[文档] def saveBufData(self,url,buf,lens): """ FIXME: 没修正 """ if lens==0:return contents=(c_char * lens).from_address(buf) _type=self.get_type(url) if _type==None:return name=binascii.crc32(url.encode()) file_name=f'{name}{_type}' try: with open(file_name,'wb') as f: f.write(contents) self.bufs.append({url:file_name}) except: ... finally: ...
##############Cookie##############
[文档] def setCookie(self,url,cookie): """设置页面cookie Args: url(int): 页面文件地址 cookie(str): 页面cookie字符串 Returns: str: 地址 .. note:: cookie必须符合curl的cookie写法。一个例子是: PERSONALIZE=123;expires=Monday, 13-Jun-2022 03:04:55 GMT; domain=.fidelity.com; path=/; secure """ cookie=cookie.split(';') for x in cookie: self.dll.wkeSetCookie(self.cId,url.encode('utf8'),x.encode('utf8')) #self.dll.wkePerformCookieCommand(self.cId,2) return
[文档] def getCookieW(self): """获取页面cookie Returns: str: 页面cookie字符串 """ return self.dll.wkeGetCookieW(self.cId)
[文档] def clearCookie(self): """清除页面cookie TODO: 官方文档说目前只支持清理所有页面的cookie。 """ self.dll.wkeClearCookie(self.cId)
[文档] def setLocalStorageFullPath(self,path): """设置local storage的全路径 *注意*:这个接口只能接受目录。如“c:\\mb\\LocalStorage\” """ self.dll.wkeSetLocalStorageFullPath(self.cId,path) return
[文档] def setCookieJarPath(self,path): """设置页面cookie的本地文件目录 Args: path(str): 页面cookie文件存储目录 默认是当前目录。cookies存在当前目录的“cookie.dat”里 """ return self.dll.wkeSetCookieJarPath(self.cId,path)
[文档] def setCookieJarFullPath(self,path): """设置页面cookie文件的全路径 Args: path(str): 页面cookie文件的全路径 设置cookie的全路径+文件名,如“c:\\mb\\cookie.dat” """ return self.dll.wkeSetCookieJarFullPath(self.cId,path)
##############JS##############
[文档] def getJsExec(self): return self.dll.wkeGlobalExec(self.cId)
[文档] def runJsCode(self,js_code:str): """页面执行一段指定的js代码 Args: js_code(str):指定的js代码 Returns: str: js代码执行结果 """ es=self.getJsExec() #闭包执行JS val=self.dll.wkeRunJSW(self.cId,js_code) val=self.dll.jsToStringW(es,val) if val=='undefined': val=None return val
[文档] def runJsFile(self,file_name): """页面执行指定路径的文件内容中的js代码 Args: file_name(str or path):指定的文件路径 Returns: str: js代码执行结果 """ with open(file_name) as f: js_code=f.read() return self.runJsCode(js_code)
[文档] def runJsFunc(self,funcName,paramList=[],thisValue=0): """页面主frame执行js函数 Args: funcName(str): js函数名 paramList(list): 参数列表 this_func(BO) Returns: str: js代码执行结果 TODO: NO VERIFY """ es=self.getJsExec() if thisValue == 0: funcName=funcName.encode() #获取window上的属性 func=self.dll.jsGetGlobal(es,funcName) else: pass argCount=len(paramList) argsList=(c_longlong *argCount)() for i,param in enumerate(paramList): if isinstance(param,str): param=self.dll.jsStringW(es,param) elif isinstance(param,int): param=self.dll.jsInt(c_longlong(param)) elif isinstance(param,float): param=self.dll.jsFloat(param) elif isinstance(param,bool): param=self.dll.jsBoolean(param) argsList[i]=param #调用js #jsValue jsCall(jsExecState es, jsValue func, jsValue thisValue, jsValue* args, int argCount) #调用一个func对应的js函数。如果此js函数是成员函数,则需要填thisValue。 否则可以传jsUndefined。args是个数组,个数由argCount控制。 func可以是从js里取的,也可以是自行构造的。 callRet=self.dll.jsCall(es,c_longlong(func),c_longlong(thisValue),byref(argsList),c_longlong(argCount)) val=self.dll.jsToStringW(es,c_longlong(callRet)) return val
[文档] def runJsByFrame(self,frameId,js_code,isInClosure=True): """页面指定frameId的frame上运行js Args: frameId(int): 页面中帧ID js_code(str): 指定的js代码 isInClosure(bool,optional): 是否在外层包个function() {}形式的闭包 Returns: str: js代码执行结果 NOTE: 如果需要返回值,在isInClosure为true时,需要写return,为false则不用 """ js_code=js_code.encode() val=self.dll.wkeRunJsByFrame(self.cId,frameId,js_code,isInClosure) es = self.dll.wkeGetGlobalExecByFrame(self.cId, frameId) val=self.dll.jsToTempStringW(es, c_longlong(val)) return val
##############SendEventMessage##############
[文档] def fireMouseEvent(self,msg,x,y,flags=0): """向页面发送鼠标事件 Args: message(wkeMouseMsg): 鼠标消息,取WkeConst.MK_LBUTTON等 x(int): 鼠标位置x坐标 y(int): 鼠标位置y坐标 flags(wkeMouseFlags): 可取值有WKE_CONTROL、WKE_SHIFT、WKE_LBUTTON、WKE_MBUTTON、WKE_RBUTTON,可通过“或”操作并联。 """ return self.dll.wkeFireMouseEvent(self.cId,msg,x,y,flags)
[文档] def fireMouseWheelEvent(self,msg,x,y,delta,flags=0): """向页面发送鼠标滚轮事件 Args: message(wkeMouseMsg): 鼠标消息,取WkeConst.MK_LBUTTON等 x(int): 鼠标位置x坐标 y(int): 鼠标位置y坐标 delta(int), 滚轮进度 flags(wkeMouseFlags): 可取值有WKE_CONTROL、WKE_SHIFT、WKE_LBUTTON、WKE_MBUTTON、WKE_RBUTTON,可通过“或”操作并联。 """ return self.dll.wkeFireMouseWheelEvent(self.cId,msg,x,y,flags)
[文档] def fireKeyDownEvent(self,virtualKeyCode,flags=0): """向页面发送键盘按下事件 Args: virtualKeyCode(int): 键的字符代码。 flags(wkeKeyFlags): 重复计数、扫描代码、扩展键标志、上下文代码、以前的键状态标志和转换状态标志 Return: int: 如果应用程序处理此消息,则应返回零。 WM_CHAR消息的The character code of the key.见https://msdn.microsoft.com/en-us/library/windows/desktop/ms646276(v=vs.85).aspx """ return self.dll.wkeFireKeyDownEvent(self.cId,virtualKeyCode,flags,False)
[文档] def fireKeyUpEvent(self,virtualKeyCode,flags=0): """向页面发送键盘弹起事件 Args: virtualKeyCode(int): 键的字符代码。 flags(wkeKeyFlags): 重复计数、扫描代码、扩展键标志、上下文代码、以前的键状态标志和转换状态标志 Return: int: 如果应用程序处理此消息,则应返回零。 """ return self.dll.wkeFireKeyUpEvent(self.cId,virtualKeyCode,flags,False)
[文档] def fireKeyPressEvent(self,virtualKeyCode,flags=0): """向页面发送键盘弹起事件 Args: virtualKeyCode(int): 键的字符代码。 flags(wkeKeyFlags): 重复计数、扫描代码、扩展键标志、上下文代码、以前的键状态标志和转换状态标志 Return: int: 如果应用程序处理此消息,则应返回零。 """ return self.dll.wkeFireKeyPressEvent(self.cId,virtualKeyCode,flags,False)
[文档] def fireWindowsMessage(self,msg,wParam,lParam): """向页面发送windows消息事件 Args: msg(win32con): 消息 wParam : 消息参数 lParam : 消息参数 Return: int: 如果应用程序处理此消息,则应返回零。 向mb发送任意windows消息。不过目前mb主要用来处理光标相关。mb在无窗口模式下,要响应光标事件,需要通过本函数手动发送光标消息 """ #byref( result = c_int(-1) self.dll.wkeFireWindowsMessage(self.cId,self.hwnd,msg,wParam,lParam,byref(result)) return result.value
##############OnEvent##############
[文档] def onAlertBox(self,func,param,*args,**kwargs): """ 设置网页调用alert的回调 """ return Wke.event.onAlertBox(self,func,param,*args,**kwargs)
[文档] def onConfirmBox(self,func,param,*args,**kwargs): """ 设置网页调用confirmBox的回调 """ return Wke.event.onConfirmBox(self,func,param,*args,**kwargs)
[文档] def onConsole(self,func,param,*args,**kwargs): """ 设置网页调用console触发的回调 """ return Wke.event.onConsole(self,func,param,*args,**kwargs)
[文档] def onCreateView(self,func,param,*args,**kwargs): """ 设置创建新窗口时的回调 """ return Wke.event.onCreateView(self,func,param,*args,**kwargs)
[文档] def onDocumentReady2(self,func,param,*args,**kwargs): """ 设置文档就绪时的函数 """ return Wke.event.onDocumentReady2(self,func,param,*args,**kwargs)
[文档] def onDownload(self,func,param,*args,**kwargs): """ 设置网页开始下载的回调 """ return Wke.event.onDownload(self,func,param,*args,**kwargs)
[文档] def onGetFavicon(self,func,param,*args,**kwargs): """ 设置获取favicon的回调 """ return Wke.event.onGetFavicon(self,func,param,*args,**kwargs)
[文档] def onLoadUrlBegin(self,func,param,*args,**kwargs): """ 设置网络请求发起前的回调 """ return Wke.event.onLoadUrlBegin(self,func,param,*args,**kwargs)
[文档] def onLoadUrlEnd(self,func,param,*args,**kwargs): """ 设置网络请求结束的回调 """ return Wke.event.onLoadUrlEnd(self,func,param,*args,**kwargs)
[文档] def onLoadUrlFail(self,func,param,*args,**kwargs): """ 设置网络请求失败的回调 """ return Wke.event.onLoadUrlFail(self,func,param,*args,**kwargs)
[文档] def onLoadUrlFinish(self,func,param,*args,**kwargs): """ 设置网络请求完成的回调 """ return Wke.event.onLoadUrlFinish(self,func,param,*args,**kwargs)
[文档] def onMouseOverUrlChanged(self,func,param,*args,**kwargs): """ 设置鼠标划过链接元素的回调 """ return Wke.event.onMouseOverUrlChanged(self,func,param,*args,**kwargs)
[文档] def onNavigation(self,func,param,*args,**kwargs): """ 设置网页开始浏览的回调 """ return Wke.event.onNavigation(self,func,param,*args,**kwargs)
[文档] def onNetResponse(self,func,param,*args,**kwargs): """ 设置收到网络请求的回调 """ return Wke.event.onNetResponse(self,func,param,*args,**kwargs)
[文档] def onPaintBitUpdated(self,func,param,*args,**kwargs): """ 设置窗口绘制刷新时回调 """ return Wke.event.onPaintBitUpdated(self,func,param,*args,**kwargs)
[文档] def onPaintUpdated(self,func,param,*args,**kwargs): """ 设置窗口绘制刷新时回调 """ return Wke.event.onPaintUpdated(self,func,param,*args,**kwargs)
[文档] def onPromptBox(self,func,param,*args,**kwargs): """ 设置网页调用PromptBox的回调 """ return Wke.event.onPromptBox(self,func,param,*args,**kwargs)
[文档] def onTitleChanged(self,func,param,*args,**kwargs): """ 设置标题变化的回调 """ return Wke.event.onTitleChanged(self,func,param,*args,**kwargs)
[文档] def onURLChanged2(self,func,param,*args,**kwargs): """ 设置标题变化的回调 """ return Wke.event.onURLChanged2(self,func,param,*args,**kwargs)
[文档] def onWindowClosing(self,func,param,*args,**kwargs): """ 设置窗口关闭时回调 """ return Wke.event.onWindowClosing(self,func,param,*args,**kwargs)
[文档] def onWindowDestroy(self,func,param,*args,**kwargs): """ 设置窗口销毁时回调 """ return Wke.event.onWindowDestroy(self,func,param,*args,**kwargs)
[文档] class WebWindow(WebView): """Wke网页视图带窗口 """ def __init__(self,*args,**kwargs): super().__init__(*args,**kwargs) return
[文档] def create(self,parent=0,x=0,y=0,width=480,height=320,_type=0): """创建一个带真实窗口的wkeWebView .. code:: c wkeWebView wkeCreateWebWindow(wkeWindowType type, HWND parent, int x, int y, int width, int height); Args: _type(int): 窗口类型 ============================ ===== ============================ WKE_WINDOW_TYPE_POPUP 0 普通窗口 WKE_WINDOW_TYPE_TRANSPARENT 1 透明窗口。mb内部通过layer window实现 WKE_WINDOW_TYPE_CONTROL 2 嵌入在父窗口里的子窗口。此时parent需要被设置 ============================ ===== ============================ """ self.cId = self.dll.wkeCreateWebWindow(_type,parent,x,y,width,height) self.type = _type self.x,self.y = x,y self.w,self.h = width,height return self.cId
[文档] def build(self,hwnd,x=0,y=0,width=640,height=480,_type=2): """为一个真实窗口绑定一个wkeWebWindow Args: hwnd (int): 窗口句柄 x (int): 窗口绑定区域左上角起始点的x坐标 y (int): y坐标 width (int): 宽度 height (int): 高度 """ if hwnd==0: return 0 self.cId = self.dll.wkeCreateWebWindow(2,hwnd,x,y,width,height) self.type = _type self.hwnd = hwnd #self.dll.wkeShowWindow(id,show) self.x,self.y = x,y self.w,self.h = width,height return
[文档] def setWindow(self,_type=0,hwnd=0,x=0,y=0,width=360,height=480): self.type = _type self.hwnd = hwnd self.x = x self.y = y self.w = width self.h = height return
[文档] def destroy(self): """销毁wkeWebView对应的所有数据结构,包括真实窗口等 """ self.dll.wkeDestroyWebWindow(self.cId) return