2012-01-03 52 views
6

私は、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まで大丈夫です。次に、バム:

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へのアップデート。 try [selenium](http://selenium.googlecode.com/svn/trunk/docs/api/py/index.html) – jfs

+0

オプションは現在ありません。私は商業的な状況にあり、セレンが行うよりもはるかに多くを行います。私たちはPythonをアップグレードする方法をしています:)私たちは無料のスレッディングと手作業によるマーシャリングの代わりにアパートを使用して回避策を見つけましたが、私はまだ不思議です。 – fraca7

答えて

1

正しい答えは、手作業によるものです。それはあなたがここでやろうとしている解決策ではありません。あなたはアパートのスレッドを使用する必要はありません。あなたがマルチスレッドアパートメントとして初期化

- それはがどのスレッドであなたのインターフェースを呼び出すことができますCOMに指示します。 ではなく、を使用すると、任意のスレッド上で他のインターフェイスを呼び出すことができます。また、COMによって提供されるインターフェイスをマーシャリングすることはできません。それは「偶然に」機能します。呼び出すオブジェクトがインプロセスのMTAオブジェクトである場合は問題にはなりません。

CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStreamです。

これは、オブジェクトが独自のプロキシを提供できるため、フリースレッドである場合とそうでない場合があります。 (または実際にカスタムマーシャリングを提供します)。それらをマーシャリングしてスレッド間を移動していることを伝える必要があります。プロキシがフリースレッドである場合、同じポインタを戻すことがあります。

関連する問題