HTTPS-Download automatisieren

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
paedubucher
Beiträge: 939
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

HTTPS-Download automatisieren

Beitrag von paedubucher » 02.07.2009 09:52:48

Hallo allerseits

Ich muss wöchentlich ein Backup von unseren CRM-Daten durchführen. Als CRM-Software setzen wir Salesforce (Weblösung) ein. Das Backup wird automatisch erstellt, nur muss ich dann diese ganzen Daten (mehrere Dateien zu > 100 MB) manuell herunterladen. Das erfordert jeweils ein Login, ausserdem wird dann meine Internetleitung während der Arbeitszeit voll ausgelastet. Sowas könnte man meiner Meinung nach auch automatisiert von einem Server erledigen lassen.

Nun möchte ich das ganze automatisieren, vorzugsweise in Python, Java oder Perl.

Zunächst habe ich mal die Seite mit dem Login-Fenster geöffnet, diese sieht etwa so aus:

Code: Alles auswählen

<form id='login_form' name='login' method='POST' onSubmit='handleLogin(); action='https://emea.salesforce.com/'
<div class='inputbox'>
<label for='username'>Benutzername</label><br />
<span><input class='txtbox' type='text' id='username' name='username' value="" /></span>
</div><!-- inputbox -->
<div class='inputbox inputbox_password'>
<label for='password'>Kennwort</label><br />
<span><input class='txtbox' type='password' id='password' name="pw" onKeyPress="checkCaps(event)"/></span>
</div><!-- inputbox -->
...
...und dann irgendwo noch ein Submit-Button. Wichtig scheinen mir hier nur die Parameter "username" und "pw". die JavaScript-Funktion "handleLogin();" verändert bloss ein bisschen die Darstellung.
Ich müsste somit irgendwie einen HTTPS-Request auf https://emea.salesforce.com/ absetzen und dazu die Parameter "username" und "pw" mitgeben. Mit Python habe ich das mal (sehr naiv) so versucht:

Code: Alles auswählen

import http.client
con = http.client.HTTPSConnection('emea.salesforce.com')
con.connect()
con.request('POST', 'https://emea.salesforce.com?username=[ich]&pw=[geheim])
res = con.getresponse()
data = res.read()
print(data)
Nun erhalte ich zwar eine HTML-Seite, aber leider genau wieder das Login-Formular.

So einfach scheint es also nicht zu klappen. Ich nehme an, dass ich die POST-Angaben (username und pw) wohl irgendwie verschlüsselt, statt als URL-Parameter übergeben muss.

Hat irgend jemand ein Ansatz, wie man das bewerkstelligen könnte? Wenn es per Browser funktioniert, sollte das doch irgendwie auch programmatisch funktionieren. Ich habe auch schon versucht, den Netzwerkverkehr mitzusniffen, dabei sehe ich natürlich nur irgendwelche kryptischen Request-Bodies (da verschlüsseltes HTTPS?).
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Benutzeravatar
neuss
Beiträge: 2165
Registriert: 06.11.2004 17:56:02
Lizenz eigener Beiträge: MIT Lizenz

Re: HTTPS-Download automatisieren

Beitrag von neuss » 02.07.2009 10:28:49

Hallo,

sollte sich dein Problem nicht einfach mit wget lösen lassen?
als Ansatz,

Code: Alles auswählen

wget  https://username:password@<url>:<port>
gruss neuss
stell dir vor, es geht, und keiner kriegt es hin.

uname
Beiträge: 12426
Registriert: 03.06.2008 09:33:02

Re: HTTPS-Download automatisieren

Beitrag von uname » 02.07.2009 10:44:11

Für "wget" ist es wichtig, dass du die absolute URL deiner Backupdatei findest. Meist ist das zugehörige Verzeichnis durch "htaccess" geschützt. Das kannst du bei "wget" aber bestimmt auch einbauen. Sollte das Backup jedoch in einer Datenbank rumliegen und nicht auf der Platte direkt erreichbar sein, so wäre das nicht so gut.

Ermittle somit die absolute URL (evtl. mit Wireshark), versuche den direkten Aufruf und baue das dann für "wget" um.

paedubucher
Beiträge: 939
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: HTTPS-Download automatisieren

Beitrag von paedubucher » 02.07.2009 10:50:19

Leider sind die Anzahl der Dateien und deren Dateinamen nicht voraussehbar und ändern sich jedes mal. Von daher muss ich mir zunächst die Download-Seite anzeigen lassen, die ich dann ausparsen, bzw. aufgrund des fehlerhaften XHTML-Codes, mit Regex weiterverarbeiten kann.

Bei wget kriege ich ausserdem jeweils die Meldung "bad port number". Ich habe 443 bzw. nichts verwendet, da der Download-Link im Browser auch keinen speziellen Port verwendet. Komisch, dass das nicht funktioniert.
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Danielx
Beiträge: 6419
Registriert: 14.08.2003 17:52:23

Re: HTTPS-Download automatisieren

Beitrag von Danielx » 02.07.2009 11:42:10

uname hat geschrieben:evtl. mit Wireshark
Bei HTTPS wird das nicht ganz einfach. :wink:
paedubucher hat geschrieben:Von daher muss ich mir zunächst die Download-Seite anzeigen lassen
Dann schneide den Login-Vorgang z.B. mit HTTPFox mit, nicht nur auf die Login-Daten achten, sondern auch überprüfen, ob Cookies zur Authentifizierung verwendet werden.
Das Abrufen der Seite, z.B. mit cURL dürfte nicht so schwer sein, siehe z.B. mein Beispiel:
viewtopic.php?f=30&t=111527#p707226

Gruß,
Daniel

nepos
Beiträge: 5238
Registriert: 05.01.2005 10:08:12

Re: HTTPS-Download automatisieren

Beitrag von nepos » 02.07.2009 11:54:58

Hm, mal in Perl WWW::Mechanize und Co angeschaut?

uname
Beiträge: 12426
Registriert: 03.06.2008 09:33:02

Re: HTTPS-Download automatisieren

Beitrag von uname » 02.07.2009 13:34:39

Bei HTTPS wird das nicht ganz einfach.
Selbst

Selbst

Code: Alles auswählen

strace -ff -o out.txt iceweasel
führt zu keinen Ergebnissen. Ist eben eine Ende-zu-Ende-Verschlüsselung zwischen Browser und Webserver. Kann man vielleicht irgendwie im Browser selbst auslesen.

paedubucher
Beiträge: 939
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: HTTPS-Download automatisieren

Beitrag von paedubucher » 02.07.2009 14:15:36

@nepos: Danke für den Hinweis, ich werde das mal versuchen, wenn meine Perl-Kenntnisse etwas ausgereifter sind.

@Danielx: Vielen Dank, das habe ich hingekriegt!

Code: Alles auswählen

#!/bin/bash

CURL=/usr/bin/curl
HTML_1=/tmp/test_1.html
HTML_2=/tmp/test_2.html
COOKIE=/tmp/cookie.txt

DATA="un=[ich]&pw=[geheim]&Login=Anmelden"

# Anmelden
$CURL -s -S -L -d "$DATA" -c "$COOKIE" -o "$HTML_1" \
"https://login.salesforce.com/"

$CURL -s -S -L -b "$COOKIE" -o "$HTML_2" \
"https://emea.salesforce.com/ui/setup/export/DataExportPage/d"
Jetzt habe ich die HTML-Datei mit den Links auf die .zip-Dateien drin. Jetzt muss ich nur noch mit Regex darüber gehen und die Dinger per curl herunterladen. Mal schauen, wie ich das am besten mache...

Danke soweit!

EDIT: der relevante Parameter heisst "un" und nicht "username". Das hat mich etwa eine Stunde gekostet :oops:
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

paedubucher
Beiträge: 939
Registriert: 22.02.2009 16:19:02
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Schweiz
Kontaktdaten:

Re: HTTPS-Download automatisieren

Beitrag von paedubucher » 02.07.2009 17:46:17

Wunderbar, das Ding lädt :D

Hier das ganze Python-Skript: (ist natürlich noch verbesserungswürdig, erfüllt aber seinen Job)

Code: Alles auswählen

#!/usr/bin/python

import re
import os

loginData = 'un=[ich]&pw=[geheim]&Login=Anmelden'
downloadPage = 'downloadpage.html'
cookie = 'cookie.txt'
baseUrl = 'https://emea.salesforce.com'

# login to salesforce
loginCmd = 'curl -s -S -L -d "' + loginData + '" -o /dev/null -c "' + cookie + '" "https://login.salesforce.com/"'
print 'logging in to salesforce...'
os.system(loginCmd)
downloadCmd = 'curl -s -S -L -b "' + cookie + '" -o "' + downloadPage + '" "https://emea.salesforce.com/ui/setup/export/DataExportPage/d"'
print 'fetching filelist...'
os.system(downloadCmd)

# get the filenames
html_file = open(downloadPage, 'r')
content = html_file.read()
html_file.close()
os.remove(downloadPage)
p = re.compile('href="(.*\.ZIP.*)" class="actionLink"')
res = p.findall(content)

# download the files
n = 1
for filename in res:
	filename = filename.replace('&', '&')
	url = baseUrl + filename
	target = 'sf_backup' + str(n) + '.zip'
	n += 1
	downloadCmd = 'curl -s -S -L -b "' + cookie + '" -o "' + target + '" --connect-timeout 600 "' + url + '"'
	print 'start downloading file ' + target
	os.system(downloadCmd)
	print 'finished downloading file ' + target

os.remove(cookie)
Herzlichen Dank für die Unterstützung, die ich hier erhalten habe! Ein Hoch auf das Debian-Forum :hail:
Habe nun, ach! Java
Python und C-Sharp,
Und leider auch Visual Basic!
Durchaus programmiert mit heissem Bemühn.
Da steh' ich nun, ich armer Tor!
Und bin so klug als wie zuvor.

Danielx
Beiträge: 6419
Registriert: 14.08.2003 17:52:23

Re: HTTPS-Download automatisieren

Beitrag von Danielx » 03.07.2009 15:13:56

uname hat geschrieben:Kann man vielleicht irgendwie im Browser selbst auslesen.
Ich hatte ja schon auf HTTPFox hingewiesen.

Gruß,
Daniel

Antworten