Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).

#1 22-08-2015 08:43:10

Orsam999
Membre
Distrib. : Debian GNU/Linux 7.9 (wheezy)
Noyau : Linux 3.2.0-4-486
Inscription : 16-01-2015

[Résolu] Extraction de données html avec Sed

Bonjour à tous,

J'ai un petit problème que je n'arrive pas à résoudre.

J'explique : J'ai un code html tout simple :

<tbody>
  <tr >
    <td type="Date">20/08/2015</td>
    <td attrib="Libelle">Ouverture</td>
    <td attrib="site" class="last">Centre 1</td>
  </tr>
  <tr class='last'>
    <td headers="Date">20/08/2015</td>
    <td headers="Libelle">John part à la peche</td>
    <td headers="site" class="last">Centre 2</td>
  </tr>
</tbody>
 



L'idée c'est d'extraire les données contenues dans les balises TD et de les mettre dans une variable tableau.

Voici ce que j'ai fait :



i=-1
mon_tableau=()

sed -n 's,.*<td .*>\([^>].*\)</td>,\1,p' /tmp/test.html | while read titre; do
        echo $titre
        i=`expr $i + 1`
        mon_tableau[$i]="$titre"
done

echo ${mon_tableau[*]}

 




Maintenant j'ai deux problèmes, le premier, c'est que les deux TD qui contiennent respectivement Centre 1 et Centre 2 ne sorte pas avec echo $titre... roll

Le deuxième problème, est que mon tableau, reste vide malgré que dans la variable $titre contiennent quand même les textes des autres TD ...


Une idée ??


Merci par avance.


Orsam

Dernière modification par Orsam999 (27-08-2015 07:31:35)


Celui qui ne progresse pas chaque jour, recule chaque jour.
Confucius

Hors ligne

#2 22-08-2015 09:16:15

Orsam999
Membre
Distrib. : Debian GNU/Linux 7.9 (wheezy)
Noyau : Linux 3.2.0-4-486
Inscription : 16-01-2015

Re : [Résolu] Extraction de données html avec Sed

Re moi,

Je crois avoir trouvé le problème pour les TD qui ne renvois par de résultat. En fait, le html était plus formé comme ça (et non comme dans le post précédent) :

<tbody>
  <tr >
    <td type="Date">20/08/2015</td>
    <td attrib="Libelle">Ouverture</td>
    <td attrib="site" class="last">

Centre 1

</td>
  </tr>
  <tr class='last'>
    <td headers="Date">20/08/2015</td>
    <td headers="Libelle">John part à la peche</td>
    <td headers="site" class="last">

Centre 2

</td>
  </tr>
</tbody>



Pour résoudre le problème des tabulation, retour chariots, etc.. , j'ai fait une petite commande tr :

tr -d '\r\n\s\t'



Maintenant, mon html ressemble à ça (ok, pourquoi pas..) :

<tr ><td type="Date">20/08/2015</td><td attrib="Libelle">Ouverture</td><td attrib="site" class="last">Centre 1</td>/tr><tr class='last'><td headers="Date">20/08/2015</td><td headers="Libelle">John part à la peche</td><td headers="site" class="last">Centre 2</td>/tr>




Par contre maintenant,  le code du post précédent ne renvoi plus rien hmm :

i=-1
mon_tableau=()

sed -n 's,.*<td .*>\([^>].*\)</td>,\1,p' /tmp/test.html | while read titre; do
        echo $titre
        i=`expr $i + 1`
        mon_tableau[$i]="$titre"
done

echo ${mon_tableau[*]}
 



Je pense que c'est le while read qui ne va pas, mais je ne sais pas quoi utiliser d'autre...


Au secours !! big_smile


Merci.


Orsam


Celui qui ne progresse pas chaque jour, recule chaque jour.
Confucius

Hors ligne

#3 24-08-2015 11:21:36

D@mien
Membre
Distrib. : Gnoulinusque
Noyau : Linux 4\.[7-9]+(\.\d+)?-[1-9]+-custom
(G)UI : i3
Inscription : 22-03-2014

Re : [Résolu] Extraction de données html avec Sed

Hello
Désolé, sed me donne la nausée sad
Je l'écrirais naturellement comme ceci (où full perl, mais c'est pas la question big_smile)


#!/usr/bin/bash

array=()

while read i;do
    array+=("$i")
done < <(perl -n -e 'print "$1\n" if /<td[^>]*>(.*)<\/td>/' file)

for i in $(seq 0 ${#array[@]});do
    echo ${array[$i]}
done
 


++


% cat /usr/include/sys/errno.h
#define EPERM           1               /* Operation not permitted */
[...]
#define EMACS           666             /* Too many macros */

Hors ligne

#4 27-08-2015 07:30:51

Orsam999
Membre
Distrib. : Debian GNU/Linux 7.9 (wheezy)
Noyau : Linux 3.2.0-4-486
Inscription : 16-01-2015

Re : [Résolu] Extraction de données html avec Sed

Bonjour D@amien et merci pour ta réponse.

Ca marche PARFAITEMENT !!!!!

Euh... par contre, désolé pour ta nausée.. big_smile


Merci beaucoup

Orsam

Dernière modification par Orsam999 (27-08-2015 07:31:13)


Celui qui ne progresse pas chaque jour, recule chaque jour.
Confucius

Hors ligne

#5 29-02-2016 15:59:31

EmilieS
Membre
Distrib. : Mageia 5
Noyau : Linux 4.1.15
(G)UI : Xfce 4.12
Inscription : 29-02-2016
Site Web

Re : [Résolu] Extraction de données html avec Sed

Bonjour,

Sinon en php il y a une librairie qui s'apelle simpledomhtml très pratique !

Hors ligne

#6 29-02-2016 21:39:10

enicar
Membre
Lieu : Grenoble
Distrib. : debian/sid
Noyau : Linux 4.8.10
(G)UI : openbox
Inscription : 26-08-2010

Re : [Résolu] Extraction de données html avec Sed

Orsam999 a écrit :

Je pense que c'est le while read qui ne va pas, mais je ne sais pas quoi utiliser d'autre...


Ce n'est pas le « while read » qui ne fonctionne mais la façon dont il
est utilisé.  Le problème vient du tube que tu utilises pour passer tes
données à read.  Ce tube va créer un sous shell dans lequel la
variable mon_tableau est complétement indépendante de celle que
tu as créé juste avant la boucle. Pour circonvenir à cette situation,
on peut utiliser une substitution de processus comme l'a fait D@mien.
Pour être clair, la substitution de processus c'est :


<(sed -n 's,.*<td .*>\([^>].*\)</td>,\1,p')
 


Cela crée un tube nomé (c'est un fichier dans le système de fichier)
temporaire. sed va donc afficher sur la sortie standard qui est
redirigé vers ce tube nomé. Avec l'autre partie  :


< <(sed -n 's,.*<td .*>\([^>].*\)</td>,\1,p')
 


On va rediriger l'entrée standard pour lire dans le tube nomé.
Et donc :


mon_tableau=()
while read titre; do
        mon_tableau += ("$titre")
done < <(sed -n 's,.*<td .*>\([^>].*\)</td>,\1,p' /tmp/test.html)
 


Va permettre à read de lire les données extraites par sed.
Donc, tu peux tout à fait continuer à utiliser sed wink

Aller, le programme complet :


mon_tableau=()
while read titre; do
        mon_tableau += ("$titre")
done < <(sed -n 's,.*<td .*>\([^>].*\)</td>,\1,p' /tmp/test.html)

for titre in "${mon_tableau[@]}"; do
    echo $titre
done
 



Évidemment, ça serait mieux en perl, python ou ruby, mais bon… En
plus, analyser du code html en utilisant des expressions rationnelles
peut être assez aventureux. Il existe d'excellentes bibliothèques pour
cela, beautifulsoup et html5lib en python par exemple.  Il en existe
en perl et en ruby aussi. Mais même mieux l'utilitaire xpath
fournit avec libxml-xpath-perl permet aussi d'extraire des
données des fichiers html pour peu qu'ils soient bien formés (d'après
ce que je me souviens). Il est tout à fait possible d'utiliser xpath
dans un shell script smile

Dernière modification par enicar (29-02-2016 22:07:15)


La machine, c'est dépassé ! On va tout remplacer par des humains big_smile

Hors ligne

#7 01-03-2016 11:54:17

enicar
Membre
Lieu : Grenoble
Distrib. : debian/sid
Noyau : Linux 4.8.10
(G)UI : openbox
Inscription : 26-08-2010

Re : [Résolu] Extraction de données html avec Sed

Ah ! J'ai oublié ! On peut faire bien plus simple pour initialiser un
tableau, grâce à la fonction interne de bash readarray (ou
mapfile) :


readarray -t mon_tableau < <(sed -n 's,.*<td[^>]*>\([^<]*\)</td>,\1,p' /tmp/test.html)

for titre in "${mon_tableau[@]}"; do
    echo "$titre"
done
 


Le « -t », c'est pour enlever les retour à la ligne. Du coup ton script
devient vraiment simple. J'ai un peu modifié l'expression sed
pour qu'elle corresponde mieux à tes données…
Mais si il y a un <td> écrit sur plusieurs lignes ça ne marchera pas…
C'est la limite de ce genre d'approche basée sur des expressions
rationnelles. Je pense que l'on peut le faire fonctionner quand même
avec plusieurs expressions sed bien choisies… je le laisse en exercice wink


La machine, c'est dépassé ! On va tout remplacer par des humains big_smile

Hors ligne

Pied de page des forums