PEAR-Forum.de Übersicht Thema anzeigen - [HowTo] Google-Webservice mit SOAP, ITX und QuickForm

[HowTo] Google-Webservice mit SOAP, ITX und QuickForm


 

PEAR-Forum.de Übersicht » HowTo´s, Tutorials, Codebeispiele und Wissenswertes
Neues Thema eröffnen Neue Antwort erstellen Diesen Beitrag ausdrucken
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
MaGdev
Site Admin


Anmeldungsdatum: 04.02.2004
Beiträge: 719
Wohnort: Hamburg

Beitrag10.06.2005 19:33    [HowTo] Google-Webservice mit SOAP, ITX und QuickForm Antworten mit Zitat

Eine Suchseite, die sich des Google-Webservices bedient, kann man sich mit einigen PEAR-Klassen problemlos selber programmieren.

Wenn man den Dienst in Anspruch nehmen möchte, muss man sich zunächst mal unter http://www.google.com/apis anmelden. Ihr erhaltet dann eine eMail zur Bestätigung, in dem per Link die Registrierung aktiviert werden muss. Danach kann man sich anmelden und erhält daraufhin eine weitere eMail mit dem Benutzer-Code.
Dann solltet Ihr euch noch die API-Dokumentation unter http://www.google.com/apis/download.html herunterladen. Neben der Dokumentation findet ihr hier noch vorgefertigte Klassen und Funktionen für Java und .NET.

Ausserdem gibt es einige Beschränkungen für die Nutzung des Dienstes. Man darf z.B. nur 1000 Abfragen pro Tag senden und bekommt nur 10 Ergebnisse zurück. Für den Hausgebrauch dürften diese Werte allerdings vollkommen ausreichen.

Funktion zur Abfrage des Dienstes erstellen
Für die eigentlich Abfrage des Webservices schreiben wir uns eine Funktion, die auch die SOAP-Funktionalität enthält.
Die Funktion nimmt mehrere Parameter entgegen. Einige Werte sind vorbelegt, so das letztendlich nur der erste Parameter, nämlich der zu suchende String, übergeben werden muss. Die genaue Bedeutung der einzelnen Parameter entnehmt bitte der Google-API-Dokumentation. Die globalen Variablen $dev_key (Benutzer-Code) und $lang (Sprache der Ergebnisse) wurden zur Konfiguration ausserhalb der Funktion definiert.

PHP:
<?php
function google($query_string,$safeSearch=false,$filter=false,$start=1)
{
    global 
$dev_key,$lang;
    
$client=&new SOAP_Client("http://api.google.com/search/beta2");
    
$param=array(
        
'key' => $dev_key,
        
'q' => $query_string,
        
'start' => $start,
        
'maxResults' => 10,
        
'filter' => $filter,
        
'restrict' => '',
        
'safeSearch' => $safeSearch,
        
'lr' => $lang,
        
'oe' => '',
        
'ie' => ''
    
);
    
$result=$client->call('doGoogleSearch',$param,'urn:GoogleSearch');
    return 
$result;
}
?>


Als erstes instanzieren wir ein neues Objekt der Klasse SOAP_Client und übergeben dem Konstruktor den Serverpfad. Dann brauchen wir nur noch die Methode call() dieses Objekts mit dem Methodennamen des Webservice, dem zuvor definiertem Parameter-Array und dem zu verwendenden Namespace aufrufen und das erhaltene Objekt vom Typ stdClass zurückgeben.

Template-System laden
Jetzt können wir mit der eigentlichen Suchseite anfangen. Dazu instanzieren wir zunächst ein HTML_Template_ITX-Objekt. Dem Konstruktor übergeben wir den Pfad zum Verzeichnis, in dem die Template-Dateien liegen. Dann laden wir das globale Template (index.htm) und setzen die beiden Variablen {DOCUMENT_TITLE} und {FOOTER}.

PHP:
<?php
$tpl
=&new HTML_Template_ITX("./templates");
$tpl->loadTemplatefile("index.htm");

$tpl->setVariable(array(
    
'DOCUMENT_TITLE' => 'Google-Suchseite: powered by Caddata',
    
'FOOTER' => '<a href="http://www.caddata.de" target="_blank">powered by caddata</a>'
));
?>


Suchmaske mit QuickForm aufbauen
Unsere Suchmaske besteht nur aus einem Textfeld und dem Submit-Button. Auf die Formatierungsmöglichkeiten der QuickForm-Klasse gehen wir nicht näher ein.
Unser Textfeld soll von QuickForm automatisch überprüft werden.

PHP:
<?php
$form
=&new HTML_QuickForm('searchbox','post');
$form->addElement('text','query','Suchworte');
$form->addElement('submit','submit','Suche starten');
$form->addRule('query','Bitte geben Sie ein Suchwort ein!','required');
if (
$form->validate())
{
    
$form->process('process_data'false);
} else {
    
$tpl->setVariable(array(
        
'CONTENT' => '<center>'.$form->toHTML().'</center>'
    
));
}
?>


Dem Konstruktor übergeben wir den Namen des Formulars und die Übergabe-Methode, in diesem Fall 'post'. Dann fügen wir mit addElement ein Textfeld ('text') mit dem Namen 'query' und dem Label 'Suchworte' hinzu. Nach dem erzeugen des Submit-Buttons fügen wir noch mit addRule() eine Regel ein. Als Parameter übergeben wir den Namen des Feldes, das überprüft werden soll, eine Fehlermeldung und den Typ der Überprüfung, in unserem Fall 'required'.

Jetzt ist unser Formular fertig und wir prüfen mit validate(), ob das Formular bereits übergeben wurde und alle Regeln erfüllt wurden. Gibt validate() 'true' zurück, können wir das Formular absenden. Per Voreinstellung wird das Formular an sich selbst gesendet.
Im Fehlerfall (oder wenn das Formualr noch gar nicht gesendet wurde) gibt validate() 'false'zurück und wir übergeben das Formular zur Anzeige der Template-Variablen {CONTENT}. Dafür benutzen wir die QuickForm-Methode toHTML(), die den HTML-Quellcode zurückgibt.

Die Ergebnisse anzeigen
Kommen wir zur Auswertung der Ergebnisliste. Als erstes reinigen wir die Übergabe aus $_POST['query'] mit trim() und strip_tags(). Dann übergeben wir den Querystring an die Funktion von oben.
Die Rückgabe prüfen wir auf einen PEAR-Fehler und übergeben ggf. die zurückgelieferte Fehlermeldung an die Template-Variable {CONTENT}. Ist kein Fehler aufgetreten, können wir anfangen, die Ergebnisse auzuwerten.

PHP:
<?php
$query
=trim(strip_tags($_POST['query']));
$res=google($query);
if(
PEAR::isError($res))
{
    
$tpl->setVariable(array(
        
'CONTENT' => $res->getMessage()
    ));
} else {

// Ergebnisse anzeigen
?>


Um die Ergebnisse anzuzeigen, laden wir zunächst das entsprechende Template in die Template-Variable {CONTENT}. Danach besetzen wir die Template-Variablen {HEADER} und {METADATA} mit den der Anzahl der gefundenen Seiten ($res->estimatedTotalResultsCount) und der Dauer der Abfrage ($res->searchTime), sowie den Zurück-Button mit einem Javascript-Link.
Jetzt überprüfen wir, ob ein Ergebnis-Array zurückgeliefert wurde. Ist dies der Fall, setzen wir den Template-Block 'result_row' aktiv und füllen ihn mit einer foreach()-Schleife so oft wir ihn benötigen. Wir erreichen das, indem wir den aktiven Block innerhalb der Schleife mit Daten füllen und parsen. Danach parsen wir den eingefügten Ergebniss-Block (parse('results')) und die Ergebnisliste ist fertig.

PHP:
<?php
$tpl
->addBlockfile('CONTENT','results','results.htm');
$tpl->setCurrentBlock('results');
$tpl->setVariable(array(
    
'HEADER' => 'Gefundene Seiten: '.$res->estimatedTotalResultsCount,
    
'METADATA' => 'Benötigte Zeit: '.$res->searchTime,
    
'GO_BACK' => '<a href="#" target="_self" onclick="javascript&#058;window.history.back()">Zurück</a>'
));
        
if(
is_array($res->resultElements))
{
    
$tpl->setCurrentBlock('result_row');
    foreach(
$res->resultElements as $element)
    {
        
$tpl->setVariable(array(
            
'U_TITLE' => $element->URL,
            
'TITLE' => utf8_decode($element->title),
            
'SNIPPET' => utf8_decode($element->snippet)
        ));
        
$tpl->parse('result_row');
    }
}
$tpl->parse('results');
?>


Zu guter letzt parsen wir das gesamte Template mit $tpl->parse() und geben es mit $tpl->show() an den Browser.

_________________
Auch der längste Weg beginnt immer mit einem kleinem Schritt!

Vorgehen bei Problemen:
1. PHP-Handbuch oder PEAR-Handbuch lesen!
2. Forensuche benutzen!
3. Fragen posten und dabei die Regeln beachten!


Zuletzt bearbeitet von MaGdev am 26.08.2005 22:05, insgesamt 2-mal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Twilo
Neuer User


Anmeldungsdatum: 05.07.2005
Beiträge: 12
Wohnort: Berlin

Beitrag05.07.2005 0:09     Antworten mit Zitat

Hallo,

ich bekomme immer nur folgende Meldung
Zitat:
/search/beta2No Deserializer found to deserialize a 'urn:GoogleSearch:ns4:key' using encoding style 'http://schemas.xmlsoap.org/soap/encoding/'.

woran könnte dies liegen?

mfg
Twilo

_________________
Farbtabelle


Zuletzt bearbeitet von Twilo am 11.06.2006 19:19, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MaGdev
Site Admin


Anmeldungsdatum: 04.02.2004
Beiträge: 719
Wohnort: Hamburg

Beitrag05.07.2005 13:40     Antworten mit Zitat

Hallo Twilo,

du hast Recht, das Beispiel funktioniert so nicht mehr... ich weiss allerdings auch gerade nicht, warum das so ist. Werds mir später mal anschauen.

Eventuell sollte man doch lieber WSDL benutzen...

Grüße,
Marco

PS. Das Beispiel ist auch schon etwa ein Jahr alt...kann schon sein, das Google da was geändert hat.

_________________
Auch der längste Weg beginnt immer mit einem kleinem Schritt!

Vorgehen bei Problemen:
1. PHP-Handbuch oder PEAR-Handbuch lesen!
2. Forensuche benutzen!
3. Fragen posten und dabei die Regeln beachten!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Twilo
Neuer User


Anmeldungsdatum: 05.07.2005
Beiträge: 12
Wohnort: Berlin

Beitrag05.07.2005 13:46     Antworten mit Zitat

Hallo,

Caddata hat folgendes geschrieben:
du hast Recht, das Beispiel funktioniert so nicht mehr... ich weiss allerdings auch gerade nicht, warum das so ist. Werds mir später mal anschauen.

das wäre super
ich werde mal versuchen zu verstehen, was du da gemacht hattest Wink

Caddata hat folgendes geschrieben:
Eventuell sollte man doch lieber WSDL benutzen...

meinst du das mit WDSL?
http://de.wikipedia.org/wiki/WSDL
nur so ganz verstehen tu ich das noch nicht, was das sein soll *g*

mfg
Twilo

_________________
Farbtabelle


Zuletzt bearbeitet von Twilo am 11.06.2006 19:14, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MaGdev
Site Admin


Anmeldungsdatum: 04.02.2004
Beiträge: 719
Wohnort: Hamburg

Beitrag05.07.2005 14:41     Antworten mit Zitat

Bin gerade auffer Arbeit.... WSDL ist eine feine Sache. Du kannst dir damit quasi deine Zugriffsbibliothek aus der WSDL-Datei generieren und diese dann für den Zugriff verwenden.

Ich bastel heute abend mal ein kleines Beispiel.

Grüße,
Marco

_________________
Auch der längste Weg beginnt immer mit einem kleinem Schritt!

Vorgehen bei Problemen:
1. PHP-Handbuch oder PEAR-Handbuch lesen!
2. Forensuche benutzen!
3. Fragen posten und dabei die Regeln beachten!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Twilo
Neuer User


Anmeldungsdatum: 05.07.2005
Beiträge: 12
Wohnort: Berlin

Beitrag05.07.2005 15:19     Antworten mit Zitat

Hallo,

Caddata hat folgendes geschrieben:
Bin gerade auffer Arbeit.... WSDL ist eine feine Sache. Du kannst dir damit quasi deine Zugriffsbibliothek aus der WSDL-Datei generieren und diese dann für den Zugriff verwenden.

das hört sich interessant an

Caddata hat folgendes geschrieben:
Ich bastel heute abend mal ein kleines Beispiel.

das hört sich noch besser an Cool

mfg
Twilo
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MaGdev
Site Admin


Anmeldungsdatum: 04.02.2004
Beiträge: 719
Wohnort: Hamburg

Beitrag07.07.2005 1:00     Antworten mit Zitat

Hi,

also irgenwie bekomme ich das momentan auch nicht auf die Reihe. Ich bekomme einen (mir) völlig nichtssagenden Fehler, sowohl bei der beschriebenen Methode als auch per WSDL.

Hier mal der Testcode für WSDL
PHP:
<?php
require_once("SOAP/Client.php"); 
$wsdl="http://api.google.com/GoogleSearch.wsdl";
$devkey="*****DEVKEY*****";
$query="PEAR Forum"

$params = array(
  
'key' => $devkey,
  
'q' => utf8_encode($query),
  
'start' => 0,
  
'maxResults' => 25
);

$wsdl=&new SOAP_WSDL($wsdl); 
$gg=$wsdl->getProxy();  // <-- Hier wird die Zugriffsbibliothek generiert
// Mal aus Spass
// print_r(get_class_methods($gg));
$res=$gg->doGoogleSearch($params);
if(
PEAR::isError($res)) {
  echo 
$res->getMessage();
} else {
  echo 
"<pre>";
  
print_r($res);
  echo 
"</pre>";
}


Fehler:
Code:
/search/beta2For input string: ""


Hab nen utf8-Suchstring übergeben.... url stimt auch laut googleapi.... Ich weiss es nicht... Confused Question

Falls jemand eine Lösung kennt - bin interessiert!

Greets,
Marco

_________________
Auch der längste Weg beginnt immer mit einem kleinem Schritt!

Vorgehen bei Problemen:
1. PHP-Handbuch oder PEAR-Handbuch lesen!
2. Forensuche benutzen!
3. Fragen posten und dabei die Regeln beachten!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Twilo
Neuer User


Anmeldungsdatum: 05.07.2005
Beiträge: 12
Wohnort: Berlin

Beitrag05.08.2005 22:20     Antworten mit Zitat

Hallo,

schon schlauer geworden? Smile


mfg
Twilo

_________________
Farbtabelle


Zuletzt bearbeitet von Twilo am 11.06.2006 19:12, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MaGdev
Site Admin


Anmeldungsdatum: 04.02.2004
Beiträge: 719
Wohnort: Hamburg

Beitrag05.08.2005 23:23     Antworten mit Zitat

Neee, sorry - aber im Moment habe ich nicht wirklich viel zeit...
Ich melde mich auf jeden Fall!

Marco

_________________
Auch der längste Weg beginnt immer mit einem kleinem Schritt!

Vorgehen bei Problemen:
1. PHP-Handbuch oder PEAR-Handbuch lesen!
2. Forensuche benutzen!
3. Fragen posten und dabei die Regeln beachten!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
joggeli
Neuer User


Anmeldungsdatum: 22.08.2005
Beiträge: 1

Beitrag22.08.2005 11:51     Antworten mit Zitat

Habe genau das Selbe Problem! Bei mir kommt auch diese Deserialzer Fehlermeldung! Hat jemand da eine Lösung parat?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
adler1860
Neuer User


Anmeldungsdatum: 13.01.2006
Beiträge: 1

Beitrag13.01.2006 16:44     Antworten mit Zitat

Hallo,

das Thema ist zwar schon älter, aber für alle, die trotzdem noch eine Lösung suchen hab ich folgendes gefunden:

http://www.googleduel.com/google-api-php-faq.php

Hab es also mit der Version 0.7.5 probiert. Der deserialize-Fehler war weg, allerdings kam ein Timeout-Fehler Crying or Very sad ...

Würde mich interessieren, ob dieser Fehler bei Euch auch auftaucht...

Gruss

Johannes
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fritz10
Neuer User


Anmeldungsdatum: 30.06.2006
Beiträge: 1

Beitrag30.06.2006 22:13     Antworten mit Zitat

ich wollte mal fragen, ob ihr schon das Problem beheben konntet?
_________________
Fritz
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
weiresr
Neuer User


Anmeldungsdatum: 20.12.2006
Beiträge: 1

Beitrag20.12.2006 16:52     Antworten mit Zitat

Das Problem mit der Fehlermeldung
Code:
No Deserializer found to deserialize a 'urn:GoogleSearch:ns4:key'

hatte ich ebenfalls. Soweit ich das erkennen kann hat sich da in PEAR::SOAP was geändert. Jedenfalls habe ich einen Weg gefunden, mit dem man die Google API auch mit der aktuellen PEAR::SOAP Version benutzen kann.

Das Problem mit dem Programm z.B. unter http://www.googleduel.com/apiexample.php liegt - zumindest mit der aktuellen PEAR::SOAP Version - darin, dass der SOAP Namespace unpassend gesetzt wird. Die SOAP Anfrage sieht hier nämlich so aus:
Zitat:

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns4="urn:GoogleSearch"
>
<SOAP-ENV:Body>

<ns4:doGoogleSearch>
<ns4:key>xxxxxxxxxxxxxxxxxxxxxx</ns4:key>
<ns4:q>Cars</ns4:q>
<ns4:start>0</ns4:start>
<ns4:maxResults>5</ns4:maxResults>
<ns4:filter>false</ns4:filter>
<ns4:restrict></ns4:restrict>
<ns4:safeSearch>false</ns4:safeSearch>
<ns4:lr></ns4:lr>
<ns4:ie></ns4:ie>
<ns4:oe></ns4:oe></ns4:doGoogleSearch>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Sie sollte aber folgendermaßen aussehen, damit der Google Web Service damit zurecht kommt:
Zitat:

<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns="urn:GoogleSearch"
>
<SOAP-ENV:Body>

<doGoogleSearch>
<key>xxxxxxxxxxxxxxxxxxxxxx</key>
<q>Cars</q>
<start>0</start>
<maxResults>5</maxResults>
<filter>false</filter>
<restrict></restrict>
<safeSearch>false</safeSearch>
<lr></lr>
<ie></ie>
<oe></oe></doGoogleSearch>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Der einzige Unterschied besteht also im zusätzlichen Präfix ns4, das aber nicht vorhanden sein sollte. Der Namespace urn:GoogleSearch sollte also der Basis- oder Default-Namespace sein, wenn ich das richtig sehe.

Ok, aber langer Rede kurzer Sinn - mit der folgenden einfachen Zeile kann man erreichen, dass die Abfrage richtig funktioniert:
Code:

$client = new SOAP_Client("http://api.google.com/search/beta2");
$client->_namespace = 'urn:GoogleSearch'; // Diese Zeile einfügen
...

Damit funktioniert es bei mir (PEAR::SOAP 0.9.1) einwandfrei. Ob das so gedacht ist von den PEAR::SOAP-Entwicklern, weiß ich nicht - aber es funktioniert auf jeden Fall so.

Vielleicht hilft's ja noch jemandem, auch wenn der Thread hier schon relativ alt ist...

Übrigens, der o.g. Fehler mit dem Timeout tritt bei mir auch recht häufig auf - aber ich denke das liegt am Web Service von Google; also einfach ein paar Mal im Code wiederholen, falls es nicht klappt...

Gruß,
Ralph Weires
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Diese Seite übersetzen
PEAR-Forum.de Übersicht » HowTo´s, Tutorials, Codebeispiele und Wissenswertes
Neues Thema eröffnen Neue Antwort erstellen Diesen Beitrag ausdrucken
   Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

Zu Deinen Favoriten hinzufügen

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum nicht posten
Du kannst Dateien in diesem Forum herunterladen