2012-01-03 30 views
6

Tôi đang cố gắng xem xét DOM của IE từ một luồng riêng biệt gửi đi IE và một số thuộc tính tôi nhận được lỗi "không có giao diện được hỗ trợ". Tôi đã quản lý để giảm sự cố cho tập lệnh này:python, COM và vấn đề đa luồng

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() 

Mọi thứ đều ổn cho đến khi frame.contentWindow. Sau đó, 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) 

Bất kỳ gợi ý nào?

+1

Trực giao cho câu hỏi của bạn: cập nhật lên Python2.7; hãy thử [selenium] (http://selenium.googlecode.com/svn/trunk/docs/api/py/index.html) – jfs

+0

Không phải là một tùy chọn ngay bây giờ; Tôi đang ở trong một bối cảnh thương mại và chúng tôi làm nhiều hơn những gì Selen làm. Chúng tôi đang trên con đường để nâng cấp Python mặc dù :) Chúng tôi tìm thấy một workaround bằng cách sử dụng căn hộ thay vì miễn phí luồng và marshalling thứ bằng tay nhưng tôi vẫn tò mò. – fraca7

Trả lời

1

Câu trả lời đúng là sắp xếp công cụ bằng tay. Đó không phải là một cách giải quyết nó là những gì bạn có nghĩa vụ phải làm ở đây. Bạn không cần phải sử dụng luồng căn hộ mặc dù.

Bạn khởi tạo làm căn hộ đa luồng - cho biết rằng có thể gọi giao diện của bạn trên bất kỳ chuỗi nào. Nó không cho phép bạn gọi các giao diện khác trên bất kỳ chuỗi nào, hoặc xin lỗi bạn từ các giao diện marshalling do COM cung cấp. Điều đó sẽ chỉ hoạt động "do tai nạn" - Ví dụ: nếu đối tượng bạn đang gọi xảy ra là một đối tượng MTA trong quá trình, nó sẽ không thành vấn đề.

CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream hoạt động kinh doanh.

Lý do cho điều này là các đối tượng có thể cung cấp proxy của riêng mình, có thể hoặc không thể được tạo luồng. (Hoặc thực sự cung cấp tùy chỉnh marshalling). Bạn phải sắp xếp họ để nói với họ rằng họ đang di chuyển giữa các chủ đề. Nếu proxy được tự do chuỗi, bạn có thể nhận được cùng một con trỏ trở lại.