[C++ mit libcurl] Captcha Abfrage automatisieren
-
Hi Leute

Bin froh dieses Forum gefunden zu haben, da ich mir vorstellen könnte, dass ihr mir das ein oder andere mal wenn ich beim programmieren "hängen bleibe" helfen könnt.
Da ich neu hier bin erstmal ein herzliches Hallo an alle.Nun zu meinem Problem:
Ich probiere derzeit ein wenig mit libcurl herum und habe noch nicht allzu viel Erfahrung, deshalb stehe ich vor einem Problem
Ich möchte ein Programm schreiben, dass auf einer bestimmten Webseite ein Captcha herunterläd, es dem Nutzer anzeigt, seine Eingabe annimmt, diese an die Seite sendet und weitergeleitet wird.
Ich lade also die Seite und speichere den Quelltext in einer Variablen:
CURL *curl; curl=curl_easy_init(); char buf[5000]=""; if(curl) { curl_easy_setopt(curl, CURLOPT_URL, sz); curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 0); curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 0); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiver); curl_easy_setopt(curl, CURLOPT_WRITEDATA, buf); curl_easy_perform(curl); }Ich nutze absichtlich kein cleanup, da ich die Verbindung halten möchte, auch zu erkennen an FORBID_REUSE = 0 und FRESH_CONNECT = 0
Nun folgt einiger Code, in dem ich die Adresse des Captcha-Bildes auslese.
Mit folgendem Code lade ich das Bild herunter:CURL *curl2; curl2=curl_easy_init(); FILE *f; f=fopen("cap.png", "wb"); if(curl2) { curl_easy_setopt(curl2, CURLOPT_URL, captcha); curl_easy_setopt(curl2, CURLOPT_WRITEDATA, f); curl_easy_perform(curl2); curl_easy_cleanup(curl2); }dieses Zeige ich an, nehme die Eingabe des Nutzers entgegen, verpacke diese als Post-Command und versuche das an die immer noch offene Verbindung vom Anfang zu senden mit:
curl_easy_setopt(curl, CURLOPT_URL, sz); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiver); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post); curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer); curl_easy_perform(curl); curl_easy_cleanup(curl);Allerdings kommt jedes mal die Meldung, dass es der falsche Captcha Text war.
Nun meine Frage: Habe ich einen Programmierfehler darin? oder einen Denkfehler? Muss ich mit Cookies arbeiten (habe ich versucht)?
Ist das Problem, dass ich zwischendurch eine zweite Verbindung zum Download des Bildes aufbaue? Eigentlich gibt es doch einen Connection Pool der per Grundeinstellung 5 Verbindungen akzeptiert und hält.
Ich weiß ehrlich gesagt nicht weiter.Ich hoffe ihr könnt mir helfen

Schönen Gruß
Face
-
Hey,
nur so nebenbei, dir ist bewusste das es ein C++ Wrapper gibt !?
Blessed love C0de4Fun
-
Ich versteh nicht ganz was du mir sagen willst.
Ich möchte das nunmal jetzt mit libcurl programmieren und hatte gefragt ob jemand meinen Fehler findet.
Kann nicht jemand mit viel Ahnung mal eben drüber schauen? dürfte doch echt keine große Sache sein.Gruß Face
-
Gut möglich, daß du ein Cookie mit der session-id senden musst. Das ist bei captchas oft so.
-
Habe es mit CURLOPT_COOKIESESSION probiert, mit COOKIEFILE, COOKIEJAR, aber es klappt einfach nicht. Jemand noch eine andere Idee?!
-
So ich habe mal weiter herumprobiert.
Ich glaube mittlerweile, dass es tatsächlich mit der Session-id zusammenhängt.
Habe in Firefox die Cookies ausgeschaltet und versucht das Captcha einzugeben aber dann kommt auch dass es der falsche Captcha Text war.
Außerdem habe ich mir die Header meiner Requests angesehen.
Egal wie ich mit den Curl-Options Arbeite bekomme ich es nicht hin in den 2 Requests die gleiche Session ID zu senden.Wenn ich im ersten Schritt die ID mit CURLOPT_COOKIEJAR speichere, sendet mein zweites Request, trotz CURLOPT_COOKIEFILE, keine Session ID an den Server.
Woran könnte das liegen?!
-
Face schrieb:
Wenn ich im ersten Schritt die ID mit CURLOPT_COOKIEJAR speichere, sendet mein zweites Request, trotz CURLOPT_COOKIEFILE, keine Session ID an den Server.
Da hast du was falsch verstanden.
CURLOPT_COOKIEJARspeichert die Cookies ins angegebene File erst, wenn eincleanuperfolgt.COOKIEJARdient eigentlich für die Kommunikation zwischen mehreren Handles.Standardmässig sind die Cookies in libcurl nicht aktiviert und werden einfach ignoriert. Um die Cookies zu aktivieren, ruft man am besten einmal
CURLOPT_COOKIEFILEauf gleich nach dem Initialisieren des Handles. Dann sollten die Cookies empfangen und gelesen werden. Beim nächsten Request sollten automatisch die richtigen Cookies zurückgesendet werden. Ein weiterer Aufruf vonCURLOPT_COOKIEFILEist nicht nötig. Man kann im übrigen auch beiCURLOPT_COOKIEFILEeinen Pfad angeben, welcher nicht existiert. Dann werden die Cookies im RAM verwaltet.Ist leider schon etwas her, seit ich das letzte Mal mit libcurl gearbeitet habe, aber ich hoffe, dass dies bereits weiterhilft. Ansonsten zeig mal einen kurzen Code, wie du die Abfrage mit den Cookies durchgeführt hast.
Grüssli
-
Probier mal curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
Dann mach dein perform und lad das Captcha runter und mach anschließend ein erneutes perform mit der anderen URL.
**
Erst wenn du alle Anfragen abgeschlossen hast und dein Programm sich dem Ende nähert und Curl nicht mehr benötigt wird, kannst du das Handle mit cleanup wieder freigeben.**
-
Hi, erstmal danke für die Hilfe, aber es klappt trotzdem noch nicht so recht.
Ich lasse jetzt alle Anfragen über ein Handle laufen.CURL *curl; curl=curl_easy_init(); char buf[5000]=""; if(curl) { curl_easy_setopt(curl, CURLOPT_URL, sz); curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiver); curl_easy_setopt(curl, CURLOPT_WRITEDATA, buf); curl_easy_perform(curl); }FILE *f; f=fopen("cap.png", "wb"); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, captcha); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, 0); curl_easy_setopt(curl, CURLOPT_WRITEDATA, f); curl_easy_perform(curl); }char buffe[50000]=""; if(curl) { curl_easy_setopt(curl, CURLOPT_URL, sz); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiver); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post); curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffe); curl_easy_perform(curl); curl_easy_cleanup(curl); }So funktioniert es leider immer noch nicht.
Ich habe mir den Header von Anfrage 3 angesehen und es wir nicht die Session-id von vorher mitgesendet.
Was ist falsch an dem Code?
-
Wenn ich CURLOPT_COOKIEFILE weglasse, sehen meine Header logischerweise so aus:
HTTP/1.1 200 OK Date: Sun, 12 Sep 2010 13:06:20 GMT Server: Apache Set-Cookie: PHPSESSID=a396439358e3e360feb98250fc0057ea; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Vary: Accept-Encoding Content-Length: 4151 Connection: close Content-Type: text/html HTTP/1.1 200 OK Date: Sun, 12 Sep 2010 13:06:20 GMT Server: Apache Set-Cookie: PHPSESSID=45fbf671039c41402c16da228882dc85; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Connection: close Transfer-Encoding: chunked Content-Type: image/png HTTP/1.1 200 OK Date: Sun, 12 Sep 2010 13:06:28 GMT Server: Apache Set-Cookie: PHPSESSID=dd3e76b1ba36a581e2caf83e5534e0b9; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Vary: Accept-Encoding Content-Length: 4264 Connection: close Content-Type: text/htmlJeder eine andere Session ID.
Wenn ich COOKIEFILE hinzufüge sehen sie so aus:HTTP/1.1 200 OK Date: Sun, 12 Sep 2010 13:08:54 GMT Server: Apache Set-Cookie: PHPSESSID=2c57156f271434c683fec2ce55482d79; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Vary: Accept-Encoding Content-Length: 4147 Connection: close Content-Type: text/html HTTP/1.1 200 OK Date: Sun, 12 Sep 2010 13:08:54 GMT Server: Apache Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Connection: close Transfer-Encoding: chunked Content-Type: image/png HTTP/1.1 200 OK Date: Sun, 12 Sep 2010 13:09:00 GMT Server: Apache Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Vary: Accept-Encoding Content-Length: 4260 Connection: close Content-Type: text/htmlWarum haben die 2te und 3te Anfrage plötzlich keine Session ID mehr?!
Ich versteh das nicht.
Wie bekomm ich es hin, dass jedesmal dieselbe gesendet wird?!
Oder wird sie gesendet und steht nur nicht bei Set-Cookie weil sie nicht neu gesetzt wird, aber müsste sie dann nicht irgendwo im Header auftauchen?!
-
Was du uns hier präsentierst, sind die Antworten des Servers. Wenn man ihm eine gültige Session-ID zurücksendet, gibt er natürlich nicht mehr die Anweisung, dass der Client ein Cookie setzen soll, denn es wurde bereits gesetzt.
Ich würde langsam mal darauf tippen, dass du wirklich den falschen Captcha Text zurücksendest. Kannst du den Code nicht auf ein kurzes Beispiel reduzieren, so dass wir ihn selber testen können?
Grüssli
-
Hab dir ne Mail geschickt.
Vielleicht siehst du dir das mal an
-
toll mail. damit auch keiner der irgendwann mal das gleiche problem hat deine lösung nutzen kann
-
Face schrieb:
Hab dir ne Mail geschickt.
Vielleicht siehst du dir das mal an
ROFL ...
Es geht um eine Warez Seite. Damit erlischt meine Hilfsbereichtschaft in diesem Fall und zwar einfach schon nur rein persönlich. Zudem hatte ich dir gesagt, dass du einen reduzierten Code präsentieren sollst. Einen Code hast du aber nicht mal angefügt.Viel Glück noch ...
Grüssli