[python-win32] IE HTML DOM events

Richard Liao richard-liao at 163.com
Mon Aug 28 17:43:49 CEST 2006


Hi,

I have a win32com application need to get IE HTML DOM events. 
I searched web for a few days, and I have found 4 methods to approach that.

Sorry about this long text, because I want to give more hint.


1. method 1
#----------------------------------------------------------------------
#	method 1
#   Make an instant of DocEvents(subclass of HTMLDocumentEvents2)
#   It will take a long time(about tens of seconds) to generate / compile 
#   3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py in directory gen_py
#   when execute code 'EnsureModule(...)' if this file did not exist. 
#----------------------------------------------------------------------

from win32com.client import gencache, Dispatch
import time

docmod = gencache.EnsureModule('{3050F1C5-98B5-11CF-BB82-00AA00BDCE0B}', 0, 4, 0)

class DocEvents(docmod.HTMLDocumentEvents2):
    def __init__(self, doc):
        docmod.HTMLDocumentEvents2.__init__(self, doc)

    def Ononclick(self, event):
        print 'onclick'

        ev = gencache.EnsureDispatch(event)
        elem = ev.srcElement
        
        print 'tagName' 	, elem.tagName
        print 'id' 			, elem.id
        print 'innerText' 	, elem.innerText
        print 'clientX' 	, ev.clientX
        print 'clientY' 	, ev.clientY
        print 'body text'	, doc.body.createTextRange().text
           
ie = Dispatch("InternetExplorer.Application")
ie.Navigate('http://www.google.com')
ie.Visible = 1

while ie.Busy:
    time.sleep(0.1)

doc = ie.Document
d = DocEvents(doc)

#----------------------------------------------------------------------
#   end of method 1
#----------------------------------------------------------------------

#----------------------------------------------------------------------
#   output of method 1
#----------------------------------------------------------------------
"""
onclick
tagName B
id 
innerText Web
clientX 172
clientY 182
body textpythoncom error: Python error invoking COM method.

Traceback (most recent call last):
  File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 285, in _Invoke_
    return self._invoke_(dispid, lcid, wFlags, args)
  File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 290, in _invoke_
    return S_OK, -1, self._invokeex_(dispid, lcid, wFlags, args, None, None)
  File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 588, in _invokeex_
    return func(*args)
  File "D:\project\python\Test\ie-event-method-1.py", line 29, in Ononclick
    print 'body text'   , doc.body.createTextRange().text
  File "C:\Python24\Lib\site-packages\win32com\client\__init__.py", line 454, in __getattr__
    raise AttributeError, "'%s' object has no attribute '%s'" % (repr(self), attr)
exceptions.AttributeError: '<win32com.gen_py.Microsoft HTML Object Library.IHTMLElement instance at 0x37223760>' object has no attribute 'createTextRange'
"""
#----------------------------------------------------------------------
#   end of output 1
#----------------------------------------------------------------------


2. method 2
#----------------------------------------------------------------------
#	method 2
#   Dispatch ie.Document with DocEvents(subclass of HTMLDocumentEvents2)
#   It will take a long time(about tens of seconds) to generate / compile 
#   3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py in directory gen_py
#   when execute code 'EnsureModule(...)' if this file did not exist. 
#----------------------------------------------------------------------

from win32com.client import gencache, Dispatch, DispatchWithEvents
import time


docmod = gencache.EnsureModule('{3050F1C5-98B5-11CF-BB82-00AA00BDCE0B}' ,0 ,4, 0)

class DocEvents(docmod.HTMLDocumentEvents2):
    def Ononclick(self):
        print 'onclick'

        ev = doc.parentWindow.event
        elem = ev.srcElement

        print 'tagName' 	, elem.tagName
        print 'id' 			, elem.id
        print 'innerText' 	, elem.innerText
        print 'clientX' 	, ev.clientX
        print 'clientY' 	, ev.clientY
        print 'body text'	, doc.body.createTextRange().text

ie = Dispatch('InternetExplorer.Application')
ie.Visible = 1
ie.Navigate('http://www.google.com')

while ie.Busy:
    time.sleep(0.1)

doc = ie.Document
d = DispatchWithEvents(doc, DocEvents)

#----------------------------------------------------------------------
#   end of code 2
#----------------------------------------------------------------------

#----------------------------------------------------------------------
#   output of method 2
#----------------------------------------------------------------------
"""

onclick
tagName B
id 
innerText Web
clientX 171
clientY 176
body textpythoncom error: Python error invoking COM method.

Traceback (most recent call last):
  File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 285, in _Invoke_
    return self._invoke_(dispid, lcid, wFlags, args)
  File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 290, in _invoke_
    return S_OK, -1, self._invokeex_(dispid, lcid, wFlags, args, None, None)
  File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 588, in _invokeex_
    return func(*args)
  File "D:\project\python\Test\ie-event-method-2.py", line 27, in Ononclick
    print 'body text'   , doc.body.createTextRange().text
  File "C:\Python24\Lib\site-packages\win32com\client\__init__.py", line 454, in __getattr__
    raise AttributeError, "'%s' object has no attribute '%s'" % (repr(self), attr)
exceptions.AttributeError: '<win32com.gen_py.Microsoft HTML Object Library.IHTMLElement instance at 0x37223880>' object has no attribute 'createTextRange'
"""
#----------------------------------------------------------------------
#   end of output 2
#----------------------------------------------------------------------



3. method 3
#----------------------------------------------------------------------
#	method 3
#   Use WithEvents(not a subclass of HTMLDocumentEvents2)
#   This method will also take a long time to generate / compile
#   3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py in directory gen_py
#   when execute code 'WithEvents(...)' if this file did not exist. 
#----------------------------------------------------------------------

from win32com.client import Dispatch, WithEvents
import time

class DocEvents:  
    def Ononclick(self):
        print 'onclick'

        ev = doc.parentWindow.event
        elem = ev.srcElement

        print 'tagName' 	, elem.tagName
        print 'id' 			, elem.id
        print 'innerText' 	, elem.innerText
        print 'clientX' 	, ev.clientX
        print 'clientY' 	, ev.clientY
        print 'body text'	, doc.body.createTextRange().text

ie = Dispatch("InternetExplorer.Application")
ie.Visible = 1
ie.Navigate('http://www.google.com')

while ie.Busy:
    time.sleep(0.1)

doc = ie.Document
d = WithEvents(doc, DocEvents)

#----------------------------------------------------------------------
#   end of code 3
#----------------------------------------------------------------------

#----------------------------------------------------------------------
#   output of method 3 (when this code run first time, 
#	ie, 3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py *NOT* exist)
#----------------------------------------------------------------------
"""
onclick
tagName B
id 
innerText Web
clientX 168
clientY 182
body text Personalized Home | Sign in




Web    Images    VideoNew!    News    Maps    more ?Books
Froogle
Groups
even more ?

 
  Advanced Search
  Preferences
  Language Tools



Advertising Programs - Business Solutions - About Google 
Make Google Your Homepage!
?2006 Google
"""
#----------------------------------------------------------------------
#   end of output 3 
#	(3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py *NOT* exist)
#----------------------------------------------------------------------



#----------------------------------------------------------------------
#   output of method 3 (when this code run another time, 
#	ie, 3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py *DO* exist)
#----------------------------------------------------------------------
"""
onclick
tagName B
id 
innerText Web
clientX 172
clientY 182
body textpythoncom error: Python error invoking COM method.

Traceback (most recent call last):
  File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 285, in _Invoke_
    return self._invoke_(dispid, lcid, wFlags, args)
  File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 290, in _invoke_
    return S_OK, -1, self._invokeex_(dispid, lcid, wFlags, args, None, None)
  File "C:\Python24\Lib\site-packages\win32com\server\policy.py", line 588, in _invokeex_
    return func(*args)
  File "D:\project\python\Test\ie-event-method-3.py", line 24, in Ononclick
    print 'body text'   , doc.body.createTextRange().text
  File "C:\Python24\Lib\site-packages\win32com\client\__init__.py", line 454, in __getattr__
    raise AttributeError, "'%s' object has no attribute '%s'" % (repr(self), attr)
exceptions.AttributeError: '<win32com.gen_py.Microsoft HTML Object Library.IHTMLElement instance at 0x43431616>' object has no attribute 'createTextRange'
"""
#----------------------------------------------------------------------
#   end of output 3 
#	(3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py *DO* exist)
#----------------------------------------------------------------------




4. method 4
#----------------------------------------------------------------------
#	method 4
#   Try to use attachEvent, but never worked
#----------------------------------------------------------------------

from win32com.client import Dispatch
import time

class DocEvents:  
    def Ononclick(self):
        print 'onclick'

        ev = doc.parentWindow.event
        elem = ev.srcElement

        print 'tagName' 	, elem.tagName
        print 'id' 			, elem.id
        print 'innerText' 	, elem.innerText
        print 'clientX' 	, ev.clientX
        print 'clientY' 	, ev.clientY
        print 'body text'	, doc.body.createTextRange().text

ie = Dispatch("InternetExplorer.Application")
ie.Visible = 1
ie.Navigate('http://www.google.com')

while ie.Busy:
    time.sleep(0.1)

doc = ie.Document
#doc.attachEvent('onclick',DocEvents.Ononclick)
doc.attachEvent('onclick',DocEvents)

#----------------------------------------------------------------------
#   end of code 4
#----------------------------------------------------------------------

#----------------------------------------------------------------------
#   output of method 4
#----------------------------------------------------------------------
"""
Traceback (most recent call last):
  File "C:\Python24\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 310, in RunScript
    exec codeObject in __main__.__dict__
  File "D:\project\python\Test\ie-event-method-4.py", line 31, in ?
    doc.attachEvent('onclick',DocEvents)
  File "C:\Python24\lib\site-packages\win32com\gen_py\3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py", line 9518, in attachEvent
    , pdisp)
ValueError: argument is not a COM object
"""
#----------------------------------------------------------------------
#   end of output 4
#----------------------------------------------------------------------


5. method 5
#----------------------------------------------------------------------
#	method 5
#   Don't handle DOM events, always works right 
#	when 3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py not exist
#----------------------------------------------------------------------

from win32com.client import Dispatch
import time

ie = Dispatch("InternetExplorer.Application")
ie.Visible = 1
ie.Navigate('http://www.google.com')

while ie.Busy:
    time.sleep(0.1)

doc = ie.Document

print doc.body.createTextRange().text
#----------------------------------------------------------------------
#   end of code 5
#----------------------------------------------------------------------

#----------------------------------------------------------------------
#   output of method 5
#	(3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py not exist)
#----------------------------------------------------------------------
"""
Personalized Home | Sign in




Web    Images    VideoNew!    News    Maps    more ?Books
Froogle
Groups
even more ?

 
  Advanced Search
  Preferences
  Language Tools



Advertising Programs - Business Solutions - About Google 
Make Google Your Homepage!
?2006 Google
"""
#----------------------------------------------------------------------
#   end of output 5
#	(3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py not exist)
#----------------------------------------------------------------------


#----------------------------------------------------------------------
#   output of method 5
#	(3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py DO exist)
#----------------------------------------------------------------------
"""
Traceback (most recent call last):
  File "C:\Python24\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 310, in RunScript
    exec codeObject in __main__.__dict__
  File "D:\project\python\Test\ie-event-method-5.py", line 19, in ?
    print doc.body.createTextRange().text
  File "C:\Python24\Lib\site-packages\win32com\client\__init__.py", line 454, in __getattr__
    raise AttributeError, "'%s' object has no attribute '%s'" % (repr(self), attr)
AttributeError: '<win32com.gen_py.Microsoft HTML Object Library.IHTMLElement instance at 0x37747768>' object has no attribute 'createTextRange'
"""
#----------------------------------------------------------------------
#   end of output 5
#	(3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py DO exist)
#----------------------------------------------------------------------



method 1,2,3,5 can work, not method 4.

My result is:

method 1,2 works right when try 'elem.tagName', 'elem.id', 'elem.innerText', 'ev.clientX',
but never works when try 'doc.body.createTextRange()' whether file
'3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py' exist. 

*** method 3 works right when '3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py' do NOT exist ***,
but works like method 1,2 when file '3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py' exist.

method 4 never get works, just I think may be works. 

method 5 can always works when file '3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py' NOT exist,
but never works when file '3050F1C5-98B5-11CF-BB82-00AA00BDCE0Bx0x4x0.py' DO exist.

These code run under:
Windows XP SP2
Internet Explorer 6.0.2900.2180.xpsp_sp2_rtm.040803-2158
PythonWin 2.4.3 (#69, Apr 11 2006, 15:32:42) [MSC v.1310 32 bit (Intel)] on win32.
pywin32 build 209

My question:
It looks like that:
'doc.body.createTextRange()' never works right, whenever makepy.py generate 
{3050F1C5-98B5-11CF-BB82-00AA00BDCE0B} python wrapper before run these code,

Noticed that in method 3,  'd = WithEvents(doc, DocEvents)' will generate this wrapper, but works right
at first time when this wrapper not generate before.
But works wrong when this wrapper already exist.

I don't know why this wrapper effect method 5, since method 5 never handle {3050F1C5-98B5-11CF-BB82-00AA00BDCE0B}.

Method 1,2 always generate this wrapper file, and never works right whether this wrapper exist.

And I notice that, when generate this wrapper file, my application memory consumption will grow up to 180MB, and
60MB when do not generate it.

Any advice will be appreciated.

Thanks,
Richard
   





More information about the Python-win32 mailing list