#-*- coding:utf-8 -*-
import win32com.client, pythoncom
import time
ie = win32com.client.DispatchEx('InternetExplorer.Application.1')
ie.Visible = 1
ie.Navigate('http://ieeexplore.ieee.org/xpl/periodicals.jsp')
time.sleep( 5 )
ie.Document.getElementById("browse_keyword").value ="Computer"
ie.Document.getElementsByTagName("input")[24].click()
import win32com.client, pythoncom
import time
ie = win32com.client.DispatchEx('InternetExplorer.Application')
ie.Visible = 1
ie.Navigate('www.baidu.com')
time.sleep(5)
print 'browse_keword'
ie.Document.getElementById("kw").value ="Computer"
ie.Document.getElementById("su").click()
print 'Done!'
运行第一段代码时,将弹出:
ie.Document.getElementById("browse_keyword").value ="Computer"
TypeError: getElementById() takes exactly 1 argument (2 given)
第二段代码运行正常。使结果不同的区别是什么?
对Python中实例的方法的调用会自动将实例添加为第一个参数-这就是为什么必须在方法中显式地编写“self”参数的原因。
例如,
instance.method(args...)
等于Class.method(instance, args...)
。从我看来,程序员一定忘了写self关键字,结果破坏了方法。尝试查看库代码内部。
作为
COMObject
的一种方法,getElementById
由win32com
动态构建。在我的计算机上,如果url是http://ieeexplore.ieee.org/xpl/periodicals.jsp,它几乎等于
如果网址是www.baidu.com,它几乎相当于
显然,如果您将参数传递给第一个代码,您将收到一个
TypeError
。但如果您尝试直接使用它,即调用ie.Document.getElementById()
,则不会收到TypeError
,而是收到com_error
。为什么
win32com
构建了错误的代码?让我们看看
ie
和ie.Document
。它们都是COMObject
,更准确地说,是win32com.client.CDispatch
实例。CDispatch
只是一个包装类。核心是属性_oleobj_
,其类型是PyIDispatch
。要构建
getElementById
,win32com
需要从_oleobj_
获取getElementById
方法的类型信息。大致上,win32com
使用以下过程funcdesc
包含几乎所有的导入信息,例如参数的数量和类型。如果url是http://ieeexplore.ieee.org/xpl/periodicals.jsp,
funcdesc.args
是()
,而相应的funcdesc.args
应该是((8, 1, None),)
。总之,长话短说,
win32com
检索到了错误的类型信息,从而建立了错误的方法 我不知道该怪谁,PyWin32或IE。但根据我的观察,我发现PyWin32的代码没有任何错误。另一方面,以下脚本在Windows脚本主机中运行得很好。邓肯已经指出IE的兼容模式可以防止这个问题。不幸的是,似乎无法从脚本启用兼容模式。
但我发现了一个技巧,可以帮助我们绕过这个问题。
首先,您需要访问一个好的站点,它为我们提供一个HTML页面,并从中检索一个正确的
Document
对象。然后跳转到不起作用的页面
现在您可以通过旧的
Document
对象访问第二页的DOM。如果使用新的
Document
对象,将再次获得TypeError
。这两种情况之间的差异与您指定的COM名称无关:无论是
InternetExplorer.Application
还是InternetExplorer.Application.1
都会产生完全相同的CLSID,从而为您提供IWebBrowser2
接口。运行时行为的差异完全取决于您检索到的URL。这里的区别可能是,工作的页面是HTML,而另一个页面是XHTML;或者可能只是失败页面中的错误阻止了DOM的正确初始化。不管它是IE9解析器的“特性”。
请注意,如果启用兼容模式,则不会发生这种情况(在下面的第二行单击地址栏中的兼容模式图标之后):
不幸的是,我不知道如何从脚本切换兼容模式(不能设置
documentMode
属性)。也许其他人知道?我认为,错误的参数计数来自COM:Python传入参数,COM对象以误导性错误拒绝调用。
相关问题 更多 >
编程相关推荐