Mashup : YQL + google trends
Mettons que votre site ait besoin de générer du contenu au kilomètre. Et que tant qu'à faire vous ayez envie de coller aux mots clés du moment. Et qu'en plus il faut que ça soit international.
Pour faire ça il suffit d'accèder à Google Trends, et de faire une recherche sur un pays et une période de recherche (7 derniers jours dans mon cas). Très bien lorsqu'on veut le faire à la main, mais voici comment faire pour le mettre de manière automatique sur un site.
En ouvrant Firebug, on se rend compte qu'une requête XHR est faite pour récupérer le résultat. Exemple pour la France :
http://www.google.com/insights/search/overviewReport?geo=FR&date=today%207-d&gprop=news&cmpt=q&content=1
On récupère du HTML. Plutôt que de jouer avec les regexps pour récupérer les données qui nous intéressent, on va plutôt utiliser YQL qui permet de récupérer le contenu d'une URL et de lancer XPath dessus !. En inspectant le HTML, le Xpath le plus spécifique et le plus court semble être "//tr[@class="trends-table-row"]//a"
En utilisant la console YQL, on peut tester et valider la requete suivante :
select content // le contenu de la balise A visée
from html // la table spéciale YQL
where url="http://www.google.com/insights/search/overviewReport?geo=FR&date=today%207-d&gprop=news&cmpt=q&content=1" // notre source
and xpath = '//tr[@class="trends-table-row"]//a' // le chemin Xpath vers la liste des keywords
On a coché les options JSON (le XML killer), vidé le champs de callback (cbfunc par défaut) et décoché les options de diagnostic. Ensuite on copie/colle l'URL donnée dans le bloc de droite (REST query) pour l'utiliser en PHP
// j'ai mis en évidence l'insertion du pays du user
$url = 'http://query.yahooapis.com/v1/public/yql?q=select%20content%20from%20html%20where%20url%3D%22http%3A%2F%2Fwww.google.com%2Finsights%2Fsearch%2FoverviewReport%3Fgeo%3D';
// insert the country of the user
$url .= $Intl->getCountry(); // GB, FR, US, DE ...
$url .= "%26date%3Dtoday%25207-d%26gprop%3Dnews%26cmpt%3Dq%26content%3D1%22%20and%20xpath%20%3D%20'%2F%2Ftr%5B%40class%3D%22trends-table-row%22%5D%2F%2Fa'&format=json&diagnostics=false&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
// récupération des résultats YQL
$json = file_get_contents($url, 'r');
// interprétation
$data = json_decode($json);
// les résultats qui nous intéressent sont dans un sous tableau :
$search-terms = $data->query->results->a;
// un petit nettoyage avant utilisation ultérieure pour affichage
foreach($this->data['search-terms'] as $i => $term) {
$term = preg_replace('/ss+/', ' ', $term);
}
Et voila, YQL et Xpath permettent de récupérer du contenu sur n'importe quel site sans forcément passer par une API ou avoir faire des expressions régulières tordues (ce qu'on a tous fait au moins une fois :)-
Bien sur ça ne change rien quand à la fragilité de ce code le jour où google change le format de son HTML, mais ce n'est en général pas le genre de code qu'on pousse en production sans précautions :
- un système système de cache est obligatoire dans ce cas, ne serait ce que pour ne pas abuser de YQL et google (voire se faire blacklister),
- un système d'alertes (mail au développeur) lorsqu'on rencontre des erreurs sera utile pour être alerté d'un changement de format
Le même système est jouable en JS (ici avec la librairie YUI), en rajoutant cette vois ci un callback :
var sUrl = 'http://query.yahooapis.com/v1/public/yql?q=select%20content%20from%20html%20where%20url%3D%22http%3A%2F%2Fwww.google.com%2Finsights%2Fsearch%2FoverviewReport%3Fgeo%3D';
<p><p>Bien sur on perd l'intérêt du référencement dans ce cas là :)</p></p>
// insert the country of the user
sUrl += Intl.getCountry(); // GB, FR, US, DE ...
sUrl += "%26date%3Dtoday%25207-d%26gprop%3Dnews%26cmpt%3Dq%26content%3D1%22%20and%20xpath%20%3D%20'%2F%2Ftr%5B%40class%3D%22trends-table-row%22%5D%2F%2Fa'&format=json&diagnostics=false&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
sUrl += '&callback=myCallback';
YAHOO.util.Get.script(sUrl);
var myCallback = function(oResponse) {
aResults = oResponse.query.results.a;
alert(aResults);
}