Webseiteninhalt auslesen aber wie...
-
Hallo,
ich möchte aus einer lokalen WinApi-Anwendung folgendes machen:
Eine Suchanfrage an eine Web-Site schicken und das Ergebnis auslesen.
Ein Beispiel wäre:
https://portal.d-nb.de/opac.htm?method=simpleSearch&query=3860631888
Sucht in der deutschen Nationalbibliothek eine ISBN und zeigt sie an.
Diese Buchdaten möchten ich dann in eine Maske einlesen und in einer Datenbank speichern. (Das Alles ist ja auch kein Problem, wenn ich nur an die Daten käme.)Folgende Dinge habe ich bereits probiert:
Per Socket und http-Protokol mit POST oder GET versucht die Seite abzuholen.
Ich erhalte dann zwar tatsächlich eine Web-Site zurück aber dort fehlen die angefragten Daten.
Im Web-Browser klappen die Anfragen jedoch einwandfrei.Nun habe ich den WebBrowser.lib für Minggw-gcc (APITalk.com) installiert und in meine lokale Anwendung eingebaut. Diesen habe ich dann in ein riesiges edit-Feld gelegt.
Wenn ich nun meine lokale Anwendung starte, dann habe ich im oberen Bereich des Fensters meine Eingabemaske für die Daten und im unteren Bereich erscheinen die Web-Seiten im edit-Feld, welches als Web-Browser dient.Meine Suchanfragen werden angezeigt, und ich kann sie mit Hilfe der Zwuschenablage in meine Maske einlesen.
Soweit alles zur vollen Zufriedenheit, jedoch ist das ganze doch recht umständlich.
1.ISBN eingeben, Browser lädt fertige Suchanfrage.
2.Buchdaten markieren und per rechten Mausklick in Clipboard kopieren.
3.Lokale Anwendung liest Clipboard aus und verarbeitet die Daten.Mein Wunschvorgehen wäre es, wenn ich das Browserfenster irgendwie komplett auslesen könnte, ohne selbst mit dem Clipboard arbeiten zu müssen.
1.ISBN eingeben, Browser lädt Suchanfrage.
2.Daten werden ausgelesen und verarbeitet.Nun zu meiner Frage:
Kennt sich jemand mit dieser Webbrowser.lib aus?
Es fehlt jegliche Dokumentation.
Es scheint auch nur diese vier Funktionen zu geben:OpenURL(hwnd,"http://www.d-nb.de"); CreateBrowserWindow(hwnd); HWND browser = GetBrowserHandle(hwnd); DestroyBrowserWindow(hwnd);Weiterhin benötigt wird noch:
OleInitialize(NULL); OleUninitialize();Mein bisheriges Vorgehen:
Ein edit-Feld erstellen:bwindow = CreateWindow("edit","", // erstellt ein edit feld ES_AUTOHSCROLL |WS_VISIBLE|WS_CHILD|WS_BORDER, 10,HOEHE-370,BREITE-10,300, pHwnd,(HMENU)100000, hInstGlobal, NULL);Dann:
Browser mit edit-Feld verknüpfen und darin Web-Site öffnen.OleInitialize(NULL); CreateBrowserWindow(bwindow); OpenURL(bwindow, "http://www.d-nb.de"); OleUninitialize();Klappt wunderbar, kann auch zwischen verschiedenen URLs wechseln, Clipboard auswerten usw.
Nun dachte ich, ich könnte mit
SendMessage(bwindow,WM_GETTEXT,lenght,(LPARAM)text);den Inhalt des Browserfensters auslesen. Geht aber nicht.
Der Browser scheint über dem edit-Feld (ähnlich wie eine Bitmap) zu liegen.Auch, wenn ich vorher mit GetBrowserHandle() mir das Handle des Fensters hole, ich komme nicht an den Inhalt des Browser ran.
Wie komme ich an den Inhalt des Browser ran?
Gibt es da irgendetwas wie direkt den Text aus dem Speicherbereich des Browsers auslesen?
(Dabei ist es wichtig, daß es innerhalb einer lokalen Anwendung umgesetzt wird)Gibt es noch andere Möglichkeiten, Ergebnisse solcher Suchanfragen auszulesen? Muß ich meine GET/POST Anfrage anders gestalten?
char http_req[]= "POST /search.vm HTTP/1.1\r\n" "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,*/*;q=0.5\r\n" "Referer:\r\n" "Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "Accept-Encoding: deflate\r\n" "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)\r\n" "Host: www.d-nb.de\r\n" "Content-Length: 00\r\n" "Connection: Keep-Alive\r\n" "Cache-Control: no-cache\r\n\r\n"; char http_line_req[]="query=3860631888\r\n"; send(s,http_req,strlen(http_req),0); send(s,http_line_req,strlen(http_line_req),0)Mit dieser Methodfe erhalte ich eine Web-Site, aber aufgrund von XHTML-Problemen stehen da nicht die angeforderten Daten drin.
Hier auch mal die obersten Zeilen, der empfangenen Web-Site:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.d-nb.de/standards/w3c/xhtml1/dtd/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de" dir="ltr">Vielleicht weiss ja einer etwas,
vielen Dank,DC
-
Jetzt ohne konkret helfen zu können gehen mir doch zwei dinge durch den Kopf:
- Sind auf dieser Webseite automatisierte Abfragen erlaubt?
- Werden Session-Cookies verwendet die deine Abfrage kaputt machen?
-
Hmmm, habe nun mal versucht mit Hilfe von curl (erleichtert die http-Anfragen ungemein) auf diese Seite zuzugreifen.
Dort bekomme dann tatsächlich eine Autentifizierungs-Problem-Fehlermeldung.
Offenbar wird die POST Anfrage tatsächlich geblockt.Dann würde mich natürlcih umso mehr interessieren, ob es eien Möglichkeit gibt, dann direkt das Browser-Fenster auszulesen.
Gruß,
DC
-
Du hast schon gesehen dass dies eine https Seite ist? Also mit curl geht das.
-
Na, danke für den Hinweis.
Nun habe ich bei curl mal die SSL Optionen mit bei meiner Anfrage hinzugefügt und was passiert?
Ich erhalte tatsächlich eine korrekte Ausführung meiner Suchanfrage.Problem ist nun eigentlich schon gelöst.

Nochmals vielen Dank für die Denkanstöße.Gibt es auch eine Möglichkeit das Ganze ohne curl zu lösen, oder wird diese SSL Geschichte dann zu kompliziert?
Gruß,
DC
-
Na du brauchst die "libcurl.lib" (von curl), die "libeay32MT.lib" (von OpenSSL, *MT kann variieren) und die "ssleay32MT.lib" (von OpenSSL, *MT kann variieren). Dann ruft du ein paar mal die Funktion "curl_easy_setopt(...)" mit entsprechenden Parametern auf und fertig du hast dann deine https Seite in einem buffer.
Könnte z.B. so aussehen:boolean GetHttpsSite(char *https_site){ CURL *curl; CURLcode res; buff_t bf; curl = curl_easy_init(); if(!curl){ return FALSE; } memset(&bf, 0, sizeof(bf)); curl_easy_setopt(curl, CURLOPT_URL, https_site); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //SKIP_PEER_VERIFICATION curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); //SKIP_HOSTNAME_VERFICATION curl_easy_setopt(curl, CURLOPT_WRITEDATA, &bf); //http://curl.haxx.se/libcurl/c/libcurl-tutorial.html curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_curlwritebufferdata); //das msachst du mal schön selbern, sollst ja was lernen res = curl_easy_perform(curl); curl_easy_cleanup(curl); if(bf.len_buffer > 0){ // Do something with "bf.buffer" free(bf.buffer); return TRUE; }else{ return FALSE; } }
-
Jupp, vielen Dank.
Läuft super.
Gruß,
DC