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
   



_______________________________________________
Python-win32 mailing list
Python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to