Für Entwickler, Stand 27.11.2024
Einführung
Warum Web Scraping?
Viele Banken betreiben mittlerweile einen FinTS/HBCI-Server für Finanzsoftware. Einige Banken bieten jedoch leider überhaupt keine maschinenlesbare Schnittstelle an, über die eine Finanzsoftware (wie MoneyMoney) die Umsätze abrufen könnte. In so einem Fall können die Umsätze von einer Finanzsoftware nur mittels Web Scraping von der Website der Bank heruntergeladen werden.
Die Web Banking Engine
Die Web Banking Engine von MoneyMoney besteht aus einem recht umfangreichen Kern, der in C und Objective-C implementiert ist. Der Kern wird durch mehrere schlanke Extensions ergänzt. Diese Web Banking Extensions sind kurze Lua-Skripte, die einfach zu erstellen, zu modifizieren und auszuwechseln sind. Die Lua-Skripte werden von der Web Banking Engine in einer virtuellen Maschine ausgeführt und kommunizieren über eine dokumentierte API mit MoneyMoney. Das vorliegende Dokument spezifiziert diese API.
Die Wahl der Skriptsprache fiel auf Lua, da sie relativ leicht zu erlernen ist und sich gut mit C/C++/Objective-C kombinieren lässt. Für unsere Extensions reicht es vollkommen aus, die ersten fünf Kapitel von »Programming in Lua« gelesen zu haben. Die meisten innerhalb einer Extension aufgerufenen Funktionen sind nämlich gar nicht Bestandteil von Lua, sondern existieren ausschließlich in MoneyMoney.
Ein Praxisbeispiel
Das folgende Stück Lua-Code soll einen Eindruck davon vermitteln, wie eine Web Banking Extension in der Praxis vorgeht:
➊ connection = Connection()
html = HTML(connection:get("https://moneymoney.app/onlinebanking"))
➋ html:xpath("//input[@name='kontonummer']"):attr("value", username)
html:xpath("//input[@name='pin']"):attr("value", password)
➌ connection:request(html:xpath("//input[@name='loginbutton']"):click())
Zuerst wird die Login-Seite vom Server geholt und aus ihrem HTML-Code eine Baumstruktur aufgebaut ➊. Mit Hilfe dieser Baumstruktur wird im HTML-Dokument mit XPath-Ausdrücken zu den Texteingabefeldern navigiert. Deren HTML-Attribute value
werden dann mit den Anmeldedaten ausgefüllt ➋. Danach wird das Login-Formular abgeschickt ➌. Offensichtlich sind nur wenige Code-Zeilen notwendig, um den typischen Anmeldevorgang beim Online-Banking durchzuführen.
Das Skript erzeugt das gleiche Ergebnis, also die gleiche Serverkommunikation, wie sie ein Mensch mit einem Webbrowser beim Ausfüllen derselben Login-Seite erzeugen würde. Die Web Banking Engine kann man daher mit einem automatisch gesteuerten Webbrowser vergleichen.
Vom Skript zur Extension
Installation
Das Verzeichnis, in dem eigene Extensions abgelegt werden, kann über Menü Hilfe
→ Zeige Datenbank im Finder
im Finder geöffnet werden:
~/Library/Containers/com.moneymoney-app.retail/Data/Library/Application Support/MoneyMoney/Extensions
Jede Änderung an Dateien in diesem Verzeichnis wirkt sich unmittelbar auf die Web Banking Engine aus, d.h. es ist nicht nötig, MoneyMoney neu zu starten.
Fehlermeldungen werden im Protokoll-Fenster von MoneyMoney angezeigt. Das Protokoll-Fenster lässt sich mit der Menüfunktion »Fenster« → »Protokollfenster« erreichen.
Hinweis: Für die Entwicklung eigener Extensions lässt sich die Überprüfung der digitalen Signatur in den Einstellungen von MoneyMoney ausschalten. Die Option lässt sich mit der Menüfunktion »MoneyMoney« → »Einstellungen« → »Erweiterungen« → »Digitale Signatur von Extensions überprüfen« erreichen.
Registrierung einer Extension
Ein Skript weist sich als Web Banking Extension aus, indem es am Beginn des Skripts einen Aufruf der Art
WebBanking{version = 1.00,
url = "https://moneymoney.app/onlinebanking",
services = {"Premium Account"},
description = "Demo"}
enthält. Bei den benannten Parameter der Funktion WebBanking
handelt es sich um:
- Number
version
: Versionsnummer der Extension - String
url
(optional): URL der Einstiegsseite des Online-Bankings - Array
services
(optional): Die in diesem Array enthaltenen Service-Namen werden in MoneyMoney in der Auswahlliste beim Anlegen eines Kontos angezeigt. - String
description
(optional): Beschreibung der Extension
Lua-Laufzeitumgebung
Die Parameter der Funktion WebBanking
sind später im Skript als globale Variablen version
, url
, services
und description
zugänglich. Zusätzlich ist auch noch die globale Variable extensionName
mit dem Namen der Extension definiert.
Die Variablen MM.productName
und MM.productVersion
enthalten Informationen zur Anwendung, also MoneyMoney.
Die Ausgabe der Standard-Funktion print
wird im Protokoll-Fenster von MoneyMoney angezeigt.
Die Standard-Funktion error
bricht die Ausführung des Skripts ab. Die Fehlermeldung wird im Protokoll-Fenster und je nach Kontext auch in einem GUI-Dialog angezeigt.
Das Objekt LocalStorage
kann über die Laufzeit des Skripts hinaus zur Speicherung von Informationen genutzt werden.
Das Skript selbst muss UTF-8-kodiert sein und es werden auch alle Strings als UTF-8-Strings zwischen dem Skript und MoneyMoney übergeben, außer es steht in der API-Beschreibung, dass es sich um Binärdaten handelt.
Aufbau einer Web Banking Extension
Einsprungspunkte
Die Web Banking Engine treibt die Ausführung des Skripts, was bedeutet, dass jedes Skript bestimmte Funktionen als Einsprungspunkte zur Verfügung stellen muss.
Es gibt zwei Anwendungsfälle, für die MoneyMoney die Web Banking Engine startet:
- Für den Anwendungsfall Bankzugang einrichten ruft die Web Banking Engine nacheinander folgende Funktionen des Skripts auf:
SupportsBank
(Klärung der Zuständigkeit)InitializeSession
(Anmeldung)ListAccounts
(Auflistung der verfügbaren Konten)- für jedes Konto:
RefreshAccount
(Aktualisierung eines Kontos) EndSession
(Abmeldung)
- Der Anwendungsfall Kontenrundruf läuft ähnlich ab:
SupportsBank
(Klärung der Zuständigkeit)InitializeSession
(Anmeldung)- für jedes Konto:
RefreshAccount
(Aktualisierung eines Kontos) EndSession
(Abmeldung)
Klärung der Zuständigkeit
Um herauszufinden, welche Extension für welchen Bankzugang zuständig ist, ruft die Web Banking Engine diese Funktion auf:
function SupportsBank (protocol, bankCode)
Parameter:
- Konstante
protocol
: Protokoll des Bankzugangs; Mögliche Werte sindProtocolFinTS
undProtocolWebBanking
. Der erste Wert ist dazu gedacht, einen FinTS/HBCI-Bankzugang um Konten zu bereichern, die von der Bank nicht über das FinTS/HBCI-Protokoll zur Verfügung gestellt werden. Der zweite Wert ist für Bankzugänge gedacht, die aussschließlich über Web Scraping abgefragt werden. - String
bankCode
: Bankleitzahl oder Service-Name
Mögliche Rückgabewerte:
false
, wenn die Extension für den besagten Bankzugang das Web Scraping nicht übernehmen kann.true
, wenn die Extension für den besagten Bankzugang das Web Scraping übernehmen kann. Anstelle vontrue
kann auch die URL der Einstiegsseite des Online-Bankings zurückgegeben werden.
Anmeldung (einfach)
Diese Funktion führt einen einfachen Anmeldevorgang durch:
function InitializeSession (protocol, bankCode, username, reserved, password)
Parameter:
- Konstante
protocol
: Protokoll des Bankzugangs; Mögliche Werte sindProtocolFinTS
undProtocolWebBanking
. - String
bankCode
: Bankleitzahl oder Service-Name - String
username
: Benutzername - String
reserved
: leer, derzeit nicht verwendet - String
password
: Passwort
Mögliche Rückgabewerte:
- Nichts oder
nil
, wenn die Anmeldung erfolgreich war. - Die Konstante
LoginFailed
, wenn die Zugangsdaten vom Server abgewiesen wurden. Um eine Sperrung des Passworts durch den Server zu vermeiden, werden die betroffenen Konten durch MoneyMoney nicht mehr automatisch aktualisiert, bis die Zugangsdaten durch den Anwender erneut eingegeben wurden. - Ein String mit einer Fehlermeldung.
Anmeldung (mit Zwei-Faktor-Authentifizierung)
Diese Alternative zur Funktion InitializeSession
führt einen Anmeldevorgang mit Zwei-Faktor-Authentifizierung durch. Wenn diese Funktion beim ersten Aufruf ein Objekt mit Informationen zur Zwei-Faktor-Authentifizierung zurückgibt, dann wird sie ein zweites Mal mit step=2
aufgerufen. Beim ersten Aufruf enthält credentials
die Benutzernamen und das Passwort. Beim zweiten Aufruf enthält credentials
die Antwort auf challenge
.
function InitializeSession2 (protocol, bankCode, step, credentials, interactive)
Parameter:
- Konstante
protocol
: Protokoll des Bankzugangs; Mögliche Werte sindProtocolFinTS
undProtocolWebBanking
. - String
bankCode
: Bankleitzahl oder Service-Name - Number
step
: Schritt1
oder2
der Zwei-Faktor-Authentifizierung - Array
credentials
: Liste von Benutzernamen und Passwörtern - Boolean
interactive
: MoneyMoney wird im Vordergrund oder Hintergrund ausgeführt
Mögliche Rückgabewerte:
- Nichts oder
nil
, wenn die Anmeldung erfolgreich war. - Die Konstante
LoginFailed
, wenn die Zugangsdaten vom Server abgewiesen wurden. Um eine Sperrung des Passworts durch den Server zu vermeiden, werden die betroffenen Konten durch MoneyMoney nicht mehr automatisch aktualisiert, bis die Zugangsdaten durch den Anwender erneut eingegeben wurden. - Ein String mit einer Fehlermeldung.
- Ein Objekt mit folgenden Feldern:
- String
title
: Überschrift für den Dialog der Zwei-Faktor-Authentifizierung - Binary
challenge
: Die Aufforderung kann entweder ein String für eine Frage sein, oder die Binärdaten eines Captchas im PNG- oder JPEG-Format. - String
label
: Beschriftung des Eingabefelds
- String
Auflistung der verfügbaren Konten
Diese Funktion listet alle Konten auf, die mittels Web Scraping abgefragt werden können:
function ListAccounts (knownAccounts)
Parameter:
Array knownAccounts
: Wenn das Protokoll des Bankzugangs FinTS/HBCI ist, Web Scraping also nur als Ergänzung dient, dann enthält dieser Parameter ein Array mit schon bekannten Konten. Das Skript kann anhand dieses Arrays feststellen, welche Kontoinformationen es nicht mehr über Web Scraping abzufragen braucht. Die Struktur der Array-Elemente ist im Abschnitt »Datenstruktur eines Kontos« beschrieben.
Mögliche Rückgabewerte:
- Ein Array mit Konten, die mittels Web Scraping abgefragt werden können. Die Struktur der Array-Elemente ist im Abschnitt »Datenstruktur eines Kontos« beschrieben.
- Ein String mit einer Fehlermeldung.
Für jedes Konto muss mindestens die Kontonummer zurückgegeben werden, andernfalls wird das Konto ignoriert.
Aktualisierung eines Kontos
Mit dieser Funktion werden Saldo- und Umsatzinformationen oder der Wertpapierbestand eines Kontos abgefragt:
function RefreshAccount (account, since)
Parameter:
- Table
account
: Das Konto, das abgefragt werden soll. Die Strukur ist im Abschnitt »Datenstruktur eines Kontos« beschrieben. - Number
since
: Der Buchungstag, ab dem Umsätze geliefert werden sollten. Das Skript braucht ältere Umsätze nicht mehr zu liefern. Die Angabe erfolgt in Form eines POSIX-Zeitstempels. Bei Depots wird anstelle dieses Parametersnil
übergeben.
Mögliche Rückgabewerte:
- Eine Tabelle mit ein oder mehreren Feldern:
- Number
balance
: Kontostand - Array
balances
: Ein Array mit Tupeln (Kontostand, Währung). Dieses Feld sollte nur dann an Stelle vonbalance
zurückgegeben werden, wenn das Konto mehrere Kontostände in unterschiedlichen Währungen besitzt. - Number
pendingBalance
: Summe der vorgemerkten Umsätze - Array
transactions
: Ein Array mit Umsätzen; Diese Umsätze werden als »neu« klassifiziert, wenn sie noch nicht in der Datenbank von MoneyMoney vorhanden sind. Andernfalls werden sie als Duplikate verworfen. Das Array sollte nach Buchungstag geordnet sein, mit den neuesten Umsätzen vorne. Die Struktur der Array-Elemente ist im Abschnitt »Datenstruktur eines Umsatzes« beschrieben. - Array
securities
: Ein Array mit Depotpositionen; Die Struktur der Array-Elemente ist im Abschnitt »Datenstruktur von Wertpapieren« beschrieben. - Number
bonusPoints
: Anzahl der Punkte in einem Bonusprogramm
- Number
- Ein String mit einer Fehlermeldung.
Bei Depots wird nur das Feld securities
erwartet, bei allen anderen Konten die Felder balance
/balances
und transactions
. Wenn diese fehlen oder den Wert nil
enthalten, wird in der GUI eine Fehlermeldung angezeigt, dass der Kontostand bzw. die Umsätze bzw. der Wertpapierbestand nicht abgefragt werden konnte.
Für jeden Umsatz müssen mindestens Betrag und Buchungstag angegeben werden, andernfalls führt dies ebenfalls zu einer Fehlermeldung.
Abmeldung
Diese Funktion führt den Abmeldevorgang durch:
function EndSession ()
Mögliche Rückgabewerte sind:
- Nichts oder
nil
, wenn die Abmeldung erfolgreich war. - Ein String mit einer Fehlermeldung.
Vorlage
Folgende Vorlage kann als Ausgangspunkt für eigene Web Banking Extensions dienen.
WebBanking{version = 1.00,
url = "https://moneymoney.app/onlinebanking",
services = {"Premium Account"},
description = "Demo"}
function SupportsBank (protocol, bankCode)
return protocol == ProtocolWebBanking and bankCode == "Premium Account"
end
function InitializeSession (protocol, bankCode, username, reserved, password)
-- Login.
end
function ListAccounts (knownAccounts)
-- Return array of accounts.
local account = {
name = "Premium Account",
owner = "Jane Doe",
accountNumber = "111222333444",
bankCode = "80007777",
currency = "EUR",
type = AccountTypeGiro
}
return {account}
end
function RefreshAccount (account, since)
-- Return balance and array of transactions.
local transaction = {
bookingDate = 1325764800,
purpose = "Hello World!",
amount = 42.00
}
return {balance=42.00, transactions={transaction}}
end
function EndSession ()
-- Logout.
end
Tipp: Um während der Entwicklung einer Extension nicht bei jeder Skriptänderung die Kontoeinrichtung von MoneyMoney durchlaufen zu müssen, kann man ListAccounts
wie in der Vorlage statische Informationen zurückgeben lassen. Wenn man dann erst einmal die Funktionen InitializeSession
und EndSession
implementiert hat, kann man sich in Ruhe den Funktionen ListAccounts
und RefreshAccount
widmen.
Tipp: In der Anfangsphase der Entwicklung einer Extension ist es gar nicht nötig, eine Online-Verbindung aufzubauen. Vorab mit einem Browser gespeicherte HTML-Seiten können über Lua-Funktionen geladen werden, so dass man gefahrlos mit dem Skript experimentieren kann.
Die API von MoneyMoney
Datenstruktur eines Kontos
Die Informationen eines Konto werden in einer Lua-Tabelle gespeichert. Folgende Felder können belegt werden, soweit deren Inhalt bekannt ist:
- String
name
: Bezeichnung des Kontos - String
owner
: Name des Kontoinhabers - String
accountNumber
: Kontonummer - String
subAccount
: Unterkontomerkmal - Boolean
portfolio
:true
für Depots undfalse
für alle anderen Konten - String
bankCode
: Bankleitzahl - String
currency
: Kontowährung - String
iban
: IBAN - String
bic
: BIC - Konstante
type
: Kontoart; Mögliche Werte sindAccountTypeGiro
(Girokonto),AccountTypeSavings
(Sparkonto),AccountTypeFixedTermDeposit
(Festgeldanlage),AccountTypeLoan
(Darlehenskonto),AccountTypeCreditCard
(Kreditkarte),AccountTypePortfolio
(Wertpapierdepot),AccountTypeOther
(Sonstige).
Datenstruktur eines Umsatzes
Die Daten eines Umsatzes werden in einer Lua-Tabelle gespeichert:
- String
name
: Name des Auftraggebers/Zahlungsempfängers - String
accountNumber
: Kontonummer oder IBAN des Auftraggebers/Zahlungsempfängers - String
bankCode
: Bankzeitzahl oder BIC des Auftraggebers/Zahlungsempfängers - Number
amount
: Betrag - String
currency
: Währung - Number
bookingDate
: Buchungstag; Die Angabe erfolgt in Form eines POSIX-Zeitstempels. - Number
valueDate
: Wertstellungsdatum; Die Angabe erfolgt in Form eines POSIX-Zeitstempels. - String
purpose
: Verwendungszweck; Mehrere Zeilen können durch Zeilenumbrüche ("\n"
) getrennt werden. - Number
transactionCode
: Geschäftsvorfallcode - Number
textKeyExtension
: Textschlüsselergänzung - String
purposeCode
: SEPA-Verwendungsschlüssel - String
bookingKey
: SWIFT-Buchungsschlüssel - String
bookingText
: Umsatzart - String
primanotaNumber
: Primanota-Nummer - String
batchReference
: Sammlerreferenz - String
endToEndReference
: SEPA-Ende-zu-Ende-Referenz - String
mandateReference
: SEPA-Mandatsreferenz - String
creditorId
: SEPA-Gläubiger-ID - String
returnReason
: Rückgabegrund - Boolean
booked
: Gebuchter oder vorgemerkter Umsatz
Datenstruktur von Wertpapieren
Die Daten von Wertpapieren werden in einer Lua-Tabelle gespeichert:
- String
name
: Bezeichnung des Wertpapiers - String
isin
: ISIN - String
securityNumber
: WKN - Number
quantity
: Nominalbetrag oder Stückzahl - String
currencyOfQuantity
: Währung bei Nominalbetrag odernil
bei Stückzahl - Number
purchasePrice
: Kaufpreis oder Kaufkurs - String
currencyOfPurchasePrice
: Von der Kontowährung abweichende Währung des Kaufpreises - Number
exchangeRateOfPurchasePrice
: Wechselkurs zum Kaufzeitpunkt - Number
price
: Aktueller Preis oder Kurs - String
currencyOfPrice
: Von der Kontowährung abweichende Währung des Preises - Number
exchangeRateOfPrice
: Aktueller Wechselkurs - Number
amount
: Wert der Depotposition in Kontowährung - Number
originalAmount
: Wert der Depotposition in Originalwährung - String
currencyOfOriginalAmount
: Originalwährung - String
market
: Name des Börsenplatzes - Number
tradeTimestamp
: Notierungszeitpunkt; Die Angabe erfolgt in Form eines POSIX-Zeitstempels.
Objekt für eine HTTPS-Verbindung
connection = Connection()
Erzeugt ein Objekt, mit dem eine HTTPS-Verbindung zu einem Webserver aufgebaut werden kann.
content, charset, mimeType, filename, headers = connection:request(method, url[, postContent, postContentType, headers])
Diese Methode des Connection-Objekts fordert eine Ressource vom Webserver an.
Falls noch keine HTTPS-Verbindung zum Server besteht, wird diese aufgebaut. Das Connection-Objekt verwendet HTTP-Pipelining. Wenn der Server dies auch anbietet und solange über den URL-Parameter nicht der Server gewechselt wird, werden alle Anfragen über dieselbe HTTPS-Verbindung geschickt.
Für JSON-basierte REST-APIs sollte im Parameter headers
das HTTP-Header-Feld Accept
auf "application/json"
gesetzt werden. Dann wird auch bei einem HTTP-Fehler die Serverantwort im Skript zurückgegeben. Andernfalls wird im Fehlerfall die Ausführung des Skripts abgebrochen und stattdessen in der GUI eine Fehlermeldung angezeigt.
Parameter:
- String
method
: HTTP-Request-Methode; Mögliche Werte sind"GET"
,"POST"
,"PUT"
,"PATCH"
und"DELETE"
. - String
url
: Server-URL; Die URL darf absolut oder relativ sein. Bei der ersten Server-Anfrage muss eine absolute URL angegeben werden. Relative URLs beziehen sich wie üblich auf die gerade aktive, d.h. zuletzt aufgerufene URL. - Binary
postContent
: Die Daten, die mit einem HTTP-POST-Request an den Server gesendet werden sollen - String
postContentType
: Der Inhalt des FeldsContent-Type
für den HTTP-POST-Header - Dictionary
headers
: Weitere HTTP-Header-Felder
Rückgabewerte:
- Binary
content
: Daten vom Server - String
charset
: Der Zeichensatz, mit dem die vom Server gelieferten Daten zu interpretieren sind - String
mimeType
: MIME-Type der vom Server gelieferten Daten - String
filename
: Dateiname aus dem HTTP-Header-FeldContent-Dispositon
- Dictionary
headers
: Vom Server gelieferte HTTP-Header-Felder
Zur Bestimmung des Zeichensatzes und des MIME-Typs werden der HTTP-Header des Servers und <meta>
-Tags im HTML-Code herangezogen.
Beispiel:
content, charset, mimeType = connection:request("POST",
"https://moneymoney.app/onlinebanking",
"username=foo&password=bar",
"application/x-www-form-urlencoded; charset=UTF-8")
print(content) -- "<html>\n<head>\n<title>[…]"
print(charset) -- "UTF-8"
print(mimeType) -- "text/html"
Tipp: Die Art und Reihenfolge der Rückgabewerte ist so gewählt, dass sie sich für die Erzeugung eines HTML-Objektes verwenden lassen:
html = HTML(connection:request("GET", "https://moneymoney.app/onlinebanking"))
content, charset, mimeType = connection:get(url)
Kurzform für: connection:request("GET", url)
content, charset, mimeType = connection:post(url, postContent[, postContentType])
Kurzform für: connection:request("POST", url, postContent, postContentType)
connection:close()
Schließt die HTTPS-Verbindung zum Server. Normalerweise braucht diese Methode nicht aufgerufen werden, da nach der Ausführung des Skripts alle offenen Verbindungen automatisch geschlossen werden.
url = connection:getBaseURL()
Diese Methode gibt die zuletzt aufgerufene URL zurück.
Rückgabewert:
String url
: Die zuletzt aufgerufene URL
connection:setCookie(cookie)
Jedes Skript erhält für die Dauer seiner Ausführung einen Speicher für HTTP-Cookies. Dieser Speicher wird von allen HTTP-Verbindungen, die innerhalb desselben Skripts aufgebaut werden, gemeinsam genutzt. Die Cookies werden automatisch aus dem HTTP-Header des Servers und den <meta>
-Tags im HTML-Code extrahiert. Nach der Ausführung des Skripts werden alle Cookies wieder gelöscht.
Mit dieser Methode können dem Speicher weitere Cookies hinzugefügt oder vorhandene Cookies geändert werden.
Parameter:
String cookie
: HTTP-Cookie; Das Format ist identisch zum Feld Set-Cookie
im HTTP-Header.
Beispiel:
connection:setCookie("SESSION=foobar; path=/")
cookies = connection:getCookies()
Mit dieser Methode lassen sich die HTTP-Cookies abfragen, die für die gerade aktive, d.h. zuletzt aufgerufene URL gültig sind.
Rückgabewert:
String cookies
: HTTP-Cookies; Das Format ist identisch zum Feld Cookies
im HTTP-Header.
connection.useragent
Dieses Attribut vom Typ String enthält den Wert des Felds User-Agent
für den HTTP-Header. Durch Veränderung dieses Werts lässt sich gegenüber dem Webserver ein bestimmter Browser oder ein mobiles Endgerät simulieren.
Beispiel:
connection.useragent = "Mozilla/5.0 (compatible; " .. MM.productName .. "/" .. MM.productVersion .. ")"
connection.language
Dieses Attribut vom Typ String enthält den Wert des Felds Accept-Language
für den HTTP-Header. Bei manchen Servern lässt sich so die Sprache der Inhalte auswählen. Als Standardwert ist die Sprache des Betriebssystems voreingestellt.
Beispiel:
connection.language = "de-de"
Objekt für ein HTML-Dokument
html = HTML(content[, charset])
Erzeugt ein neues Objekt, mit dem sich in einem HTML-Dokument navigieren lässt.
Parameter:
- Binary
content
: HTML-Code - String
charset
: Der Zeichensatz, mit dem der HTML-Code zu interpretieren ist. Wenn dieser Parameter fehlt, wird der Zeichensatz aus den<meta>
-Tags extrahiert.
elements = html:xpath(query)
Wählt HTML-Elemente mittels eines XPath-Ausdrucks aus.
Parameter:
String query
: XPath-Ausdruck in der XML Path Language Version 1.0; Alle Tag- und Attributsnamen müssen klein geschrieben werden.
Rückgabewert:
Objekt elements
: Eine Liste von HTML-Elementen, die durch den XPath-Ausdruck ausgewählt wurden. Die Methoden, die auf dieses Objekt angewendet werden können, sind im Abschnitt »Objekt für HTML-Elemente« beschrieben.
Tipp: Die Entwicklertools von Webbrowsern bieten komfortable Werkzeuge an, um XPath-Ausdrücke zu schreiben und zu testen.
text = html:html()
Diese Methode generiert aus dem HTML-Dokument neuen, formatierten HTML-Code. Dieser ist nicht unbedingt identisch zum ursprünglichen HTML-Code. Der generierte HTML-Code ist immer UTF-8-kodiert.
Rückgabewert:
String text
: HTML-Code
Objekt für HTML-Elemente
count = elements:length()
Diese Methode liefert die Anzahl der HTML-Elemente, die sich im Objekt elements
befinden.
Rückgabewert:
Number count
: Anzahl der HTML-Elemente
elements = elements:get(n)
Diese Methode wählt das n
-te HTML-Element aus elements
aus.
Parameter:
Number n
: Index des auszuwählenden HTML-Elements; Wie in Lua üblich, beginnt die Indexierung bei 1.
Rückgabewert:
Objekt elements
: Der Rückgabewert besteht selbst wieder aus einem Objekt für HTML-Elemente. Wenn n
ein gültiger Index ist, enthält elements
das n
-te HTML-Element. Andernfalls ist elements
leer.
Beispiel:
if elements:get(2):length() == 1 then print "Fnord!" end
elements:each(function (index, element))
Diese Methode durchläuft alle HTML-Elemente von elemente
und führt für jedes HTML-Element eine Aktion aus.
Parameter:
Function function (index, element)
: Eine Funktion, die für jedes HTML-Element ausgeführt werden soll. Die Funktion besitzt selbst zwei Parameter:
- Number
index
: Index des aktuellen HTML-Elements; Wie in Lua üblich, beginnt die Indexierung bei 1. - Object
element
: Dieser Parameter besteht selbst wieder aus einem Objekt für HTML-Elemente und enthält genau ein HTML-Element.
Wenn die Funktion func
den Wert false
zurückgibt, wird die Methode each
abgebrochen.
Beispiel:
elements:each(function (index, element))
print (index .. "=" .. element:text())
end
elements = elements:reverse()
Diese Methode dreht die Reihenfolge der HTML-Elemente von elemente
um.
Rückgabewert:
Objekt elements
: Der Rückgabewert besteht selbst wieder aus einem Objekt für HTML-Elemente, welches die HTML-Elemente in umgekehrter Reihenfolge enthält.
elements = elements:children()
Diese Methode wählt die unmittelbaren Kindelemente der HTML-Elemente aus elements
aus.
Rückgabewert:
Objekt elements
: Der Rückgabewert besteht selbst wieder aus einem Objekt für HTML-Elemente und enthält die HTML-Kindelemente.
elements = elements:xpath(query)
Diese Methode wählt mittels eines XPath-Ausdrucks HTML-Elemente relativ zum ersten HTML-Element von elements
aus. Der XPath-Ausdruck query
muss dazu ebenfalls relativ sein, d.h. mit einem Punkt beginnen.
Parameter:
String query
: Relativer XPath-Ausdruck (beginnend mit einem Punkt) in der XML Path Language Version 1.0; Alle Tag- und Attributsnamen müssen klein geschrieben werden.
Rückgabewert:
Objekt elements
: Eine Liste von HTML-Elementen, die durch den XPath-Ausdruck ausgewählt wurden.
text = elements:text()
Diese Methode liefert den kombinierten Text, der sich zwischen den HTML-Tags der HTML-Elemente elements
und deren Kindelementen befindet.
Rückgabewert:
String text
: Text, der sich zwischen den HTML-Tags befindet.
value = elements:attr(attribute)
Diese Methode gibt den Inhalt eines Attributs des ersten HTML-Elements aus elements
zurück.
Parameter:
String attribute
: Name des Attributs
Rückgabewert:
String value
: Inhalt des Attributs
elements:attr(attribute, value)
Diese Methode ändert ein Attribut für alle HTML-Elements aus elements
.
Parameter:
- String
attribute
: Name des Attributs - String
value
: Neuer Inhalt des Attributs
value = elements:val()
Diese Methode gibt den Wert eines Formularfelds zurück. Das erste HTML-Element in elements
muss ein Formularfeld sein. Im Gegensatz zur Methode elements:attr("value")
berücksichtigt diese Methode auch das Attribut disabled
und wertet die ausgewählte Option von Auswahllisten (<select>
-Tag) aus.
Rückgabewert:
String value
: Wert des Formularfelds
elements:select(value)
Diese Methode wählt eine Option in einer Auswahlliste (<select>
-Tag) aus. Das erste HTML-Element in elements
muss eine Auswahlliste sein. Im Gegensatz zur Methode elements:attr("selected", "selected")
berücksichtigt diese Methode auch das Attribut disabled
und wählt die übrigen Optionen ab.
Parameter:
String value
: Ausgewählte Option
method, url[, postContent, postContentType] = elements:click()
Diese Methode erzeugt aus einem HTML-Link oder einem HTML-Formular die Parameter für einen HTTP-Request. In elements
muss als erstes HTML-Element ein Link (<a href>
-Tag) oder ein Submit-Button (<input type="submit">
-Tag, <button>
-Tag) oder ein Image-Button (<input type="image">
-Tag) vorhanden sein.
Bei einem HTML-Link wird die verlinkte URL zurückgegeben. Bei einem Formular werden die Werte der <input>
-Tags URL-kodiert und entweder als GET-Parameter an die URL angehängt oder als POST-Parameter zurückgegeben.
Rückgabewerte:
- String
method
: HTTP-Request-Methode; Mögliche Werte sind"GET"
und"POST"
. - String
url
: Server-URL - Binary
postContent
: Die Daten, die mit einem HTTP-POST-Request an den Server gesendet werden sollen. - String
postContentType
: Der Inhalt des FeldsContent-Type
für den HTTP-POST-Header.
Tipp: Die Art und Reihenfolge der Rückgabewerte ist so gewählt, dass sie sich für einen HTTP-Request verwenden lassen:
connection:request(elements:click())
method, url[, postContent, postContentType] = elements:submit()
Diese Methode erzeugt aus einem HTML-Formular ohne Submit-Button die Parameter für einen HTTP-Request. In elements
muss als erstes HTML-Element ein Formular (<form>
-Tag) vorhanden sein. Die Werte der <input>
-Tags werden URL-kodiert und entweder als GET-Parameter an die URL angehängt oder als POST-Parameter zurückgegeben. Die Werte von Submit-Buttons (<input type="submit">
-Tag) werden ignoriert, da das Formular ohne Submit-Button generiert wird.
Rückgabewerte:
- String
method
: HTTP-Request-Methode; Mögliche Werte sind"GET"
und"POST"
. - String
url
: Server-URL - Binary
postContent
: Die Daten, die mit einem HTTP-POST-Request an den Server gesendet werden sollen. - String
postContentType
: Der Inhalt des FeldsContent-Type
für den HTTP-POST-Header.
Tipp: Die Art und Reihenfolge der Rückgabewerte ist so gewählt, dass sie sich für einen HTTP-Request verwenden lassen:
connection:request(elements:submit())
Objekt für ein JSON-Dokument
fields = JSON(json):dictionary()
Diese Methode konvertiert ein JSON-Dokument in eine Lua-Datenstruktur.
Parameter:
Binary json
: JSON-Dokument
Rückgabewert:
Dictionary oder Array fields
: Lua-Datenstruktur des JSON-Dokuments
lua = JSON():set(fields):json()
Diese Methode konvertiert eine Lua-Datenstruktur zunächst in ein JSON-Dokument.
Parameter:
Dictionary oder Array fields
: Lua-Datenstruktur des JSON-Dokuments
Rückgabewert:
Binary json
: JSON-Dokument
Objekt für ein PDF-Dokument
text = PDF(pdf):text()
Diese Methode extrahiert, so gut wie möglich, den unformattierten Text aus einem PDF-Dokument.
Parameter:
Binary pdf
: PDF-Dokument
Rückgabewert:
String text
: Unformattierter Text
Objekt für Bankinformationen
bankInfo = BankInfo(bankCode)
Erzeugt ein neues Objekt mit Informationen zu einer Bank.
Parameter:
String bankCode
: Bankleitzahl
Beispiel:
print(BankInfo("80007777").name)
Datenstruktur für Bankinformationen
Die Informationen zu einer Bank werden in einer Lua-Tabelle gespeichert. Derzeit gibt es nur ein einziges belegtes Feld:
- String
name
: Name der Bank
Sonstige Funktionen
str = MM.localizeText(str)
Mit dieser Funktion kann ein Text übersetzt werden. Diese Funktion ist primär für die mit MoneyMoney ausgelieferten Extensions gedacht. Sie ist ein Wrapper für die Cocoa-Funktion NSLocalizedString
und liefert natürlich nur dann eine Übersetzung, wenn der Text in MoneyMoney hinterlegt worden ist.
Parameter:
String str
: Englischer Text
Rückgabewert:
String str
: Übersetzter Text
str = MM.localizeDate([format, ]date)
Lokalisiert eine Zeitangabe. Da die von Lua unterstützten POSIX Locales innerhalb von macOS-Apps nicht zur Verfügung stehen, baut diese Funktion auf der Cocoa-Klasse NSDateFormatter
auf.
Parameter:
- String
format
(optional): Ausgabeformat; Die Angabe erfolgt wie bei der Cocoa-KlasseNSDateFormatter
nach dem Unicode Technical Standard #35. - Number
date
: Datum; Die Angabe erfolgt in Form eines POSIX-Zeitstempels.
Rückgabewert:
String str
: Datum im lokalisierten Format
str = MM.localizeNumber([format, ]num)
Lokalisiert eine Zahl. Da die von Lua unterstützten POSIX Locales innerhalb von macOS-Apps nicht zur Verfügung stehen, baut diese Funktion auf der Cocoa-Klasse NSNumberFormatter
auf.
Parameter:
- String
format
(optional): Ausgabeformat; Die Angabe erfolgt wie bei der Cocoa-KlasseNSNumberFormatter
nach dem Unicode Technical Standard #35. - Number
num
: Zahl
Rückgabewert:
String str
: Zahl im lokalisierten Format
str = MM.localizeAmount([format, ]amount[, currency])
Lokalisiert einen Währungsbetrag.
Parameter:
- String
format
(optional): Ausgabeformat; Die Angabe erfolgt wie bei der Cocoa-KlasseNSNumberFormatter
nach dem Unicode Technical Standard #35. - Number
amount
: Betrag - String
currency
(optional): Währung; Ohne diesen Parameter wird nur der Betrag ohne Währungsangabe zurückgegeben.
Rückgabewert:
String str
: Währungsbetrag im lokalisierten Format
urlencoded = MM.urlencode(str, [charset])
Wendet eine URL-Kodierung an.
Parameter:
- String
str
: Zu kodierender Text - String
charset
(optional): Zeichensatz; Die Angabe erfolgt wie bei HTTP nach IANA. Ohne diesen Parameter wird ISO-8859-1 verwendet.
Rückgabewert:
String urlencoded
: URL-kodierter Text.
str = MM.urldecode(urlencoded)
Entfernt die URL-Kodierung.
Parameter:
String urlencoded
: URL-kodierter Text.
Rückgabewert:
String str
: Text ohne URL-Kodierung.
data = MM.toEncoding(charset, str[, bom])
Konvertiert einen Text von UTF-8 zu einem anderen Zeichensatz.
Parameter:
- String
charset
: Zeichensatz; Die Angabe erfolgt wie bei HTTP nach IANA. - String
str
: Text in UTF-8 - Boolean
bom
(optional): Wenn dieser Parameter mittrue
belegt ist, wird der Rückgabewert um eine Byte Order Mark (BOM) ergänzt, sofern sie für den angegeben Zeichensatz existiert.
Rückgabewert:
Binary data
: Text im angegebenen Zeichensatz
str = MM.fromEncoding(charset, data)
Konvertiert einen Text von einem anderen Zeichensatz zu UTF-8.
Parameter:
- String
charset
: Zeichensatz; Die Angabe erfolgt wie bei HTTP nach IANA. - Binary
data
: Text im angegebenen Zeichensatz
Rückgabewert:
String str
: Text in UTF-8
encoded = MM.base64(data)
Konvertiert Daten zu Base64.
Parameter:
Binary data
: Zu konvertierende Daten
Rückgabewert:
String encoded
: Base64-kodierte Daten
data = MM.base64decode(encoded)
Konvertiert Daten von Base64.
Parameter:
Binary encoded
: Base64-kodierte Daten
Rückgabewert:
String data
: konvertierte Daten
digest = MM.sha512(data)
digest = MM.sha256(data)
digest = MM.sha1(data)
digest = MM.md5(data)
Berechnet einen SHA512-, SHA256-, SHA1- oder MD5-Hashwert.
Parameter:
Binary data
: Daten, über die der Hashwert berechnet werden soll.
Rückgabewert:
String digest
: Hashwert als hexidezimaler String
digest = MM.hmac512(key, data)
digest = MM.hmac384(key, data)
digest = MM.hmac256(key, data)
digest = MM.hmac1(key, data)
Berechnet einen HMAC512-, HMAC384-, HMAC256- oder HMAC1-Message-Authentication-Code.
Parameter:
- Binary
key
: HMAC-Schlüssel - Binary
data
: Daten, über die der Message Authentication Code berechnet werden soll.
Rückgabewert:
Binary digest
: Message Authentication Code als binärer String
data = MM.random(length)
Generiert zufällige binäre Daten mit der angegebenen Länge.
Parameter:
Number length
: Anzahl der Bytes
Rückgabewert:
Binary data
: zufällig generierte Daten
timestamp = MM.time()
Gibt die aktuelle Uhrzeit zurück. Im Gegensatz zum Aufruf os.time()
enthält der Rückgabewert auch Millisekunden als Nachkommestellen.
Rückgabewert:
Number timestamp
: Aktuelle Uhrzeit in Form eines POSIX-Zeitstempels.
MM.sleep(seconds)
Unterbricht die Ausführung des Skripts für ein paar Sekunden.
Parameter:
Number seconds
: Anzahl der Sekunden
MM.printStatus(...)
Diese Funktion arbeitet ähnlich zur Lua-Funktion print
: Die Parameter werden mittels der Lua-Funktion tostring
zu einem String konvertiert und im Protokoll-Fenster von MoneyMoney angezeigt. Zusätzlich wird der String als Statusmeldung in der GUI angezeigt.