Auslesen des Inhalts einer durch Login geschützten Website mit Java

Wenn eine Website eine POST-Authentifizierung erfordert (bspw. über ein Login-Formular) um Daten herunterzuladen, kann man dies mit den üblichen Java-Klassen lösen (z.B. mit URLConnection, siehe hier: Sending a POST Request Using a URL). Wenn aber ein Session-Konzept mit Cookies mit ins Spiel kommt, wird dies schon schwieriger.

Wie gut, dass es die Apache Commons-Bibliotheken gibt. Damit geht es recht einfach (wie auf Tutorials.de beschrieben). Eine nette Gegenüberstellung der beiden Methoden gibt es hier: A Comparison of java.net.URLConnection and HTTPClient.

package JavaTest; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; public class PostTest { public static void main(String[] args) { try { HttpClient client = new HttpClient(); GetMethod getMethod1 = new GetMethod("http://example.org/geheim.php"); client.executeMethod(getMethod1); System.out.println("Aufruf ohne Login -----------------"); System.out.println(getMethod1.getResponseBodyAsString()); System.out.println("-----------------------------------"); PostMethod postMethod1 = new PostMethod("http://example.org/login.php"); postMethod1.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); postMethod1.addParameter("name", "stefan"); postMethod1.addParameter("pass", "geheim"); client.executeMethod(postMethod1); System.out.println("Login -----------------------------"); System.out.println(postMethod1.getResponseBodyAsString()); System.out.println("-----------------------------------"); client.executeMethod(getMethod1); System.out.println("Aufruf nach Login -----------------"); System.out.println(getMethod1.getResponseBodyAsString()); System.out.println("-----------------------------------"); } catch (Exception e) { e.printStackTrace(); } } }

Wichtig wäre vielleicht noch, alle hierfür benötigten Bibliotheken einzubinden, damit man sich die vielen ClassNotFound-Exceptions sparen kann:

Über Stefan

Polyglot Clean Code Developer

13 Kommentare

  1. Also mit dem Titel hast Du mich ganz schön in die Irre geführt. Bin über deinen Blog-Beitrag eher zufällig gestolpert … was du eigentlich meinst, ist es POST-Daten mittels eines http-Client zu übertragen um dann in Folge in derselben Session weitere Seiten abrufen , das es sich dabei um eine Login-Form handelt ist dabei doch eher nebensächlich , oder?!?

  2. Da hast du natürlich Recht (das schreibe ich aber ja auch so). Mein Anliegen bei dem beschriebenen Progrämmchen war halt, eine passwortgeschützte Seite aufzurufen und dort eine Datei herunterzuladen. Deswegen die Überschrift 🙂

  3. Danke für den Post. Das ist echt interessant, auch die Links, die du mit an den Start gebracht hast. Da kann man sich gleich mal ein wenig weiter bilden, was ich jetzt auch tun werde! Obwohl es schon erschreckend ist, dass man die Daten so leicht finden kann.

  4. hallo stefan,
    ich versuche schon seit ein paar tagen ein solches script zu erstellen, welches sich auf einer webseite einloggt und dann im geschützten bereich informationen zu “holen”.
    aber irgendeinen fehler mache ich, aber weder mit dem sourcecode noch der von anderen webseiten funktioniert…
    ich versuch mich bei geocaching.com einzuloggen. was muss ich beachten?
    mein source ist wie folgt:

    //package JavaTest;

    import org.apache.commons.httpclient.HttpClient;

    import org.apache.commons.httpclient.cookie.CookiePolicy;

    import org.apache.commons.httpclient.methods.GetMethod;

    import org.apache.commons.httpclient.methods.PostMethod;

    public class PostTest

    {
    public static void main(String[] args)

    {
    try

    {

    HttpClient client = new HttpClient();

    GetMethod getMethod1 = new GetMethod(“http://www.geocaching.com/login/Default.aspx”);

    client.executeMethod(getMethod1);

    System.out.println(“Aufruf ohne Login —————–“);

    System.out.println(getMethod1.getResponseBodyAsString());

    System.out.println(“———————————–“);

    PostMethod postMethod1 = new PostMethod(“http://www.geocaching.com/login/Default.aspx”);
    postMethod1.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);

    postMethod1.addParameter(“myUsername”, “meinbenutzer”);

    postMethod1.addParameter(“myPassword”, “xxxxxx”);

    client.executeMethod(postMethod1);

    System.out.println(“Login —————————–“);

    System.out.println(postMethod1.getResponseBodyAsString());

    System.out.println(“———————————–“);

    client.executeMethod(getMethod1);

    System.out.println(“Aufruf nach Login —————–“);

    System.out.println(getMethod1.getResponseBodyAsString());

    System.out.println(“———————————–“);

    }

    catch (Exception e)

    {

    e.printStackTrace();

    }

    }

    }

    kannst du mir evtl einen tipp geben?
    das wäre seeeehr nett.
    vielen dank & grüße
    robert

  5. Ähem… also eine Fehlermeldung wäre durchaus sinnvoll. Was funktioniert denn nicht? Bis wohin läuft der Code?

  6. Das Problem liegt am login. Um sich bei Geocaching.com einzuloggen, musst du verschiedene ASP.NET Kriterien erfüllen, z.B musst du den erhaltenen Viewstate zurücksenden. Ob du den vorher anpassen musst oder nicht, weiß ich selber noch nicht, da ich da noch expirementiere.
    Wenn jemand hier eine Lösung weiß, wäre ich auch dankbar.
    Du kannst aber auf die Schnelle die Get-Methode zum Laufen bringen, indem du du deine userId als Cookie mitsendest. (Die kannst du aus dem Cookie auslesen, das dein Browser speichert.)

    GetMethod getM = new GetMethod(url);
    			getM.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
    			getM.setRequestHeader("Cookie", "userid=ab54f1234-d67e-afb5-bb75-69b3f20e453");
    
    int result = this.client.executeMethod(getM);
  7. Irgendwie wollte der Code nicht abgebildet werden. Also nochmal:

    GetMethod getM = new GetMethod(url); getM.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
    getM.setRequestHeader(“Cookie”, “userid=12345678-4fb3-bb45-b367-169b3f20e123”);
    int result = this.client.executeMethod(getM);

  8. Hallo, ich wollte dein Code ma ausprobieren, habe auch die von dir unten genannten Biblotehken eingebunden, aber anscheinend sind GetMethod & PostMethod, da gibt er mir nämlich eine Fehlermeldung aus (“Cannot find symbol”). Mfg

  9. Hallo Ralf. Hast du die Bibliotheken auch korrekt eingebunden (CLASSPATH)?

  10. Hallo,
    ich habe die Bibliotheken geladen und eingebunden. Allerdings scheinen die Bibliotheken für GetMethod und PostMethod zu fehlen. Zudem sind einige Bibliotheken fehlerhaft. Wäre super wenn du mir weiterhelfen könntest. 🙂

  11. Hallo Coke. Dann müsstest du mir mal deinen Code schicken. Ohne weitere Informationen kann ich dir leider nicht helfen.

  12. Hallo Stefan und Coke,

    das Problem lliegt wohl darin, dass Apache ab Version 3.x die Struktur ihrer Imports geändert hat.

    Hier der Link:
    http://hc.apache.org/httpclient-3.x/

    Allerdings hab ich die neue Post und Get Methode auch noch nicht zum laufen bekommen 🙁

    LG

  13. Good articles are articles that are considered to be of good quality

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax