HTTP Formulare füllen und Datei downloaden

kevin9r

Aktives Mitglied
Guten Abend,
ich habe da mal eine Frage. Ich würde gerne eine Methode schreiben, welche mir eine Datei von einer Website downloaded. Das Problem ist, dass ich auf der Website erstmal 4 Formulare füllen muss und dann den Submit Button drücken muss und erst dann wird die Datei heruntergeladen.

Ich habe mich nie mit Netzwerkprogrammierung auseinander gesetzt und bin auch ein Java Anfänger. Ich hätte jetzt erstmal die Frage ob dies a) überhaupt möglich ist und b) welche Möglichkeiten es da gibt.
Das Problem ist einfach folgendes.
Drücke ich nach Dateneingabe den Submit Button öffnet sich ein neues Fenster (ohne sichtbaren Link) und der download beginnt (ich bekomme keinen Weiterleitungslink o.ä.).

Ich hoffe Ihr könnt mir da paar Tips geben wie ich da an die Sache dran gehen soll.

Vielen Dank!
 
Hey kevin9r,

schau dir mal http://htmlunit.sourceforge.net/gettingStarted.html an.
Damit kannst du relativ einfach sowas machen:

Java:
WebClient webClient = new WebClient();
HtmlPage page = webClient.getPage("http://foo-bar.de/");
HtmlForm form = page.getFormByName("form1");
form.getInputByName("inputText").setValueAttribute("text");
form.getTextAreaByName("textArea").setTextContent("other text");
form.getInputByName("checkbox").setChecked(true);
HtmlPage page2 = form.getInputByName("submit").click();

Hoffe, dass es das ist was du suchst.
 
Hey, wow danke, das sieht genau danach aus wonach ich gesucht habe.
Hast du schon einmal damit gearbeitet? Tue mir gerade etwas schwer (habe noch Schwierigkeiten damit die API richtig zu lesen und zu deuten und die Objektorientierung ist auch noch nicht so recht meins, aber ich arbeite daran). Schau mal, so sieht das Formular aus:

login24.jpg
Java:
form.getInputByName("inputText").setValueAttribute("text");
form.getTextAreaByName("textArea").setTextContent("other text");
form.getInputByName("checkbox").setChecked(true);

Das ist eigentlich ganze verständlich aber eclipse spuckt mir einen Fehler aus?

Der Name form1 ist der name des Feldes, welchen ich auf der Website im Quelltext sehen kann?
 
Habe es mal verwendet - ist aber eine weile her.

form ist die ID des Formulars auf der Website. getInputname("..") ist die ID des Inputfeldes und mit setValueAttribute setzt du eben den Content des Feldes.

Was spuckt er dir denn für ein Fehler aus?

Und was verstehst du denn genau nicht? Stell Fragen dann hilft man dir auch 😉
 
Ich bekomme das einfach nicht hin.. habe jetzt folgendes geschrieben:

Code:
            WebClient webClient = new WebClient();
            HtmlPage currentPage = webClient.getPage("http://www.test.com/api/csv/");
            
            //Get the query input text
            HtmlInput user = currentPage.getElementByName("username");
            user.setValueAttribute("user");
           
            HtmlInput pass = currentPage.getElementByName("password");
            pass.setValueAttribute("root");
           
            HtmlInput datef = currentPage.getElementByName("datefrom");
            datef.setValueAttribute("2015-01-01");
           
            HtmlInput dateto = currentPage.getElementByName("dateto");
           
           //Heutiges Datum in String
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); // Format für 24-Stunden-Anzeige
            String str = dateFormat.format(new Date());
           
            dateto.setValueAttribute(str);
            
            //Submit the form by pressing the submit button
            HtmlSubmitInput submitBtn = currentPage.getElementByName("Submit");
            currentPage = submitBtn.click();

Bekomme nur eine ElementNotFoundException.

In dem getElementByName stehen immer die Namen aus dem Quelltext:
<input name="password" value="" type="password">

Nur beim Button habe ich folgende Angaben:
<input value="Submit" type="submit">
Hier ist kein Name.

Und wenn ich das irgendwie zum laufen bekomme, muss ich ja auch noch irgendwie die Datei downloaden. Gibt es da auch irgendwelche Methoden?
 
Die Elemente müssten auf der Website eigentlich in eine Form eingebettet sein.
Daher musst du dir die Form mit HtmlForm noch holen.
 
Stimmt, schau mal:
<form method="POST" target="result"> ?

und dann muss ich noch:
Code:
HtmlForm form = currentPage.getFormByName("??????");
einbinden. Aber was übergebe ich da?
 
Ist das denn überhaupt mit dem HTTP Post Request möglich? Ich weiß ja eben überhaupt nicht wie ich nach dem klick auf den Submit Button weiterverlinkt werde? Hatte mich versucht da jetzt einzulesen aber irgendwie...
Also bei der GET Methode schicke ich so wie ich das verstanden habe einen Link zum Server der die Informationen bereits enthält (das ist ja in meinem Fall nicht möglich) ..

Bei der POST Methode werden die Parameter in einen Block gesetzt und übertragen? Was bedeutet das mit "in einen Block gesetzt"? Und werden mit Parameter dann die Formularwerte gemeint?
Puh ist alles nicht so leicht.. und das mit dem htmlunit klappt nicht?
 
Also ich mische mich jetzt doch noch mal mit meinem HTMLUNIT ein.

Ich meine, dass ich ein Weg gefunden habe, dein Problem mit dem ElementNotFount gefunden zu haben.

Java:
        WebClient webClient = new WebClient();
        HtmlPage currentPage = webClient.getPage("https://www.beds24.com/api/csv/getbookingscsv");

        List<HtmlForm> forms = currentPage.getForms();
       
        System.out.println(String.valueOf(forms.size()));
       
        HtmlForm form = forms.get(0);
       
        HtmlInput name = form.getInputByName("username");
        name.setValueAttribute("bla");
       
        System.out.println(name.getValueAttribute());
       
        HtmlSubmitInput submitBtn = form.getInputByValue("Submit");
       
        HtmlPage p2 = submitBtn.click();

Es gibt eine Methode, die dir alle Forms (ist das der Plural? 😀 ) ausgibt.
Wenn du eine List<HtmlForm> anlegst, und sie mit currentPage.getForms() initialisierst, hast du eine Liste mit allen.
Ich hab es getestet, die länge der liste ist 1. also hast du nur eine form. --> deine form ist forms.get(0).

Wenn du dir jetzt eine HtmlForm Instanz machst und über diese deine Elemente holst, dann funktioniert der Code.

So kannst du erstmal alle Form erstmal abarbeiten. Es gibt auch wege mit htmlunit pdfs zu downloaden, aber mach erstmal das eine 🙂


Hoffe es klappt so wie du es willst!

Gruß
Robert
 
hey super, scheint geklappt zu haben? Es tauchen keine Fehler auf. In der Konsolenausgabe erhalte ich einfach eine 1? Ich meine darauf folgt ja sofort ein Dateidownload, das muss man vermutlich ja jetzt irgendwie programmieren. Ich versuche mich morgen mal in der API darüber schlau zu machen, was diese eins heißt und wie ich nun zum download komme... hast du da auch noch tipps?
Danke schonmal!
 
Hast du mein Code kopiert? Wenn ja kommt die 1 weil ich mir die Länge der Liste ausgeben lassen habe 😀

Weiß nicht in welcher Form es nach dem Post weiter geht, also ob deine Anfrage mit js, jq, oder etwas anderem gemacht ist aber du kannst dir bswp die query holen und damit weiter arbeiten - Aber da musst du mal Google befragen

Kein Problem

Gruß
Robert
 
ach mist, ja habe die Zeile zur getForms und die Ausgabe kopiert :-D Ok, ich muss ins Bett! 😀
noch eine Frage, wie meinst du die Query holen? Also nach dem Absenden des Post wird dann irgendwie ein JavaScript ausgeführt das dann die Datei erzeugt und zum download weitergibt, verstehe ich das richtig? Und was meinst du jetzt mit Query?

Nach
HtmlPage p2 = submitBtn.click();
steht in p2 nur:
HtmlPage(https://www.beds24.com/api/csv/getbookingscsv)@1957078537

komplizierte Sache... 😕
 
Ach ne das alte Copy Paste Problem 😉

Was du da ausgegeben hast, ist ein sehr oft gemachter Fehler. Viele versuchen eine Instanz eines Objektes in die print Methode rein zu hauen um den Inhalt zu kriegen aber das gibt dir nur die speicheradresse von der Instanz (Page 2) aus.@.. ist also die Adresse im Speicher 🙂

Ich nehme an, dass du den Link zum Download der Datei kennst? Dann könnte das hier deine Lösung sein:

Java:
try{
    InputStream is = downloadLink.click().getWebResponse().getContentAsStream();
    try{
        File f =newFile("filename.extension");
        OutputStream os =newFileOutputStream(f);
        byte[] bytes =newbyte[1024];
        while(read = is.read(bytes)){
            os.write(bytes,0, read);
        }
        os.close();
        is.close();
    }catch(IOException ex){
        // Exception handling
    }
}catch(IOException ex){
    // Exception handling
}


Gruß
Robert
 
Hallo Robot,
nein, wenn ich auf den Submit Button drücke, dann ist das einzige was sich öffnet ein Downloadfenster. Mehr passiert da nicht mehr? Ich müsste also dann irgendwie diesen download abfangen? Aber was soll ich in deinem oben beispielhaften Quelltext als downloadLink angeben, wenn ich da überhaupt keinen Link bekomme wenn ich auf Submit klicke?
 
downloadLink kannst du in dem Fall mit deiner HtmlPage Instanze ersetzen. (in meinem ersten Bsp. wäre das p2.)
Über p2 kannst du dann
Java:
p2.getWebResponse().getContentAsStream();
aufrufen.

Versuch das mal und guck, ob das File erstellt wird / in deinem Inputstream überhaupt etwas drin steht.

Kann es leider nicht testen, da ich die Daten zum einloggen für das Formular nicht habe.

Gruß
Robert
 
Der Weg über das HTML-Fomrular zu gehen etc ist ein riesiger Umweg.^^
Das ist als API gedacht, also völlig unabhängig von den HTML-Seiten. Alles was man machen muss, ist ein einfacher HTTP-Post mit den benötigten Daten, die Antwort ist dann der csv-Content.
 
Der Weg über das HTML-Fomrular zu gehen etc ist ein riesiger Umweg.^^
Das ist als API gedacht, also völlig unabhängig von den HTML-Seiten. Alles was man machen muss, ist ein einfacher HTTP-Post mit den benötigten Daten, die Antwort ist dann der csv-Content.

Dann gib ihm doch mal ein Beispiel - er hat ja nach deinem ersten Post schon gesagt, dass er nicht so Recht weiß wie ^^
 
So etwa:

Java:
        String url = "https://www.beds24.com/api/csv/getbookingscsv";
        URL obj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

        con.setRequestMethod("POST");

        String params = "username=XXX&password=YYY";

        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(params);
        wr.flush();

        BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream()));
       
        StringBuilder response = new StringBuilder();

        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        System.out.println(response.toString());
Streams müssen noch passend geschlossen und Exceptions behandelt werden, dass sollte er aber wohl schaffen...
 
😱😱😱
wow... das hat geklappt...
und sogar ohne download der datei.. jetzt habe ich mich so lange darum bemüht eine CSV Datei auszulesen und in eine Mysql Datenbank zu schreiben und jetzt bekomme ich die Daten schön in einem String serviert.. Top.
Das das so simple ist... Ich werde mir jetzt die Methoden mal genauer ansehen, damit ich das auch verstehe. Um die Exceptions und das schließen der Streams kümmer ich mich jetzt selber.
Ich danke euch echt vielmals, habt mir echt weitergeholfen!
 

Neue Themen


Zurück
Oben