2012-01-03 40 views
6

我試圖從IE調用IE的單獨線程來看看IE的DOM,對於一些屬性我得到一個「沒有這樣的接口支持」的錯誤。我設法降低問題這個腳本:python,COM和多線程問題

import threading, time 

import pythoncom 
from win32com.client import Dispatch, gencache 
gencache.EnsureModule('{3050F1C5-98B5-11CF-BB82-00AA00BDCE0B}', 0, 4, 0) # MSHTML 

def main(): 
    pythoncom.CoInitializeEx(0) 
    ie = Dispatch('InternetExplorer.Application') 
    ie.Visible = True 
    ie.Navigate('http://www.Rhodia-ecommerce.com/') 
    while ie.Busy: 
     time.sleep(1) 

    def printframes(): 
     pythoncom.CoInitializeEx(0) 
     document = ie.Document 
     frames = document.getElementsByTagName(u'frame') 
     for frame in frames: 
      obj = frame.contentWindow 

    thr = threading.Thread(target=printframes) 
    thr.start() 
    thr.join() 

if __name__ == '__main__': 
    thr = threading.Thread(target=main) 
    thr.start() 
    thr.join() 

一切都很好,直到frame.contentWindow。然後bam:

Exception in thread Thread-2: 
Traceback (most recent call last): 
    File "C:\python22\lib\threading.py", line 414, in __bootstrap 
    self.run() 
    File "C:\python22\lib\threading.py", line 402, in run 
    apply(self.__target, self.__args, self.__kwargs) 
    File "testie.py", line 42, in printframes 
    obj = frame.contentWindow 
    File "C:\python22\lib\site-packages\win32com\client\__init__.py", line 455, in __getattr__ 
    return self._ApplyTypes_(*args) 
    File "C:\python22\lib\site-packages\win32com\client\__init__.py", line 446, in _ApplyTypes_ 
    return self._get_good_object_(
com_error: (-2147467262, 'No such interface supported', None, None) 

任何提示?

+1

正交於您的問題:更新到Python2.7;嘗試[硒](http://selenium.googlecode.com/svn/trunk/docs/api/py/index.html) – jfs 2012-01-03 18:47:16

+0

現在不是一個選項;我處於商業環境中,而且我們的工作遠遠超過了Selenium。儘管我們正在升級Python的方法:)我們通過使用公寓而不是免費的線程和編組東西來找到解決方法,但我仍然好奇。 – fraca7 2012-01-04 07:59:25

回答

1

正確的答案是手動編組東西。這不是一個解決方法,這是你應該在這裏做的。你不應該使用公寓線程。

你初始化爲多線程單元 - 告訴COM該可以調用你的接口在任何線程。它不會而不是允許你調用任何線程上的其他接口,或者原諒你從COM提供的編組接口。這隻會「偶然」發生 - 例如如果您所調用的對象恰好是一個進程內MTA對象,則無關緊要。

CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream做生意。

這樣做的原因是對象可以提供自己的代理,這些代理可以是也可以不是自由線程的。 (或者確實提供自定義編組)。你必須編組他們,告訴他們他們正在線程之間移動。如果代理是自由線程的,則可能會返回相同的指針。