Get all URLs from a webpage

This example shows how to automate Microsoft Internet Explorer with Python/Pywin32.

It
opens a Internet Explorer window, surfs to www.goermezer.de (and waits 3
sec to load the page), and prints all links of the loaded page.

Some links to the Object Model of Microsoft Internet Explorer:

Microsoft ActiveX control

DHTML Objects 

IHTMLDocument2 Interface

import win32com.client, time
ie = win32com.client.Dispatch("InternetExplorer.Application") 
ie.Visible = 1 
ie.Navigate('http://www.goermezer.de') 
time.sleep(3) #wait 3 sec. 
print 'You are surfing on', ie.Document.domain 
print 'And now a list of the Links:' 
for i in ie.Document.links: 
    print i

A simple Excel to PDF Converter

This is a simple PDF Converter which watches in a directory for
incoming Excel documents and converts them to PDF. Ghostscript and a
Postscript printer has to be installed.

path_to_watch = "D:\\share\\"
before = dict ([(f, None) for f in os.listdir (path_to_watch)]) def convert(filename): tmpfile = path_to_watch + 'tmp\\'+filename+'.ps' if filename[-3:]=='xls': pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED) myExcel = win32com.client.DispatchEx('Excel.Application') Excel = myExcel.Workbooks.Open(path_to_watch+filename, 0, False, 2) Excel.PrintOut(1, 5000, 1, False, 'Rumborak PDF-Writer Plus 1.0 RC5', \ True, False, tmpfile) Excel.Saved = 1 Excel.Close() myExcel.Quit() del Excel del myExcel os.popen('c:\\gs\\gs8.15\\bin\\gswin32c.exe -sDEVICE=pdfwrite -r300 -dNOPAUSE \ -dBATCH -dSAFER -sPAPERSIZE=a4 \ -sOutputFile="'+path_to_watch+filename+'.pdf" "'+tmpfile+'"') #os.remove(path_to_watch+filename) os.remove(tmpfile) pythoncom.CoUninitialize() while 1: time.sleep (0.1) after = dict ([(f, None) for f in os.listdir (path_to_watch)]) added = [f for f in after if not f in before] if added and added[0][-3:]=='xls': starttime = time.clock() print "File ", ", ".join (added), "added to queue" convert(added[0]) stoptime = time.clock() print "OK. It took", stoptime-starttime, 'seconds.\n' before = after

makepy – early u. late binding von COM Objekten (german)

Python nutzt das Modul win32com der Windows-Erweiterung Pywin32 zur Automatisierung von Applikationen über COM (Component ObjectModel). Man spricht hier auch von COM-Automation. Dabei unterscheidet es zwischen early- sowie late-binding. Um nicht zu weit auszuholen, versuche ich es hier einmal kurz auf den Punkt zu bringen:

Late-binding: Python kennt keine Methoden und Attribute der Objektbibliothek, die per COM angesprochen und automatisiert werden soll.

Early-binding: Python kennt alle Methoden und Attribute der Objektbibliothek, die per COM angesprochen und automatisiert werden soll.

Was macht das für einen Unterschied ?

Nun, zunächst hat das early-binding Performance-Vorteile bei der Ausführung der Python-Programme. Aber dafür müssen einmalig vor Ausführen der Anwendungen sog. Cachefiles für die genutzten Bibliotheken erzeugt werden. Das kann je nach größe und Anzahl der Bibliothek recht lange dauern. Ein Trost ist, dass dieser Prozess nur ein einziges Mal durchgeführt werden muss. Danach sind bei jeder Ausführung der Python-Programme die Cachefiles noch
vorhanden und werden genutzt.

Ein weiterer Vorteil des early-bindings betrifft das Editieren im Pythonwin-Editor. Da durch die Cachefiles alle Methoden und Attribute Python bekannt sind, sind sie auch Pythonwin bekannt. Das bedeutet, dass während des Editierens nach den ersten Buchstaben
der Pythoncode vervollständigt wird. Das macht das Programmieren wesentlich komfortabler.

Man kann aber generell keine Empfehlung abgeben, ob man early- oder late-binding nutzen soll. Es existieren Anwendungen wie z.B. CATIA V5, die mit early-binding so ihre Probleme haben. In solchen Fällen muss das late-binding genutzt werden.

Wie werden die Cachefiles erzeugt und das early-binding genutzt ?

Mir sind drei Wege bekannt:

1. Einmaliger Aufruf des Programms c:\python23\Lib\site-packages\win32com\client\makepy.py und Auswahl der zu automatisierenden Objektbibliothek.

2. Einmaliger Aufruf des Programms c:\python23Libsite-packageswin32comclientmakepy.py mit Name der zu automatisierenden Objektbibliothek als Argument. Z.B. makepy.py “Microsoft Word 10.0 Object Library”

3. dynamisches generieren der Cachefiles. Dazu sind 2 Zeilen Code im Python-Programm nötig, die durch das Aufrufen von makepy.py mit dem Argument -i ausgegeben werden. Z.B:

makepy.py -i "Microsoft Word 10.0 Object Library"

liefert folgende Ausgabe:

# Use these commands in Python code to auto generate .py support from win32com.client import gencache gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 2) 

Bei der dynamischen Methode werden beim ersten Aufruf des Programms die Cachefiles einmalig erzeugt und bleiben erhalten und von Python- Programmen genutzt, bis sie manuell vom User gelöscht werden. Bei ersteren beiden werden Sie einmalig manuell erzeugt. Das bedeutet auch: falls die Cachefiles, warum auch immer, gelöscht werden, werden sie nur von der
dynamischen Methode wieder neu erzeugt.

Wie nutzt man das late-binding ?

Wie eingangs erwähnt, haben es manche Anwendungen schwer mit early-binding. In solchen Fällen muss das late-binding genutzt werden. Man erzwingt es durch einen “dynamic Dispatch”. Dazu ruft man im Python-Programm die COM-Bibliothek der Applikation (hier Outlook) wie folgt auf:

o = win32com.client.dynamic.Dispatch("Outlook.Application")

Folgender Aufruf nutzt hingegen (falls vorhanden) das Cachefile für Outlook:

o = win32com.client.Dispatch("Outlook.Application")

Falls die Cachefiles nicht vorhanden sind (und ein makepy zuvor nicht erfolgt ist), erfolgt ebenfalls ein late-binding.

Mehr und Ausführlicheres zu Python und COM ist auf einem Probekapitel des Buchs Python Programming on Win32 zu finden.

Automating Microsoft Outlook

For Outlook automation it is nesseccary to use the makepy utility. You do this either from the tools menu of the Pythonwin-Editor (installed with Pywin32 or ActivePython) or you call the file c:\python23\Lib\site-packages\win32com\client\makepy.py. You then have to select the Outlook Object Library (“Microsoft Outlook 10.0 Object Library” for Office 10.0 or known as Office XP).

After that Python generates cachefiles into the directory c:\python23\Lib\site-packages\win32com\gen_py or c:\temp\gen_py to tell Python more about the Outlook object library.

Here is a well known example which dumps all adressbook entries from your default adressbook:

import codecs, win32com.client
# This example dumps the items in the default address book
# needed for converting Unicode->Ansi (in local system codepage)
DecodeUnicodeString = lambda x: codecs.latin_1_encode(x)[0]
def DumpDefaultAddressBook():
    # Create instance of Outlook
    o = win32com.client.Dispatch("Outlook.Application")
    mapi = o.GetNamespace("MAPI")
    folder = mapi.GetDefaultFolder(win32com.client.constants.olFolderContacts)
    print "The default address book contains",folder.Items.Count,"items"
    # see Outlook object model for more available properties on ContactItem objects
    attributes = [ 'FullName', 'Email1Address']    
    for i in range(1,folder.Items.Count+1):
        print "~~~ Entry %d ~~~" % i
        item = folder.Items[i]
        for attribute in attributes:
            print attribute, eval('item.%s' % attribute)
    o = None
DumpDefaultAddressBook()

Automating Microsoft Powerpoint

One more example how to automate Microsoft Powerpoint and printout a
postscript file with a specified postscript printer (yes, more than one
printers can be installed on the system).

Multithreadding:

Unlike Word and Excel Powerpoint can not run in multiple instances.
If you want to use Powerpoint server based you must implement code to
handle the Powerpoint processes.

How to call the function:

You simply call the function with the name of the Word file, Postscript file and the printername which you want to use.:

e.g.:

make_ps.powerpoint(‘c:\test\powerpointfilename.ppt’, ‘c:\test\psfilename.ps’, ‘My Postscript Printername’)

The source code:

def powerpoint(powerpointfile, psfile, printer):
    pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
    myPowerpoint = win32com.client.DispatchEx('Powerpoint.Application')
    myPpt = myPowerpoint.Presentations.Open(powerpointfile, False, False, False)
    myPpt.PrintOptions.PrintInBackground = 0
    myPpt.PrintOptions.ActivePrinter = printer
    myPpt.Saved = 1
    myPpt.PrintOut(1, 5000, psfile, 0, False)
    myPpt.Close()
    #myPowerpoint.Quit()
    del myPpt
    #del myPowerpoint
    pythoncom.CoUninitialize()

Automating Microsoft Word

One small example how to automate Microsoft Word and printout a
postscript file with a specified postscript printer (yes, more than one
printers can be installed on the system).

Multithreadding:

Unlike
Powerpoint Microsoft Word can run in multiple instances – If a program
creates more Word processes you will see them in the task manager.

How to call the function:

You simply call the function with the name of the Word file, Postscript file and the printername which you want to use.:

eg.
make_ps.word(‘c:\test\wordfilename.doc’, ‘c:\test\psfilename.ps’, ‘My Postscript Printername’)

The source code:

import win32com.client, pythoncom, time

def word(wordfile, psfile, printer):
    pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
    myWord = win32com.client.DispatchEx('Word.Application')
    myWord.Application.ActivePrinter = printer
    myDoc = myWord.Documents.Open(wordfile, False, False, False)
    myDoc.Saved=1
    myWord.Application.NormalTemplate.Saved = 1
    myWord.PrintOut(True, False, 0, psfile)
    while myWord.BackgroundPrintingStatus > 0:
        time.sleep(0.1)
    myDoc.Close()
    myWord.Quit()
    del myDoc
    del myWord
    pythoncom.CoUninitialize()

Print all events from Windows Event Log

This example prints all events from event log:

import win32com.client
strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2")
colItems = objSWbemServices.ExecQuery("Select * from Win32_NTLogEvent")
for objItem in colItems:
    print "Category: ", objItem.Category
    print "Category String: ", objItem.CategoryString
    print "Computer Name: ", objItem.ComputerName
    z = objItem.Data
    if z is None:
        a = 1
    else:
        for x in z:
            print "Data: ", x
    print "Event Code: ", objItem.EventCode
    print "Event Identifier: ", objItem.EventIdentifier
    print "Event Type: ", objItem.EventType
    z = objItem.InsertionStrings
    if z is None:
        a = 1
    else:
        for x in z:
            print "Insertion Strings: ", x
    print "Logfile: ", objItem.Logfile
    print "Message: ", objItem.Message
    print "Record Number: ", objItem.RecordNumber
    print "Source Name: ", objItem.SourceName
    print "Time Generated: ", objItem.TimeGenerated
    print "Time Written: ", objItem.TimeWritten
    print "Type: ", objItem.Type
    print "User: ", objItem.User 

Submitting values and clicking buttons in IE

Submits data to a website and / or clicks on a specific button using COM.

# Use the makepy utility for the "Microsoft Internet Controls (1.1)"
# object library to get early binding.
from win32com.client import Dispatch
from time import sleep

ie = Dispatch("InternetExplorer.Application")  #Create browser instance.
ie.Visible = 1      # Make it visible (0 = invisible)
ie.Navigate("http://www.google.com")
while ie.ReadyState != 4:    # Wait for browser to finish loading.
    sleep(1)

doc = ie.Document   # Get the document.
while doc.readyState != "complete": # Wait for document to finish
    sleep(1)
   
doc.f.q.value = "qwerty"    # form name is 'f'; search field name is 'q'
doc.f.submit()  # Submits form using default button (in this case, btnG)
# OR alternatively you can specify which button to click as follows...
# doc.f.btnI.click()    # click on button 'btnI'

# Note:  You can also reference the forms by the order in which they
# appear in the forms collection.  For example, you could use the
# following code as well which references the first form.
# doc.forms[0].q.value = 'qwerty'

Automating Microsoft Excel

One more example how to automate Microsoft Excel and printout a
postscript file with a specified postscript printer (yes more than one
printer can be installed on the system).

But unlike Word you can not check the background printing status in
Excel with the method "BackgroundPrintingStatus". This shouldn`t make
problems. I didn`t found an afvantage of this feature.

Multi-Threadding:

Unlike Powerpoint Excel works in more than one instances.

How to call the function:

You simply call the function with the name of the Word file, Postscript file and the printername which you want to use.:

The source code:

def excel(excelfile, psfile, printer):
    pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
    myExcel = win32com.client.DispatchEx('Excel.Application')
    myExcel.Application.AskToUpdateLinks = 0
    Excel = myExcel.Workbooks.Open(excelfile, 0, False, 2)
    Excel.Saved = 1
    Excel.PrintOut(1, 5000, 1, False, printer, True, False, psfile)
    Excel.Close()
    myExcel.Quit()
    del myExcel
    del Excel
    pythoncom.CoUninitialize()
excel('c:/test/excelfilename.xls', 'c:/test/psfilename.ps', 'My Postscript Printername')