Menu Content/Inhalt
Accueil
Scrapper - Bash Convertir en PDF Version imprimable Suggérer par mail
Appréciation des utilisateurs: / 2
FaibleMeilleur 
Écrit par Antony Avril   

Amoureux du Shell bonjour.
Voici un petit script qui simule un navigateur firefox à l'aide de wget pour récupérer le nombre de réponses à une requête.

 Télécharger score.sh
Nom du Fichier:score.sh (Details)
Type:sh
Version:1.0
Taille:1.15Kb
Licence:
Auteur:Antony Avril
Site Web:
Téléchargements:128
Evaluation: (0 Votes)
Votre Vote:
Attention, le fichier robots.txt de www.google.fr interdit l'éxecution de robots. Si vous vous servez de ce script, vous vous engagez à en endosser les responsabilités, veillez donc à vous en servir juste à titre d'exemple, uniquement pour vérifier qu'il fonctionne.

Afin de parvenir à nos fins, nous avons notamment créer une fonction BASH pour encoder la requête suivant la RFC concernant les URI.
Ceci dit la fonction n'est pas rigoureuse mais a le mérite de fonctionner.
Code: ( bash )
urlencode() {
  local decoded=`echo $1 | expand -`
  encoded=     
  for ((i=0; i<${#decoded}; i++))
  do
    local char=${decoded:i:1}
    case "$char" in
      [a-zA-Z0-9]) encoded=${encoded}${char};;
      " ") encoded=${encoded}'+';;
      *)  encoded=${encoded}`echo $char | od -t x1 -A n | tr " " %
        | sed -e 's/%0a$//'`;;
    esac
  done
}

On remarque que l'on traite caractère par caractère la chaîne à encoder. La commande expand convertit les tabulations en espace, il n'est donc pas recommandé de s'en servir si le caractère tabulation doit être envoyé tel quel au serveur.
Le caractère # renvoie la taille d'une variable comprendre pour une variable de type chaîne sa longueur en nombre de caractères.
L'écriture ${decoded:i:1} renvoie la sous-chaîne de la variable decoded à partir de l'index i et de longueur 1.
Enfin la concaténation a toujours lieu mais l'on ne conactène le caractère tel quel que s'il est alphanumérique et non-accentué (correspond à [a-zA-Z0-9]). S'il représente un espace, nous le remplacerons par '+' et dans tous les autres cas, on le remplacera par '%' suivi de sa valeur hexadecimal.
Pour trouver la valeur hexadécimale du caractère, nous avons utilisé une méthode loin d'être optimale, il faut aussi dire que le script shell n'est pas l'idéal pour gérer ce genre de chose. C'est la commande od qui nous permet de faire ça : -t x1 -> donne la valeur hexadécimal pour 1 octet -A n ignore les décalages. tr transforme l'espace généré par od en % et enfin sed supprime le Line feed (saut de ligne sous UNIX) généré par echo.
 
Regardons comment se passe l'éxecution de ce petit script maintenant :
  1. on encode la requête à l'aide de la fonction décrite ci-dessus
  2. on soumet la requête à www.google.fr à l'aide de wget et on en récupère le résultat
  3. on recherche dans le résultat l'information du score et on l'affiche
L'envoie de la requête se fait par :
Code: ( bash )
wget "http://www.google.fr/search?hl=fr&q=${requete_encoded}"
 -q -U 'Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) Gecko/20061010 Firefox/2.0'
 -O -
La requête est passée directement à wget. -q (=quiet) sert à désactiver la sortie de wget, -U sert à définir le User-agent de Firefox 2.0 pour que Google ne nous prenne pas pour un robot (donc ne faîtes pas de robot sur google !) et -O - indique de récupérer le résultat sur '-' qui représent stdout. Rien de compliqué donc.
 
Ainsi les pipes vont nous permettre de travailler directement sur le résultat de requête. Nous allons donc filtrer la sortie pour qu'il ne nous reste plus que l'information recherchée. Tout d'abord en regardant la source HTML d'une requête sur Google, on s'aperçoit que la ligne contenant la bonne information contient aussi class="t bt" qui est un attribut de classe pour le CSS correspondant au style de la ligne sur fond bleu où est affiché le score :
Image
 
Ceci se fera à l'aide de grep. Ensuite nous allons "tagger" l'information à l'aide de sed. Une bonne petite expression régulière et le tour est joué ! Ensuite, il faut enlever les supreflus à l'aide de 2 sed : 1 pour effacer l'avant-tag et le tag de début et 1 pour effacer l'après-tag et le tag de fin :
Code: ( bash )
| grep 'class="t bt"'
| sed 's/sur[^<]*<b>\([^<]*\)<\/b>.*/<end>\1/'
| sed 's/.*<end>//'
| sed 's/&nbsp;//g'
Si nous avions pû (peut-être est-ce possible ?) changer le comportement de * pour le rendre non-glouton et ainsi "matcher" le plus petit motif correspondant, on aurait pû tout faire en une expression régulière.
Le dernier sed sert à supprimer tous les tags HTML d'espaces.
 
Voilà un petit script simple qui met en place un peu de BASH et un peu de wget. En espérant que cela soit utile. 
 
Dernière mise à jour : ( 26-10-2007 )